diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26dc9628c6dd..28f53a5d0be9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - java: [8, 11, 17, 21] + java: [8, 11, 17, 21, 24, 25-ea] runs-on: ${{matrix.os}} steps: - run: git config --global core.autocrlf false @@ -33,6 +33,9 @@ jobs: java-version: ${{matrix.java}} cache: sbt + - name: Setup SBT + uses: sbt/setup-sbt@v1 + - name: Build run: | sbt setupPublishCore generateBuildCharacterPropertiesFile headerCheck publishLocal @@ -40,4 +43,4 @@ jobs: - name: Test run: | STARR=`cat buildcharacter.properties | grep ^maven.version.number | cut -d= -f2` && echo $STARR - sbt -Dstarr.version=$STARR setupValidateTest test:compile info testAll + sbt -Dstarr.version=$STARR setupValidateTest Test/compile info testAll diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 000000000000..3549dedc2a21 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,11 @@ +name: "Check Scala CLA" +on: + pull_request: +jobs: + cla-check: + runs-on: ubuntu-latest + steps: + - name: Verify CLA + uses: scala/cla-checker@v1 + with: + author: ${{ github.event.pull_request.user.login }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 000000000000..098131515f5d --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,41 @@ +name: PR validation +on: + pull_request: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 8 + cache: sbt + - uses: sbt/setup-sbt@v1 + # "mini" bootstrap for PR validation + # "mini" in these senses: + # - it doesn't use the complicated legacy scripts. + # - it doesn't publish to scala-pr-validation-snapshots + # (because we need secrets for that and PRs from forks can't have secrets) + # it is still a true bootstrap. + - name: build + run: sbt -warn setupPublishCore generateBuildCharacterPropertiesFile headerCheck publishLocal + - name: rebuild + run: | + STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR + sbt -Dstarr.version=$STARR Test/compile + - name: testAll1 + run: | + STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR + sbt -Dstarr.version=$STARR setupValidateTest testAll1 + - name: testAll2 + run: | + STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR + sbt -Dstarr.version=$STARR setupValidateTest testAll2 + - name: benchmarks + run: | + STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR + sbt -Dstarr.version=$STARR bench/Jmh/compile + - name: build library with Scala 3 + run: sbt -Dscala.build.compileWithDotty=true library/compile diff --git a/.gitignore b/.gitignore index da448597c4b7..61bf3454a8f9 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ jitwatch.out project/**/metals.sbt .bsp +.history diff --git a/.mailmap b/.mailmap index 6bb681d917ad..216682f3acfb 100644 --- a/.mailmap +++ b/.mailmap @@ -35,6 +35,7 @@ Eugene Burmako Eugene Burmako Eugene Vigdorchik François Garillot +Friendseeker <66892505+Friendseeker@users.noreply.github.com> Geoff Reedy Gilad Hoch Harrison Houghton diff --git a/.travis.yml b/.travis.yml index 9140478560e7..f95bead2a1de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,3 @@ -# `-Dsbt.io.jdktimestamps=true` is used to work around -# this bug in sbt 1.9.8: https://github.com/sbt/sbt/issues/7463 -# we can remove it once we're on an sbt version with a fix. - version: ~> 1.0 # needed for imports import: scala/scala-dev:travis/default.yml @@ -9,70 +5,12 @@ dist: xenial # GPG stuff breaks on bionic; scala/scala-dev#764 language: scala stages: - - build - - test - -templates: # this has no effect on travis, it's just a place to put our templates - pr-jdk8: &pr-jdk8 - if: type = pull_request OR repo != scala/scala - - cron-jdk17: &cron-jdk17 - if: type = cron AND repo = scala/scala - env: ADOPTOPENJDK=17 - - build-for-testing: &build-for-testing - # pull request validation (w/ bootstrap) - # differs from the build that publishes releases / integration builds: - # - not using bash script setup, but just the underlying sbt calls - # - publishing locally rather than to Artifactory - # the bootstrap above is older historically; this way of doing it is newer - # and also simpler. we should aim to reduce/eliminate the duplication. - stage: build - name: build, publishLocal, build again - script: - - set -e - - sbt -Dsbt.io.jdktimestamps=true setupPublishCore generateBuildCharacterPropertiesFile headerCheck publishLocal - - STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR - - sbt -Dsbt.io.jdktimestamps=true -Dstarr.version=$STARR setupValidateTest compile - workspaces: - create: - name: bootstrapped - paths: - # so new STARR will be available - - "buildcharacter.properties" - - "$HOME/.ivy2/local/org.scala-lang" - # so build products built using new STARR are kept - - "target" - - "project/target" - - "project/project/target" - - "project/project/project/target" - - "dist" - - "build" - - test1: &test1 - stage: test - name: tests (junit, scalacheck, et al) - workspaces: - use: bootstrapped - script: - - set -e - - STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR - - sbt -Dsbt.io.jdktimestamps=true -Dstarr.version=$STARR setupValidateTest Test/compile testAll1 - - test2: &test2 - stage: test - name: tests (partest) - workspaces: - use: bootstrapped - script: - - set -e - - STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR - - sbt -Dsbt.io.jdktimestamps=true -Dstarr.version=$STARR setupValidateTest testAll2 + - name: build jobs: include: - stage: build - if: (type = push OR type = api) AND repo = scala/scala # api for manually triggered release builds + if: type != pull_request AND repo = scala/scala AND branch = 2.13.x name: publish (bootstrapped) to scala-integration or sonatype script: # see comment in `bootstrap_fun` for details on the procedure @@ -91,45 +29,8 @@ jobs: - buildQuick - triggerScalaDist - - <<: *build-for-testing - <<: *pr-jdk8 - - - <<: *test1 - <<: *pr-jdk8 - - - <<: *test2 - <<: *pr-jdk8 - - - <<: *build-for-testing - <<: *cron-jdk17 - - - <<: *test1 - <<: *cron-jdk17 - - - <<: *test2 - <<: *cron-jdk17 - - - stage: test - name: build library with Scala 3 - if: type = pull_request OR repo != scala/scala - workspaces: - use: bootstrapped - script: - - set -e - - STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR - - sbt -Dsbt.io.jdktimestamps=true -Dscala.build.compileWithDotty=true library/compile - - - name: build benchmarks - if: type = pull_request OR repo != scala/scala - workspaces: - use: bootstrapped - script: - - set -e - - STARR=$(sed -n 's/^maven\.version\.number=//p' buildcharacter.properties) && echo $STARR - - sbt -Dsbt.io.jdktimestamps=true bench/Jmh/compile - - stage: build - if: type = pull_request OR type = push + if: type != pull_request AND repo = scala/scala AND branch = 2.13.x name: language spec dist: focal language: ruby @@ -139,6 +40,8 @@ jobs: - gem install bundler -v "< 2.5" #scala-dev#857 - bundler --version - bundle install --path vendor/bundle + # https://travis-ci.community/t/travis-focal-ubuntu-image-uses-now-expired-mongodb-4-4-package/14293/3 + - wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - # cribbed from https://github.com/SebastiaanKlippert/go-wkhtmltopdf/blob/master/.travis.yml - sudo apt-get update - sudo apt-get install -y build-essential xorg xfonts-75dpi libpng16-16 libssl1.1 @@ -162,8 +65,8 @@ env: - secure: "T1fxtvLTxioyXJYiC/zVYdNYsBOt+0Piw+xE04rB1pzeKahm9+G2mISdcAyqv6/vze9eIJt6jNHHpKX32/Z3Cs1/Ruha4m3k+jblj3S0SbxV6ht2ieJXLT5WoUPFRrU68KXI8wqUadXpjxeJJV53qF2FC4lhfMUsw1IwwMhdaE8=" # PRIVATE_REPO_PASS, for publishing to scala-ci Artifactory - secure: "dbAvl6KEuLwZ0MVQPZihFsPzCdiLbX0EFk3so+hcfEbksrmLQ1tn4X5ZM7Wy1UDR8uN9lxngEwHch7a7lKqpugzmXMew9Wnikr9WBWbJT77Z+XJ/jHI6YuiCRpRo+nvxXGp9Ry80tSIgx5eju0J83IaJL41BWlBkvyAd7YAHORI=" # GPG_SUBKEY_SECRET, so we can sign JARs - secure: "RTyzS6nUgthupw5M0fPwTlcOym1sWgBo8eXYepB2xGiQnRu4g583BGuNBW1UZ3vIjRETi/UKQ1HtMR+i7D8ptF1cNpomopncVJA1iy7pU2w0MJ0xgIPMuvtkIa3kxocd/AnxAp+UhUad3nC8lDpkvZsUhhyA0fb4iPKipd2b2xY=" # TRAVIS_TOKEN (login with GitHub as SethTisue), for triggering scala-dist job - - secure: "PbDzgRGivsDM/1P18dIAZiZnK8yG+fxU/9Ho6DkAd8pvsu7S08MPks+ekM0uSVeKxYj7Npzd3XTe4weEXM7Jtljy3CRHoPasI0TF/6ZVOb7H+MMP1cg9K1xrZXKfEk2RABCbMxKtrEv9BDa/lVtjCCEKWAIPz38Z6q2mKk417Ps=" # SONA_USER, token username for publishing to Sonatype - - secure: "D/V5nrAJsAc6t5ZMoeSt37ViIsJyRmagA286M3zWn/uZhgk4mbgYfzu6rDbYeUTBB9jX8YHKPtzUrxqcnlpkV8z6USAbDhzYSLL/QqcLnTjKZZ3KvPEimNQIXX8Nb1KIrlXNQ/xTE8u+GNvQLDdxa60QqlzvA3tt5vnVl3GatFE=" # SONA_PASS, token password for publishing to Sonatype + - secure: "cxN4KHc4RvSzqXWMypMh65ENMbbQdIV/kiqFtxA76MlRynNtMFa/A5t76EESRyNFlXMSgh6sgrjGVK5ug7iMQZpYc1TtcE7WvBjxwqD+agA0wO2qZujPd5BYU8z25hw00rYAkxtL+R7IkEgDKKmAgfRM2cbLV/B8JUikWTnRJ2g=" # SONA_USER, token username for publishing to Sonatype + - secure: "agM/qNyKzAV94JLsZoZjiR2Kd4g+Fr/mbpR2wD84m8vpDGk+pqFflaonYzjXui/ssL0lJIyGmfWJizwCSE0s9v69IMo7vrKWQ9jLam2OJyBLLs/mIGIH/okl5t8pjUJw4oEOoZ//JZAmplv6bz3gIucgziEWLIQKfBCX/kZffc8=" # SONA_PASS, token password for publishing to Sonatype # caching for sdkman / sbt / ivy / coursier imported from scala-dev cache: @@ -171,10 +74,4 @@ cache: - $HOME/.rvm notifications: - slack: - rooms: - - typesafe:WoewGgHil2FkdGzJyV3phAhj - if: (type = cron OR type = push) AND repo = scala/scala - on_success: never - on_failure: change webhooks: https://scala-ci.typesafe.com/benchq/webhooks/travis diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 197f841d78db..635929ce34a4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,21 +4,11 @@ We follow the standard GitHub [fork & pull](https://help.github.com/articles/usi You're always welcome to submit your PR straight away and start the discussion (without reading the rest of this wonderful doc, or the [`README.md`](README.md)). The goal of these notes is to make your experience contributing to Scala as smooth and pleasant as possible. We're happy to guide you through the process once you've submitted your PR. -## The Scala Community - -In 2014, you -- the Scala community -- matched the core team at EPFL in number of commits contributed to Scala 2.11, doubling the percentage of commits from outside EPFL/Lightbend since 2.10. Excellent work! (The split was roughly 25/25/50 for you/EPFL/Lightbend.) - -We are super happy about this, and are eager to make your experience contributing to Scala productive and satisfying, so that we can keep up this growth. We can't do this alone (nor do we want to)! - -This is why we're collecting these notes on how to contribute, and we hope you'll share your experience to improve the process for the next contributor! (Feel free to send a PR for this note, send your thoughts to \#scala-contributors (on [Discord](https://discord.com/invite/scala)) or contributors.scala-lang.org (Discourse).) - -By the way, the team at Lightbend is: @lrytz, @retronym, @SethTisue, and @dwijnand. - ## What kind of PR are you submitting? -Regardless of the nature of your Pull Request, we have to ask you to digitally sign the [Scala CLA](https://www.lightbend.com/contribute/cla/scala), to protect the OSS nature of the code base. +Regardless of the nature of your Pull Request, we have to ask you to digitally sign the [Scala CLA](https://contribute.akka.io/cla/scala), to protect the OSS nature of the code base. -You don't need to submit separate PRs for 2.12.x and 2.13.x. Any change accepted on 2.12.x will, in time, be merged onto 2.13.x too. (We are no longer accepting PRs for 2.11.x.) +You don't need to submit separate PRs for 2.12.x and 2.13.x. Any change accepted on 2.12.x will, in time, be merged onto 2.13.x too. ### Documentation @@ -32,7 +22,7 @@ For bigger documentation changes, you may want to poll contributors.scala-lang.o For bigger changes, we do recommend announcing your intentions on contributors.scala-lang.org first, to avoid duplicated effort, or spending a lot of time reworking something we are not able to change at this time in the release cycle, for example. -The kind of code we can accept depends on the life cycle for the release you're targeting. The current maintenance release (2.12.x) cannot break source/binary compatibility, which means public APIs cannot change. It also means we are reluctant to change, e.g., type inference or implicit search, as this can have unforeseen consequences for source compatibility. +The kind of code we can accept depends on the life cycle for the release you're targeting. The current maintenance release (2.13.x) cannot break source/binary compatibility, which means public APIs cannot change. It also means we are reluctant to change, e.g., type inference or implicit search, as this can have unforeseen consequences for source compatibility. #### Bug Fix @@ -127,7 +117,8 @@ scala -cp out Test ``` **Flags** - - To specify compiler flags such as `-Werror -Xlint`, you can add a comment at the top of your source file of the form: `// scalac: -Werror -Xlint`. + - To specify compiler flags such as `-Werror -Xlint`, you can add a comment at the top of your source file of the form: + `//> using options -Werror -Xlint` - Similarly, a `// javac: ` comment in a Java source file passes flags to the Java compiler. - A `// filter: ` comment eliminates output lines that match the filter before comparing to the `.check` file. - A `// java: ` comment makes a `run` test execute in a separate JVM and passes the additional flags to the `java` command. @@ -267,7 +258,7 @@ say so. Backports should be tagged as "[backport]". -When working on maintenance branches (e.g., 2.12.x), include "[nomerge]" +When working on older maintenance branches (namely 2.12.x), include "[nomerge]" if this commit should not be merged forward into the next release branch. diff --git a/NOTICE b/NOTICE index 22457ecf1a2d..e3d6b3bb0586 100644 --- a/NOTICE +++ b/NOTICE @@ -1,10 +1,10 @@ Scala -Copyright (c) 2002-2024 EPFL -Copyright (c) 2011-2024 Lightbend, Inc. +Copyright (c) 2002-2025 EPFL +Copyright (c) 2011-2025 Lightbend, Inc. dba Akka Scala includes software developed at LAMP/EPFL (https://lamp.epfl.ch/) and -Lightbend, Inc. (https://www.lightbend.com/). +Akka (https://akka.io/). Licensed under the Apache License, Version 2.0 (the "License"). Unless required by applicable law or agreed to in writing, software diff --git a/README.md b/README.md index 084b418e133e..c039fbc44fc9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is the home of the [Scala 2](https://www.scala-lang.org) standard library, compiler, and language spec. -If you want to visit the Scala 3 repository, go to the [lampepfl/dotty](https://github.com/lampepfl/dotty). +For Scala 3, visit [scala/scala3](https://github.com/scala/scala3). # How to contribute @@ -15,7 +15,7 @@ To contribute here, please open a [pull request](https://help.github.com/article Be aware that we can't accept additions to the standard library, only modifications to existing code. Binary compatibility forbids adding new public classes or public methods. Additions are made to [scala-library-next](https://github.com/scala/scala-library-next) instead. -We require that you sign the [Scala CLA](https://www.lightbend.com/contribute/cla/scala) before we can merge any of your work, to protect Scala's future as open source software. +We require that you sign the [Scala CLA](https://contribute.akka.io/contribute/cla/scala) before we can merge any of your work, to protect Scala's future as open source software. The general workflow is as follows. 1. Find/file an issue in scala/bug (or submit a well-documented PR right away!). @@ -37,7 +37,7 @@ If you need some help with your PR at any time, please feel free to @-mention an | | username | talk to me about... | --------------------------------------------------------------------------------------------------|----------------------------------------------------------------|---------------------------------------------------| | [`@lrytz`](https://github.com/lrytz) | back end, optimizer, named & default arguments, reporters | - | [`@retronym`](https://github.com/retronym) | 2.12.x branch, compiler performance, weird compiler bugs, lambdas | + | [`@retronym`](https://github.com/retronym) | compiler performance, weird compiler bugs, lambdas | | [`@SethTisue`](https://github.com/SethTisue) | getting started, build, CI, community build, Jenkins, docs, library, REPL | | [`@dwijnand`](https://github.com/dwijnand) | pattern matcher, MiMa, partest | | [`@som-snytt`](https://github.com/som-snytt) | warnings/lints/errors, REPL, compiler options, compiler internals, partest | @@ -53,7 +53,7 @@ P.S.: If you have some spare time to help out around here, we would be delighted # Branches -Target the oldest branch you would like your changes to end up in. We periodically merge forward from older release branches (e.g., 2.12.x) to new ones (e.g. 2.13.x). +Target the oldest branch you would like your changes to end up in. We periodically merge forward from 2.12.x to 2.13.x. Most changes should target 2.13.x, as 2.12.x is now under minimal maintenance. If your change is difficult to merge forward, you may be asked to also submit a separate PR targeting the newer branch. @@ -63,10 +63,7 @@ If your change is a backport from a newer branch and thus doesn't need to be mer ## Choosing a branch -Most changes should target 2.13.x. We are increasingly reluctant to target 2.12.x unless there is a special reason (e.g. if an especially bad bug is found, or if there is commercial sponsorship). - -The 2.11.x branch is now [inactive](https://github.com/scala/scala-dev/issues/451) and no further 2.11.x releases are planned (unless unusual, unforeseeable circumstances arise). You should not target 2.11.x without asking maintainers first. - +Most changes should target 2.13.x. We are increasingly reluctant to target 2.12.x unless there is a special reason (e.g. if an especially bad bug is found, or if there is commercial sponsorship). See [Scala 2 maintenance](https://www.scala-lang.org/development/#scala-2-maintenance). # Repository structure @@ -117,7 +114,7 @@ scala/ You need the following tools: - Java SDK. The baseline version is 8 for both 2.12.x and 2.13.x. It is almost always fine - to use a later SDK such as 11 or 15 for local development. CI will verify against the + to use a later SDK (such as 17 or 21) for local development. CI will verify against the baseline version. - sbt @@ -130,6 +127,7 @@ We are grateful for the following OSS licenses: - [JProfiler Java profiler](https://www.ej-technologies.com/products/jprofiler/overview.html) - [YourKit Java Profiler](https://www.yourkit.com/java/profiler/) - [IntelliJ IDEA](https://www.jetbrains.com/idea/download/) + - [![Revved up by Develocity](https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A)](https://develocity.scala-lang.org) ## Build setup @@ -281,17 +279,17 @@ and specifying the corresponding `scalaVersion`: ``` $ sbt > set resolvers += "pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/" -> set scalaVersion := "2.12.2-bin-abcd123-SNAPSHOT" +> set scalaVersion := "2.13.17-bin-abcd123-SNAPSHOT" > console ``` ## "Nightly" builds -The Scala CI builds nightly download releases and publishes -them to https://scala-ci.typesafe.com/artifactory/scala-integration/ . +The Scala CI publishes these to +https://scala-ci.typesafe.com/artifactory/scala-integration/ . -Using a nightly build in sbt is explained in -[this Stack Overflow answer](https://stackoverflow.com/questions/40622878) +Using a nightly build in sbt and other tools is explained on this +[doc page](https://docs.scala-lang.org/overviews/core/nightlies.html). Although we casually refer to these as "nightly" builds, they aren't actually built nightly, but "mergely". That is to say, a build is diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000000..c15d1d414175 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +The security policy of the Scala Programming Language organization can be found at [scala-lang.org/security](https://scala-lang.org/security). + +To contact us about security issues or the policy, use [security@scala-lang.org](mailto:security@scala-lang.org). diff --git a/build.sbt b/build.sbt index c42f6ffce6c6..0bbcb579a297 100644 --- a/build.sbt +++ b/build.sbt @@ -37,15 +37,13 @@ import scala.build._, VersionUtil._ // Non-Scala dependencies: val junitDep = "junit" % "junit" % "4.13.2" val junitInterfaceDep = "com.github.sbt" % "junit-interface" % "0.13.3" % Test -val scalacheckDep = "org.scalacheck" %% "scalacheck" % "1.17.0" % Test +val scalacheckDep = "org.scalacheck" %% "scalacheck" % "1.18.1" % Test val jolDep = "org.openjdk.jol" % "jol-core" % "0.16" val asmDep = "org.scala-lang.modules" % "scala-asm" % versionProps("scala-asm.version") -val jlineDep = "org.jline" % "jline" % versionProps("jline.version") -val jnaDep = "net.java.dev.jna" % "jna" % versionProps("jna.version") -val jlineDeps = Seq(jlineDep, jnaDep) +val jlineDep = "org.jline" % "jline" % versionProps("jline.version") classifier "jdk8" val testInterfaceDep = "org.scala-sbt" % "test-interface" % "1.0" -val diffUtilsDep = "io.github.java-diff-utils" % "java-diff-utils" % "4.12" -val compilerInterfaceDep = "org.scala-sbt" % "compiler-interface" % "1.9.6" +val diffUtilsDep = "io.github.java-diff-utils" % "java-diff-utils" % "4.15" +val compilerInterfaceDep = "org.scala-sbt" % "compiler-interface" % "1.10.8" val projectFolder = settingKey[String]("subfolder in src when using configureAsSubproject, else the project name") @@ -74,7 +72,7 @@ lazy val publishSettings : Seq[Setting[_]] = Seq( // should not be set directly. It is the same as the Maven version and derived automatically from `baseVersion` and // `baseVersionSuffix`. globalVersionSettings -Global / baseVersion := "2.13.13" +Global / baseVersion := "2.13.17" Global / baseVersionSuffix := "SNAPSHOT" ThisBuild / organization := "org.scala-lang" ThisBuild / homepage := Some(url("https://www.scala-lang.org")) @@ -83,7 +81,7 @@ ThisBuild / licenses += (("Apache-2.0", url("https://www.apache.org/licens ThisBuild / headerLicense := Some(HeaderLicense.Custom( s"""Scala (${(ThisBuild/homepage).value.get}) | - |Copyright EPFL and Lightbend, Inc. + |Copyright EPFL and Lightbend, Inc. dba Akka | |Licensed under Apache License 2.0 |(http://www.apache.org/licenses/LICENSE-2.0). @@ -103,6 +101,44 @@ Global / scalaVersion := { versionProps("starr.version") } +// Run `sbt -Dscala.build.publishDevelocity` to publish build scans to develocity.scala-lang.org +// In Jenkins, the `...publishDevelocity=stage` value is used to set the `JENKINS_STAGE` value of the scan +ThisBuild / develocityConfiguration := { + def pubDev = Option(System.getProperty("scala.build.publishDevelocity")) + val isInsideCI = sys.env.get("JENKINS_URL").exists(_.contains("scala-ci.typesafe.com")) + val config = develocityConfiguration.value + val buildScan = config.buildScan + val buildCache = config.buildCache + config + .withProjectId(ProjectId("scala2")) + .withServer(config.server.withUrl(Some(url("https://develocity.scala-lang.org")))) + .withBuildScan( + buildScan + .withPublishing(Publishing.onlyIf(ctx => pubDev.nonEmpty && ctx.authenticated)) + .withBackgroundUpload(false) + .withTag(if (isInsideCI) "CI" else "Local") + .withTag("2.13") + .withLinks(buildScan.links ++ + sys.env.get("BUILD_URL").map(u => "Jenkins Build" -> url(u)) ++ + sys.env.get("repo_ref").map(sha => "GitHub Commit" -> url(s"https://github.com/scala/scala/commit/$sha")) ++ + sys.env.get("_scabot_pr").map(pr => "GitHub PR " -> url(s"https://github.com/scala/scala/pull/$pr"))) + .withValues(buildScan.values + + ("GITHUB_REPOSITORY" -> "scala/scala") + + ("GITHUB_BRANCH" -> "2.13.x") ++ + pubDev.filterNot(_.isEmpty).map("JENKINS_STAGE" -> _) ++ + sys.env.get("JOB_NAME").map("JENKINS_JOB_NAME" -> _) ++ + sys.env.get("repo_ref").map("GITHUB_SHA" -> _) ++ + sys.env.get("_scabot_pr").map("GITHUB_PR" -> _) ++ + sys.env.get("NODE_NAME").map("JENKINS_NODE" -> _)) + .withObfuscation(buildScan.obfuscation.withIpAddresses(_.map(_ => "0.0.0.0"))) + ) + .withBuildCache( + buildCache + .withLocal(buildCache.local.withEnabled(false)) + .withRemote(buildCache.remote.withEnabled(false)) + ) +} + lazy val instanceSettings = Seq[Setting[_]]( // we don't cross build Scala itself crossPaths := false, @@ -160,16 +196,21 @@ lazy val commonSettings = instanceSettings ++ clearSourceAndResourceDirectories cleanFiles += (Compile / doc / target).value, run / fork := true, run / connectInput := true, - // uncomment for ease of development while breaking things - //Compile / scalacOptions ++= Seq("-Xmaxerrs", "5", "-Xmaxwarns", "5"), - // work around https://github.com/scala/bug/issues/11534 - Compile / scalacOptions += "-Wconf:cat=unchecked&msg=The outer reference in this type test cannot be checked at run time.:s", - // we don't want optimizer warnings to interfere with `-Werror`. we have hundreds of such warnings - // when the optimizer is enabled (as it is in CI and release builds, though not in local development) - Compile / scalacOptions += "-Wconf:cat=optimizer:is", - // We use @nowarn for some methods that are deprecated in Java > 8 - Compile / scalacOptions += "-Wconf:cat=unused-nowarn:s", - Compile / scalacOptions ++= Seq("-deprecation", "-feature"), + Compile / scalacOptions ++= Seq("-feature", "-Xlint", + //"-Wunused:patvars", + //"-Wunused:params", + //"-Vprint", + //"-Xmaxerrs", "5", "-Xmaxwarns", "5", // uncomment for ease of development while breaking things + // work around https://github.com/scala/bug/issues/11534 + "-Wconf:cat=unchecked&msg=The outer reference in this type test cannot be checked at run time.:s", + // optimizer warnings at INFO since `-Werror` may be turned on. + // optimizer runs in CI and release builds, though not in local development. + "-Wconf:cat=optimizer:is", + // we use @nowarn for methods that are deprecated in JDK > 8, but CI/release is under JDK 8 + "-Wconf:cat=unused-nowarn:s", + "-Wconf:cat=deprecation&msg=in class Thread :s", + "-Wunnamed-boolean-literal-strict", + ), Compile / doc / scalacOptions ++= Seq( "-doc-footer", "epfl", "-diagrams", @@ -213,8 +254,8 @@ lazy val commonSettings = instanceSettings ++ clearSourceAndResourceDirectories LAMP/EPFL - Lightbend - Lightbend, Inc. + Akka + Lightbend, Inc. dba Akka }, @@ -412,7 +453,7 @@ lazy val library = configureAsSubproject(project) name := "scala-library", description := "Scala Standard Library", Compile / scalacOptions ++= Seq("-sourcepath", (Compile / scalaSource).value.toString), - Compile / scalacOptions ++= Seq("-Xlint", "-feature"), + Compile / scalacOptions ++= Seq("-Wconf:msg=method box|method anyValClass:s"), // unused params in patched src Compile / doc / scalacOptions ++= { val libraryAuxDir = (ThisBuild / baseDirectory).value / "src/library-aux" Seq( @@ -431,7 +472,10 @@ lazy val library = configureAsSubproject(project) // Include *.txt files in source JAR: Compile / packageSrc / mappings ++= { val base = (Compile / unmanagedResourceDirectories).value - base ** "*.txt" pair Path.relativeTo(base) + (base ** "*.txt" pair Path.relativeTo(base)) ++ { + val auxBase = (ThisBuild / baseDirectory).value / "src/library-aux" + auxBase ** ("*.scala" || "*.java") pair Path.relativeTo(auxBase) + } }, Osgi.headers += "Import-Package" -> "sun.misc;resolution:=optional, *", Osgi.jarlist := true, @@ -460,9 +504,14 @@ lazy val reflect = configureAsSubproject(project) name := "scala-reflect", description := "Scala Reflection Library", Osgi.bundleName := "Scala Reflect", - Compile / scalacOptions ++= Seq("-Xlint", "-feature"), + Compile / scalacOptions ++= Seq( + "-Wconf:cat=deprecation&msg=early initializers:s", // compiler heavily relies upon early initializers + "-Xlint", + "-feature", + ), Compile / doc / scalacOptions ++= Seq( - "-skip-packages", "scala.reflect.macros.internal:scala.reflect.internal:scala.reflect.io" + "-skip-packages", "scala.reflect.macros.internal:scala.reflect.internal:scala.reflect.io", + "-Xlint:-doc-detached,_", ), Osgi.headers += "Import-Package" -> (raw"""scala.*;version="$${range;[==,=+);$${ver}}",""" + @@ -489,9 +538,9 @@ lazy val compiler = configureAsSubproject(project) description := "Scala Compiler", libraryDependencies += asmDep, libraryDependencies += diffUtilsDep, - // These are only needed for the POM: + // This is only needed for the POM: // TODO: jline dependency is only needed for the REPL shell, which should move to its own jar - libraryDependencies ++= jlineDeps, + libraryDependencies += jlineDep, buildCharacterPropertiesFile := (Compile / resourceManaged).value / "scala-buildcharacter.properties", Compile / resourceGenerators += generateBuildCharacterPropertiesFile.map(file => Seq(file)).taskValue, // this a way to make sure that classes from interactive and scaladoc projects @@ -532,8 +581,7 @@ lazy val compiler = configureAsSubproject(project) ).get }, Compile / scalacOptions ++= Seq( - "-Xlint", - "-feature", + //"-Wunused", //"-Wnonunit-statement", "-Wconf:cat=deprecation&msg=early initializers:s", // compiler heavily relies upon early initializers ), Compile / doc / scalacOptions ++= Seq( @@ -545,7 +593,6 @@ lazy val compiler = configureAsSubproject(project) |org.jline.style.*;resolution:=optional |org.jline.terminal;resolution:=optional |org.jline.terminal.impl;resolution:=optional - |org.jline.terminal.impl.jna.*;resolution:=optional |org.jline.terminal.spi;resolution:=optional |org.jline.utils;resolution:=optional |org.jline.builtins;resolution:=optional @@ -574,7 +621,7 @@ lazy val interactive = configureAsSubproject(project) .settings( name := "scala-compiler-interactive", description := "Scala Interactive Compiler", - Compile / scalacOptions ++= Seq("-Xlint", "-Wconf:cat=deprecation&msg=early initializers:s"), + Compile / scalacOptions ++= Seq("-Wconf:cat=deprecation&msg=early initializers:s"), ) .dependsOn(compiler) @@ -582,7 +629,7 @@ lazy val repl = configureAsSubproject(project) .settings(disableDocs) .settings(fatalWarningsSettings) .settings(publish / skip := true) - .settings(Compile / scalacOptions ++= Seq("-Xlint", "-Wconf:cat=deprecation&msg=early initializers:s")) + .settings(Compile / scalacOptions ++= Seq("-Wconf:cat=deprecation&msg=early initializers:s")) .dependsOn(compiler, interactive) lazy val replFrontend = configureAsSubproject(project, srcdir = Some("repl-frontend")) @@ -590,13 +637,11 @@ lazy val replFrontend = configureAsSubproject(project, srcdir = Some("repl-front .settings(fatalWarningsSettings) .settings(publish / skip := true) .settings( - libraryDependencies ++= jlineDeps, + libraryDependencies += jlineDep, name := "scala-repl-frontend", - Compile / scalacOptions ++= Seq("-Xlint"), ) .settings( run := (Compile / run).partialInput(" -usejavacp").evaluated, // so `replFrontend/run` works - Compile / run / javaOptions += s"-Dscala.color=${!scala.util.Properties.isWin}", Compile / run / javaOptions += "-Dorg.jline.terminal.output=forced-out", ) .dependsOn(repl) @@ -612,7 +657,7 @@ lazy val scaladoc = configureAsSubproject(project) libraryDependencies ++= ScaladocSettings.webjarResources, Compile / resourceGenerators += ScaladocSettings.extractResourcesFromWebjar, Compile / scalacOptions ++= Seq( - "-Xlint", + "-Xlint:-doc-detached,_", "-feature", "-Wconf:cat=deprecation&msg=early initializers:s", ), @@ -629,8 +674,6 @@ lazy val sbtBridge = configureAsSubproject(project, srcdir = Some("sbt-bridge")) description := "sbt compiler bridge for Scala 2", libraryDependencies += compilerInterfaceDep % Provided, Compile / scalacOptions ++= Seq( - "-Xlint", - "-feature", "-Wconf:cat=deprecation&msg=early initializers:s", // compiler heavily relies upon early initializers ), generateServiceProviderResources("xsbti.compile.CompilerInterface2" -> "scala.tools.xsbt.CompilerBridge"), @@ -646,10 +689,10 @@ lazy val sbtBridge = configureAsSubproject(project, srcdir = Some("sbt-bridge")) ), headerLicense := Some(HeaderLicense.Custom( s"""Zinc - The incremental compiler for Scala. - |Copyright Scala Center, Lightbend, and Mark Harrah + |Copyright Scala Center, Lightbend dba Akka, and Mark Harrah | |Scala (${(ThisBuild/homepage).value.get}) - |Copyright EPFL and Lightbend, Inc. + |Copyright EPFL and Lightbend, Inc. dba Akka | |Licensed under Apache License 2.0 |(http://www.apache.org/licenses/LICENSE-2.0). @@ -674,7 +717,7 @@ lazy val scalap = configureAsSubproject(project) headerLicense := Some(HeaderLicense.Custom( s"""Scala classfile decoder (${(ThisBuild/homepage).value.get}) | - |Copyright EPFL and Lightbend, Inc. + |Copyright EPFL and Lightbend, Inc. dba Akka | |Licensed under Apache License 2.0 |(http://www.apache.org/licenses/LICENSE-2.0). @@ -687,7 +730,6 @@ lazy val scalap = configureAsSubproject(project) xs filter { x => !excluded(x.getName) } }, Compile / headerResources := Nil, - Compile / scalacOptions ++= Seq("-Xlint", "-feature"), ) .dependsOn(compiler) @@ -700,9 +742,11 @@ lazy val partest = configureAsSubproject(project) name := "scala-partest", description := "Scala Compiler Testing Tool", libraryDependencies ++= List(testInterfaceDep, diffUtilsDep, junitDep), + Compile / scalacOptions ++= Seq( + "-Wconf:cat=deprecation&msg=early initializers:s", // compiler heavily relies upon early initializers + ), Compile / javacOptions ++= Seq("-XDenableSunApiLintControl", "-Xlint") ++ (if (fatalWarnings.value) Seq("-Werror") else Seq()), - Compile / scalacOptions ++= Seq("-feature", "-Xlint"), pomDependencyExclusions ++= List((organization.value, "scala-repl-frontend"), (organization.value, "scala-compiler-doc")), fixPom( "/project/name" -> Scala Partest, @@ -712,7 +756,7 @@ lazy val partest = configureAsSubproject(project) ) lazy val tastytest = configureAsSubproject(project) - .dependsOn(library, reflect, compiler) + .dependsOn(library, reflect, compiler, scaladoc) .settings(disableDocs) .settings(fatalWarningsSettings) .settings(publish / skip := true) @@ -720,7 +764,6 @@ lazy val tastytest = configureAsSubproject(project) name := "scala-tastytest", description := "Scala TASTy Integration Testing Tool", libraryDependencies += diffUtilsDep, - Compile / scalacOptions ++= Seq("-feature", "-Xlint"), ) // An instrumented version of BoxesRunTime and ScalaRunTime for partest's "specialized" test category @@ -752,7 +795,6 @@ lazy val specLib = project.in(file("test") / "instrumented") patch("ScalaRunTime.scala", "srt.patch") ) }.taskValue, - Compile / scalacOptions ++= Seq("-feature", "-Xlint"), ) // The scala version used by the benchmark suites, leave undefined to use the ambient version.") @@ -790,7 +832,6 @@ lazy val testkit = configureAsSubproject(project) .settings( name := "scala-testkit", description := "Scala Compiler Testkit", - Compile / scalacOptions ++= Seq("-feature", "-Xlint"), libraryDependencies ++= Seq(junitDep, asmDep), Compile / unmanagedSourceDirectories := List(baseDirectory.value), fixPom( @@ -804,7 +845,8 @@ lazy val testkit = configureAsSubproject(project) // This is enforced by error (not just by warning) since JDK 16. In our tests we use reflective access // from the unnamed package (the classpath) to JDK modules in testing utilities like `assertNotReachable`. // `add-exports=jdk.jdeps/com.sun.tools.javap` is tests that use `:javap` in the REPL, see scala/bug#12378 -val addOpensForTesting = "-XX:+IgnoreUnrecognizedVMOptions" +: "--add-exports=jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED" +: +// Also --enable-native-access is needed for jvm/natives.scala +val addOpensForTesting = "-XX:+IgnoreUnrecognizedVMOptions" +: "--add-exports=jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED" +: "--enable-native-access=ALL-UNNAMED" +: Seq("java.util.concurrent.atomic", "java.lang", "java.lang.reflect", "java.net").map(p => s"--add-opens=java.base/$p=ALL-UNNAMED") lazy val junit = project.in(file("test") / "junit") @@ -819,8 +861,7 @@ lazy val junit = project.in(file("test") / "junit") (Test / forkOptions) := (Test / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value), (Test / testOnly / forkOptions) := (Test / testOnly / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value), Compile / scalacOptions ++= Seq( - "-feature", - "-Xlint:-valpattern,_", + "-Xlint:-valpattern", "-Wconf:msg=match may not be exhaustive:s", // if we missed a case, all that happens is the test fails "-Wconf:cat=lint-nullary-unit&site=.*Test:s", // normal unit test style "-Ypatmat-exhaust-depth", "40", // despite not caring about patmat exhaustiveness, we still get warnings for this @@ -869,6 +910,9 @@ lazy val tasty = project.in(file("test") / "tasty") s"-Dtastytest.classpaths.scalaReflect=$scalaReflect", ) }, + Compile / scalacOptions ++= Seq( + "-Wconf:cat=lint-nullary-unit&site=.*Test:s", // normal unit test style + ), ) lazy val scalacheck = project.in(file("test") / "scalacheck") @@ -889,7 +933,11 @@ lazy val scalacheck = project.in(file("test") / "scalacheck") ), libraryDependencies ++= Seq(scalacheckDep, junitDep), Compile / unmanagedSourceDirectories := Nil, - Test / unmanagedSourceDirectories := List(baseDirectory.value) + Test / unmanagedSourceDirectories := List(baseDirectory.value), + Compile / scalacOptions ++= Seq( + "-Wconf:msg=match may not be exhaustive:s", // if we missed a case, all that happens is the test fails + "-Wconf:msg=Classes which cannot access Tree:s", // extension is irrelevant to tests + ), ) lazy val osgiTestFelix = osgiTestProject( @@ -964,15 +1012,12 @@ lazy val sbtTest = project.in(file("test") / "sbt-test") sbtTestDirectory := baseDirectory.value, scriptedBatchExecution := true, // set to `false` to execute each test in a separate sbt instance - scriptedParallelInstances := 2, // default is 1 + scriptedParallelInstances := 2, // hide sbt output of scripted tests scriptedBufferLog := true, scriptedLaunchOpts ++= Seq( - // work around https://github.com/sbt/sbt/issues/7463 - // we can remove it once we're on an sbt version with a fix. - "-Dsbt.io.jdktimestamps=true", "-Dplugin.scalaVersion=" + version.value, "-Dsbt.boot.directory=" + (target.value / ".sbt-scripted").getAbsolutePath, // Workaround sbt/sbt#3469 "-Dscripted.common=" + (baseDirectory.value / "common.sbt.template").getAbsolutePath, @@ -1047,7 +1092,6 @@ lazy val test = project IntegrationTest / fork := true, Compile / scalacOptions += "-Yvalidate-pos:parser,typer", IntegrationTest / javaOptions ++= List("-Xmx2G", "-Dpartest.exec.in.process=true", "-Dfile.encoding=UTF-8", "-Duser.language=en", "-Duser.country=US") ++ addOpensForTesting, - IntegrationTest / javaOptions ++= { if (scala.util.Properties.isJavaAtLeast("18")) List("-Djava.security.manager=allow") else Nil }, IntegrationTest / testOptions += Tests.Argument("-Dfile.encoding=UTF-8", "-Duser.language=en", "-Duser.country=US"), testFrameworks += new TestFramework("scala.tools.partest.sbt.Framework"), IntegrationTest / testOptions += Tests.Argument(s"-Dpartest.java_opts=-Xmx1024M -Xms64M ${addOpensForTesting.mkString(" ")}"), @@ -1131,7 +1175,7 @@ lazy val scalaDist = Project("scalaDist", file(".") / "target" / "scala-dist-dis (htmlOut ** "*.html").get ++ (fixedManOut ** "*.1").get }.taskValue, Compile / managedResourceDirectories := Seq((Compile / resourceManaged).value), - libraryDependencies ++= jlineDeps, + libraryDependencies += jlineDep, apiURL := None, fixPom( "/project/name" -> Scala Distribution Artifacts, @@ -1148,7 +1192,7 @@ def partestOnly(in: String): Def.Initialize[Task[Unit]] = def partestDesc(in: String): Def.Initialize[Task[(Result[Unit], String)]] = partestOnly(in).result map (_ -> s"partest $in") -lazy val root: Project = (project in file(".")) +lazy val scala2: Project = (project in file(".")) .settings(disableDocs) .settings(generateBuildCharacterFileSettings) .settings( @@ -1293,7 +1337,7 @@ lazy val dist = (project in file("dist")) .settings(commonSettings) .settings( bspEnabled := false, - libraryDependencies ++= jlineDeps, + libraryDependencies += jlineDep, mkBin := mkBinImpl.value, mkQuick := Def.task { val cp = (testP / IntegrationTest / fullClasspath).value @@ -1308,11 +1352,7 @@ lazy val dist = (project in file("dist")) Compile / packageBin := { val targetDir = (ThisBuild / buildDirectory).value / "pack" / "lib" val jlineJAR = findJar((Compile / dependencyClasspath).value, jlineDep).get.data - val jnaJAR = findJar((Compile / dependencyClasspath).value, jnaDep).get.data - val mappings = Seq( - (jlineJAR, targetDir / "jline.jar"), - (jnaJAR, targetDir / "jna.jar"), - ) + val mappings = Seq((jlineJAR, targetDir / "jline.jar")) IO.copy(mappings, CopyOptions() withOverwrite true) targetDir }, diff --git a/doc/LICENSE.md b/doc/LICENSE.md index 78d04c6f44d2..a85420a7d71c 100644 --- a/doc/LICENSE.md +++ b/doc/LICENSE.md @@ -2,9 +2,9 @@ Scala is licensed under the [Apache License Version 2.0](https://www.apache.org/ ## Scala License -Copyright (c) 2002-2024 EPFL +Copyright (c) 2002-2025 EPFL -Copyright (c) 2011-2024 Lightbend, Inc. +Copyright (c) 2011-2025 Lightbend, Inc. dba Akka All rights reserved. @@ -25,11 +25,6 @@ limitations under the License. This software includes projects with the following licenses, which are also included in the `licenses/` directory: -### [Apache License](http://www.apache.org/licenses/LICENSE-2.0.html) -This license is used by the following third-party libraries: - - * JNA - ### [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause) This license is used by the following third-party libraries: diff --git a/doc/License.rtf b/doc/License.rtf index eb2f0de43c42..d92cb8ba249e 100644 --- a/doc/License.rtf +++ b/doc/License.rtf @@ -23,8 +23,8 @@ Scala is licensed under the\'a0{\field{\*\fldinst{HYPERLINK "https://www.apache. \fs48 \cf2 Scala License\ \pard\pardeftab720\sl360\sa320\partightenfactor0 -\f0\b0\fs28 \cf2 Copyright (c) 2002-2024 EPFL\ -Copyright (c) 2011-2024 Lightbend, Inc.\ +\f0\b0\fs28 \cf2 Copyright (c) 2002-2025 EPFL\ +Copyright (c) 2011-2025 Lightbend, Inc. dba Akka\ All rights reserved.\ \pard\pardeftab720\sl360\sa320\partightenfactor0 \cf2 \cb4 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at {\field{\*\fldinst{HYPERLINK "http://www.apache.org/licenses/LICENSE-2.0"}}{\fldrslt http://www.apache.org/licenses/LICENSE-2.0}}.\ @@ -40,17 +40,6 @@ Unless required by applicable law or agreed to in writing, software distributed \f0\b0\fs28 \cf2 This software includes projects with the following licenses, which are also included in the\'a0\cb5 licenses/\cb1 \'a0directory:\ \pard\pardeftab720\sl300\partightenfactor0 -\f1\b \cf3 \ -\pard\pardeftab720\sl360\sa320\partightenfactor0 -{\field{\*\fldinst{HYPERLINK "http://www.apache.org/licenses/LICENSE-2.0.html"}}{\fldrslt \cf3 Apache License}}\cf2 \ -\pard\pardeftab720\sl360\sa320\partightenfactor0 - -\f0\b0 \cf2 This license is used by the following third-party libraries:\ -\pard\tx220\tx720\pardeftab720\li720\fi-720\sl360\partightenfactor0 -\ls1\ilvl0\cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 -JNA\ -\pard\pardeftab720\sl300\partightenfactor0 - \f1\b \cf3 \ \pard\pardeftab720\sl360\sa320\partightenfactor0 {\field{\*\fldinst{HYPERLINK "http://www.opensource.org/licenses/bsd-license.php"}}{\fldrslt \cf3 BSD License}}\cf2 \ diff --git a/doc/internal/tastyreader.md b/doc/internal/tastyreader.md index 2075f4885dc8..8f39f7815438 100644 --- a/doc/internal/tastyreader.md +++ b/doc/internal/tastyreader.md @@ -99,7 +99,7 @@ In the above, relative paths will be calculated from the working directory of `t Because these commands are run from sbt, incremental changes can be made to the code for the TASTy reader and then step `2` can be immediately re-run to observe new behaviour of the compiler. -In the output of the above step `2`, you will see the the following snippet, showing progress in traversing TASTy and understanding the definition of `trait Dull`: +In the output of the above step `2`, you will see the following snippet, showing progress in traversing TASTy and understanding the definition of `trait Dull`: ```scala #[trait Dull]: Addr(4) completing Symbol(trait Dull, #6286): #[trait Dull]: Addr(7) No symbol found at current address, ensuring one exists: diff --git a/doc/licenses/apache_jna.txt b/doc/licenses/apache_jna.txt deleted file mode 100644 index 592efd6604bd..000000000000 --- a/doc/licenses/apache_jna.txt +++ /dev/null @@ -1,205 +0,0 @@ -Scala includes the JLine library, which includes the JNA library, -which is made available under multiple licenses, including the -Apache 2 license: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/project/DottySupport.scala b/project/DottySupport.scala index 22b1bf128260..37d555440088 100644 --- a/project/DottySupport.scala +++ b/project/DottySupport.scala @@ -12,7 +12,7 @@ import sbt.librarymanagement.{ * Settings to support validation of TastyUnpickler against the release of dotty with the matching TASTy version */ object TastySupport { - val supportedTASTyRelease = "3.4.0" // TASTY: 28.4-0 + val supportedTASTyRelease = "3.6.4" // TASTY: 28.6-0 val scala3Compiler = "org.scala-lang" % "scala3-compiler_3" % supportedTASTyRelease val scala3Library = "org.scala-lang" % "scala3-library_3" % supportedTASTyRelease @@ -69,7 +69,9 @@ object DottySupport { object DottyLibrarySourceFilter extends FileFilter { def accept(file: File): Boolean = { val name = file.getName - file.isFile && (name.endsWith(".scala") || name.endsWith(".java")) + file.isFile && + (name.endsWith(".scala") || name.endsWith(".java")) && + !Set("AnyKind.scala", "Matchable.scala").contains(name) } } diff --git a/project/GenerateAnyVals.scala b/project/GenerateAnyVals.scala index ed2b93f07856..df9917c21f31 100644 --- a/project/GenerateAnyVals.scala +++ b/project/GenerateAnyVals.scala @@ -280,7 +280,7 @@ trait GenerateAnyValTemplates { def headerTemplate = """/* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -503,7 +503,7 @@ override def getClass(): Class[Boolean] = ??? } object GenerateAnyVals { - def run(outDir: java.io.File) { + def run(outDir: java.io.File): Unit = { val av = new GenerateAnyVals av.make() foreach { case (name, code ) => diff --git a/project/GenerateDocsData.scala b/project/GenerateDocsData.scala index 24d5d8475549..bb3f85a05bdb 100644 --- a/project/GenerateDocsData.scala +++ b/project/GenerateDocsData.scala @@ -162,7 +162,7 @@ object GenerateDocsData { import java.nio.charset.StandardCharsets.UTF_8 // output a descriptor of compiler options for docs.scala-lang/_data - def run(outDir: File) { + def run(outDir: File): Unit = { val file = new File(outDir, "compiler-options.yml") val res = new SettingsDescriptor().descriptor sbt.IO.write(file, res, UTF_8, false) diff --git a/project/GenerateFunctionConverters.scala b/project/GenerateFunctionConverters.scala index 52e02adfbb41..31ef68cdb3c0 100644 --- a/project/GenerateFunctionConverters.scala +++ b/project/GenerateFunctionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,7 +17,7 @@ object GenerateFunctionConverters { s"""/* | * Scala (https://www.scala-lang.org) | * - | * Copyright EPFL and Lightbend, Inc. + | * Copyright EPFL and Lightbend, Inc. dba Akka | * | * Licensed under Apache License 2.0 | * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/project/MimaFilters.scala b/project/MimaFilters.scala index 186652ae4a76..e7351aa1b6d5 100644 --- a/project/MimaFilters.scala +++ b/project/MimaFilters.scala @@ -13,7 +13,7 @@ object MimaFilters extends AutoPlugin { import autoImport._ override val globalSettings = Seq( - mimaReferenceVersion := Some("2.13.12"), + mimaReferenceVersion := Some("2.13.16"), ) val mimaFilters: Seq[ProblemFilter] = Seq[ProblemFilter]( @@ -39,8 +39,42 @@ object MimaFilters extends AutoPlugin { ProblemFilters.exclude[DirectMissingMethodProblem]("scala.concurrent.impl.FutureConvertersImpl#P.accept"), ProblemFilters.exclude[IncompatibleMethTypeProblem]("scala.concurrent.impl.FutureConvertersImpl#P.andThen"), - // 2.13.13; it's okay because the class is private - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.immutable.MapNodeRemoveAllSetNodeIterator.next"), + // KEEP: the CommonErrors object is not a public API + ProblemFilters.exclude[MissingClassProblem]("scala.collection.generic.CommonErrors"), + ProblemFilters.exclude[MissingClassProblem]("scala.collection.generic.CommonErrors$"), + + // scala/scala#10937 + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.LazyList#LazyBuilder#DeferredState.eval"), + ProblemFilters.exclude[MissingClassProblem](s"scala.collection.immutable.LazyList$$State"), + ProblemFilters.exclude[MissingClassProblem](s"scala.collection.immutable.LazyList$$State$$"), + ProblemFilters.exclude[MissingClassProblem](s"scala.collection.immutable.LazyList$$State$$Cons"), + ProblemFilters.exclude[MissingClassProblem](s"scala.collection.immutable.LazyList$$State$$Empty$$"), + ProblemFilters.exclude[MissingClassProblem]("scala.collection.immutable.LazyList$EmptyMarker$"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.LazyList#LazyBuilder#DeferredState.eval"), + ProblemFilters.exclude[MissingClassProblem]("scala.collection.immutable.LazyList$MidEvaluation$"), + ProblemFilters.exclude[MissingClassProblem]("scala.collection.immutable.LazyList$Uninitialized$"), + + // scala/scala#11004 + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.api.Annotations#AnnotationApi.argIsDefault"), + // A new abstract trait method is not binary compatible in principle, but `AnnotationApi` is only implemented by + // `AnnotationInfo`, both of which are in scala-reflect.jar. So this should never leak. + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.reflect.api.Annotations#AnnotationApi.argIsDefault"), + + // scala/scala#10976 + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.meta.defaultArg"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.meta.superArg"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.meta.superFwdArg"), + + ProblemFilters.exclude[MissingClassProblem]("scala.collection.IndexedSeqSlidingIterator"), + ProblemFilters.exclude[NewMixinForwarderProblem]("scala.collection.IndexedSeqOps.sliding"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.mutable.ArrayDequeOps.scala$collection$mutable$ArrayDequeOps$$super$sliding"), + + // new jdk 25 method in CharSequence => mixin forwarders + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Predef#ArrayCharSequence.getChars"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Predef#SeqCharSequence.getChars"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.mutable.StringBuilder.getChars"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.ArrayCharSequence.getChars"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.SeqCharSequence.getChars"), ) override val buildSettings = Seq( diff --git a/project/PartestUtil.scala b/project/PartestUtil.scala index 672b70a60fa7..01a3db2eb27d 100644 --- a/project/PartestUtil.scala +++ b/project/PartestUtil.scala @@ -72,7 +72,7 @@ object PartestUtil { val next = prefix + suffix testFile.getParentFile / next } - val assocFiles = List(".check", ".flags").map(sibling) + val assocFiles = List(".check").map(sibling) val sourceFiles = if (testFile.isFile) List(testFile) else testFile.**(AllPassFilter).get.toList val allFiles = testFile :: assocFiles ::: sourceFiles allFiles.exists(f => f.isFile && re.findFirstIn(IO.read(f)).isDefined) @@ -89,7 +89,7 @@ object PartestUtil { (matchingFileContent ++ matchingFileName).map(_._2).distinct.sorted } - val completion = Completions.strict(Set("", " (for source, flags or checkfile contents)").map(s => Completion.displayOnly(s))) + val completion = Completions.strict(Set("", " (for source or checkfile contents)").map(s => Completion.displayOnly(s))) val tokenCompletion = TokenCompletions.fixed((seen, level) => completion) val globOrPattern = StringBasic.map(expandGrep).flatMap { diff --git a/project/ScalaOptionParser.scala b/project/ScalaOptionParser.scala index 9378b7edcd42..d93f777efe55 100644 --- a/project/ScalaOptionParser.scala +++ b/project/ScalaOptionParser.scala @@ -83,7 +83,7 @@ object ScalaOptionParser { // TODO retrieve these data programmatically, ala https://github.com/scala/scala-tool-support/blob/master/bash-completion/src/main/scala/BashCompletion.scala private def booleanSettingNames = List("-X", "-Xasync", "-Xcheckinit", "-Xdev", "-Xdisable-assertions", "-Xexperimental", "-Xfatal-warnings", "-Xlog-free-terms", "-Xlog-free-types", "-Xlog-implicit-conversions", "-Xlog-reflective-calls", - "-Xno-forwarders", "-Xno-patmat-analysis", "-Xnon-strict-patmat-analysis", "-Xprint-pos", "-Xprint-types", "-Xprompt", "-Xresident", "-Xshow-phases", "-Xverify", "-Y", + "-Xnojline", "-Xno-forwarders", "-Xno-patmat-analysis", "-Xnon-strict-patmat-analysis", "-Xprint-pos", "-Xprint-types", "-Xprompt", "-Xresident", "-Xshow-phases", "-Xverify", "-Y", "-Ybreak-cycles", "-Ydebug", "-Ydebug-type-error", "-Ycompact-trees", "-YdisableFlatCpCaching", "-Ydoc-debug", "-Yide-debug", "-Ylog-classpath", "-Ymacro-debug-lite", "-Ymacro-debug-verbose", "-Ymacro-no-expand", @@ -140,5 +140,5 @@ object ScalaOptionParser { private def scaladocPathSettingNames = List("-doc-root-content", "-diagrams-dot-path") private def scaladocMultiStringSettingNames = List("-doc-external-doc") - private val targetSettingNames = (8 to 22).map(_.toString).flatMap(v => v :: s"jvm-1.$v" :: s"jvm-$v" :: s"1.$v" :: Nil).toList + private val targetSettingNames = (8 to 25).map(_.toString).flatMap(v => v :: s"jvm-1.$v" :: s"jvm-$v" :: s"1.$v" :: Nil).toList } diff --git a/project/ScriptCommands.scala b/project/ScriptCommands.scala index 01d8fd82b3d1..87f046ccbcb4 100644 --- a/project/ScriptCommands.scala +++ b/project/ScriptCommands.scala @@ -28,9 +28,8 @@ object ScriptCommands { def setupPublishCoreNonOpt = setup("setupPublishCoreNonOpt") { args => Seq( Global / baseVersionSuffix := "SHA-SNAPSHOT" - ) ++ (args match { - case Seq(url) => publishTarget(url) - case Nil => Nil + ) ++ (args flatMap { + case url => publishTarget(url) }) ++ noDocs } @@ -38,10 +37,9 @@ object ScriptCommands { * The optional argument is the Artifactory snapshot repository URL. */ def setupPublishCore = setup("setupPublishCore") { args => Seq( - Global / baseVersionSuffix := "SHA-SNAPSHOT" - ) ++ (args match { - case Seq(url) => publishTarget(url) - case Nil => Nil + Global / baseVersionSuffix := "SHA-SNAPSHOT", + ) ++ (args flatMap { + case url => publishTarget(url) }) ++ noDocs ++ enableOptimizer } @@ -49,10 +47,12 @@ object ScriptCommands { * The optional argument is the Artifactory snapshot repository URL. */ def setupValidateTest = setup("setupValidateTest") { args => Seq( + // include sha to prevent multiple builds running on the same jenkins worker from overriding each other + // sbtTest/scripted uses publishLocal + Global / baseVersionSuffix := "SHA-TEST-SNAPSHOT", LocalProject("test") / IntegrationTest / testOptions ++= Seq(Tests.Argument("--show-log"), Tests.Argument("--show-diff")) - ) ++ (args match { - case Seq(url) => Seq(Global / resolvers += "scala-pr" at url) - case Nil => Nil + ) ++ (args flatMap { + case url => Seq(Global / resolvers += "scala-pr" at url) }) ++ enableOptimizer } diff --git a/project/TestJDeps.scala b/project/TestJDeps.scala index 7dfa69c47453..4d76b43d7105 100644 --- a/project/TestJDeps.scala +++ b/project/TestJDeps.scala @@ -1,21 +1,29 @@ package scala.build import sbt._, Keys._ +import scala.util.Properties.isJavaAtLeast object TestJDeps { val testJDepsImpl: Def.Initialize[Task[Unit]] = Def.task { val libraryJar = (LocalProject("library") / Compile / packageBin).value val reflectJar = (LocalProject("reflect") / Compile / packageBin).value + val log = streams.value.log + // in JDK 22, the already-deprecated `-P` option to jdeps was removed, + // so we can't do the test. it's fine -- it will be a long, long time + // (probably never) before Scala 2's minimum JVM version is 22+ + if (isJavaAtLeast("22")) + log.info("can't test jdeps on JDK 22+") + else { + // jdeps -s -P build/pack/lib/scala-{library,reflect}.jar | grep -v build/pack | perl -pe 's/.*\((.*)\)$/$1/' | sort -u + val jdepsOut = scala.sys.process.Process("jdeps", Seq("-s", "-P", libraryJar.getPath, reflectJar.getPath)).lineStream - // jdeps -s -P build/pack/lib/scala-{library,reflect}.jar | grep -v build/pack | perl -pe 's/.*\((.*)\)$/$1/' | sort -u - val jdepsOut = scala.sys.process.Process("jdeps", Seq("-s", "-P", libraryJar.getPath, reflectJar.getPath)).lineStream + val profilePart = ".*\\((.*)\\)$".r + val profiles = jdepsOut.collect { + case profilePart(profile) => profile + }.toSet - val profilePart = ".*\\((.*)\\)$".r - val profiles = jdepsOut.collect { - case profilePart(profile) => profile - }.toSet - - if (profiles != Set("compact1")) - throw new RuntimeException(jdepsOut.mkString("Detected dependency outside of compact1:\n", "\n", "")) + if (profiles != Set("compact1")) + throw new RuntimeException(jdepsOut.mkString("Detected dependency outside of compact1:\n", "\n", "")) + } } } diff --git a/project/TestJarSize.scala b/project/TestJarSize.scala index 5d2e0f833dab..ffe5fb4c7766 100644 --- a/project/TestJarSize.scala +++ b/project/TestJarSize.scala @@ -6,7 +6,7 @@ object TestJarSize { final private case class JarSize(currentBytes: Long, errorThreshold: Double, warnThreshold: Double) private val libraryJarSize = JarSize(5926587L, 1.03, 1.015) - private val reflectJarSize = JarSize(3702957L, 1.03, 1.015) + private val reflectJarSize = JarSize(3814060L, 1.03, 1.015) val testJarSizeImpl: Def.Initialize[Task[Unit]] = Def.task { Def.unit(testJarSize1("library", libraryJarSize).value) diff --git a/project/VersionUtil.scala b/project/VersionUtil.scala index 49afb6b0a3ec..bbb94bfa77eb 100644 --- a/project/VersionUtil.scala +++ b/project/VersionUtil.scala @@ -29,7 +29,7 @@ object VersionUtil { ) lazy val generatePropertiesFileSettings = Seq[Setting[_]]( - copyrightString := "Copyright 2002-2024, LAMP/EPFL and Lightbend, Inc.", + copyrightString := "Copyright 2002-2025, LAMP/EPFL and Lightbend, Inc. dba Akka", shellBannerString := """ | ________ ___ / / ___ | / __/ __// _ | / / / _ | @@ -142,11 +142,12 @@ object VersionUtil { } val (canonicalV, mavenSuffix, osgiV, release) = suffix match { - case "SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-SNAPSHOT", s"$base.v$date-$sha", false) - case "SHA-SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-$sha-SNAPSHOT", s"$base.v$date-$sha", false) - case "SHA" => (s"$base-$sha", s"-$cross-$sha", s"$base.v$date-$sha", false) - case "" => (s"$base", "", s"$base.v$date-VFINAL-$sha", true) - case _ => (s"$base-$suffix", s"-$suffix", s"$base.v$date-$suffix-$sha", true) + case "SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-SNAPSHOT", s"$base.v$date-$sha", false) + case "SHA-SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-$sha-SNAPSHOT", s"$base.v$date-$sha", false) + case "SHA-TEST-SNAPSHOT" => (s"$base-$date-$sha", s"-$cross-$sha-TEST-SNAPSHOT", s"$base.v$date-$sha", false) + case "SHA" => (s"$base-$sha", s"-$cross-$sha", s"$base.v$date-$sha", false) + case "" => (s"$base", "", s"$base.v$date-VFINAL-$sha", true) + case _ => (s"$base-$suffix", s"-$suffix", s"$base.v$date-$suffix-$sha", true) } diff --git a/project/build.properties b/project/build.properties index abbbce5da4a8..cc68b53f1a30 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 +sbt.version=1.10.11 diff --git a/project/genprod.scala b/project/genprod.scala index 565281847084..ec144322a083 100644 --- a/project/genprod.scala +++ b/project/genprod.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -62,7 +62,7 @@ object genprod { def header = """/* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/project/plugins.sbt b/project/plugins.sbt index 731e0d50bea9..d8be38f31bf4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,7 +6,7 @@ scalacOptions ++= Seq( "-Werror", "-Wconf:msg=IntegrationTest .* is deprecated:s,msg=itSettings .* is deprecated:s") -libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.14.0" +libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.17.0" libraryDependencies += "biz.aQute.bnd" % "biz.aQute.bndlib" % "6.1.0" @@ -22,7 +22,7 @@ buildInfoKeys := Seq[BuildInfoKey](buildClasspath) buildInfoPackage := "scalabuild" -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.3") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.4") libraryDependencies ++= Seq( "org.eclipse.jgit" % "org.eclipse.jgit" % "4.11.9.201909030838-r", @@ -37,3 +37,5 @@ Global / concurrentRestrictions := Seq( addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.10.0") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.7") + +addSbtPlugin("com.gradle" % "sbt-develocity" % "1.2.1") diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt index 71982a81514a..ddfa827f9362 100644 --- a/project/project/plugins.sbt +++ b/project/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.13.1") diff --git a/scripts/common b/scripts/common index c069088bd762..e00731fcc01b 100644 --- a/scripts/common +++ b/scripts/common @@ -13,9 +13,7 @@ fi SBT_VERSION=`grep sbt.version $WORKSPACE/project/build.properties | sed -n 's/sbt.version=\(.*\)/\1/p'` SBT_CMD=${SBT_CMD-sbt} -# the jdktimestamps thing is to work around https://github.com/sbt/sbt/issues/7463 -- -# it can be removed again once we're on an sbt version with a fix -SBT_CMD="$SBT_CMD -Dsbt.io.jdktimestamps=true -sbt-version $SBT_VERSION" +SBT_CMD="$SBT_CMD -sbt-version $SBT_VERSION" # repo to publish builds integrationRepoUrl=${integrationRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-integration/"} diff --git a/scripts/jobs/validate/publish-core b/scripts/jobs/validate/publish-core index ff9cbc2c9c58..e04c91177b55 100755 --- a/scripts/jobs/validate/publish-core +++ b/scripts/jobs/validate/publish-core @@ -28,7 +28,7 @@ case $prDryRun in if $libraryAvailable && $reflectAvailable && $compilerAvailable; then echo "Scala core already built!" else - $SBT -warn "setupPublishCore $prRepoUrl" publish + $SBT -Dscala.build.publishDevelocity=build -warn "setupPublishCore $prRepoUrl" publish fi mv buildcharacter.properties jenkins.properties # parsed by the jenkins job diff --git a/scripts/jobs/validate/test b/scripts/jobs/validate/test index 7dd61c837bcc..e8e94c2e4ed1 100755 --- a/scripts/jobs/validate/test +++ b/scripts/jobs/validate/test @@ -18,6 +18,7 @@ case $prDryRun in # and run JUnit tests, ScalaCheck tests, partest, OSGi tests, MiMa and scaladoc $SBT \ -Dstarr.version=$scalaVersion \ + -Dscala.build.publishDevelocity=test \ -warn \ "setupValidateTest $prRepoUrl" \ $testExtraArgs \ diff --git a/spec/11-annotations.md b/spec/11-annotations.md index 9b5a0f80c5e2..64cf28243373 100644 --- a/spec/11-annotations.md +++ b/spec/11-annotations.md @@ -18,13 +18,12 @@ A simple annotation has the form `@´c´` or `@´c(a_1 , \ldots , a_n)´`. Here, ´c´ is a constructor of a class ´C´, which must conform to the class `scala.Annotation`. -Annotations may apply to definitions or declarations, types, or -expressions. An annotation of a definition or declaration appears in -front of that definition. An annotation of a type appears after -that type. An annotation of an expression ´e´ appears after the -expression ´e´, separated by a colon. More than one annotation clause -may apply to an entity. The order in which these annotations are given -does not matter. +Annotations may apply to definitions, types, or expressions. +An annotation of a definition appears in front of that definition. +An annotation of a type appears after that type. +An annotation of an expression appears after that expression, separated by a colon. +More than one annotation clause may apply to an entity. +The order in which these annotations are given does not matter. Examples: @@ -37,15 +36,13 @@ String @local // Type annotation ## Predefined Annotations -Predefined annotations are found in the `scala.annotation` package, -and also in the `scala` package. +Predefined annotations are found in the `scala.annotation` package, and also in the `scala` package. ### Scala Compiler Annotations * `@tailrec` Marks a method which must be transformed by the compiler to eliminate self-recursive invocations in tail position. - It is an error if there are no such invocations, or a recursive call - not in tail position. + It is an error if there are no such invocations, or a recursive call not in tail position. * `@switch` Marks the expression submitted to a match as "switchable", such that the match can be compiled to an efficient form. @@ -64,11 +61,9 @@ and also in the `scala` package. val Some(y) = x: @unchecked ``` - Without the `@unchecked` annotation, a Scala compiler could - infer that the pattern match is non-exhaustive, and could produce a - warning because `Option` is a `sealed` class. + Without the `@unchecked` annotation, a Scala compiler could infer that the pattern match is non-exhaustive and issue a warning because `Option` is a `sealed` class. - * `@uncheckedStable` When applied a value declaration or definition, it allows the defined + * `@uncheckedStable` When applied to a value definition, it allows the defined value to appear in a path, even if its type is [volatile](03-types.html#volatile-types). For instance, the following member definitions are legal: @@ -83,11 +78,9 @@ and also in the `scala` package. would not be a path since its type `A with B` is volatile. Hence, the reference `x.T` would be malformed. - When applied to value declarations or definitions that have non-volatile - types, the annotation has no effect. + When applied to value definitions that have no volatile types, the annotation has no effect. - * `@specialized` When applied to the definition of a type parameter, - this annotation causes the compiler to generate specialized definitions for primitive types. + * `@specialized` When applied to the definition of a type parameter, this annotation causes the compiler to generate definitions that are specialized for primitive types. An optional list of primitive types may be given, in which case specialization takes into account only those types. For instance, the following code would generate specialized traits for @@ -100,7 +93,7 @@ and also in the `scala` package. ``` Whenever the static type of an expression matches a specialized variant of - a definition, the compiler will instead use the specialized version. + a definition, the compiler will use the specialized version instead. See the [specialization SID](https://docs.scala-lang.org/sips/scala-specialization.html) for more details of the implementation. ### Deprecation Annotations diff --git a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala index 351b1f64f33b..d2dfa1f8fa6c 100644 --- a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala +++ b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,12 +14,13 @@ package scala.reflect.macros package compiler import scala.tools.nsc.Global +import scala.util.{Failure, Success, Try} abstract class DefaultMacroCompiler extends Resolvers with Validators with Errors { val global: Global - import global._ + import global.{Try => _, _} import analyzer._ import treeInfo._ import definitions._ @@ -51,10 +52,10 @@ abstract class DefaultMacroCompiler extends Resolvers * or be a dummy instance of a macro bundle (e.g. new MyMacro(???).expand). */ def resolveMacroImpl: Tree = { - def tryCompile(compiler: MacroImplRefCompiler): scala.util.Try[Tree] = { - try { compiler.validateMacroImplRef(); scala.util.Success(compiler.macroImplRef) } - catch { case ex: MacroImplResolutionException => scala.util.Failure(ex) } - } + def tryCompile(compiler: MacroImplRefCompiler): Try[Tree] = + try { compiler.validateMacroImplRef(); Success(compiler.macroImplRef) } + catch { case ex: MacroImplResolutionException => Failure(ex) } + def wrong() = Try(MacroBundleWrongShapeError()) val vanillaImplRef = MacroImplRefCompiler(macroDdef.rhs.duplicate, isImplBundle = false) val (maybeBundleRef, methName, targs) = macroDdef.rhs.duplicate match { case Applied(Select(Applied(RefTree(qual, bundleName), _, Nil), methName), targs, Nil) => @@ -69,9 +70,16 @@ abstract class DefaultMacroCompiler extends Resolvers isImplBundle = true ) val vanillaResult = tryCompile(vanillaImplRef) - val bundleResult = tryCompile(bundleImplRef) + val bundleResult = + typer.silent(_.typedTypeConstructor(maybeBundleRef)) match { + case SilentResultValue(result) if looksLikeMacroBundleType(result.tpe) => + val bundle = result.tpe.typeSymbol + if (isMacroBundleType(bundle.tpe)) tryCompile(bundleImplRef) + else wrong() + case _ => wrong() + } - def ensureUnambiguousSuccess() = { + def ensureUnambiguousSuccess(): Unit = { // we now face a hard choice of whether to report ambiguity: // 1) when there are eponymous methods in both bundle and object // 2) when both references to eponymous methods are resolved successfully @@ -100,6 +108,7 @@ abstract class DefaultMacroCompiler extends Resolvers try { if (vanillaResult.isSuccess || bundleResult.isSuccess) ensureUnambiguousSuccess() if (vanillaResult.isFailure && bundleResult.isFailure) reportMostAppropriateFailure() + //else // TODO vanillaResult.orElse(bundleResult).get } catch { case MacroImplResolutionException(pos, msg) => diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala index 9891a1c35cf9..8dc8a73c7f69 100644 --- a/src/compiler/scala/reflect/macros/compiler/Errors.scala +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala index d9223501f530..0906331643a6 100644 --- a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala +++ b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -34,7 +34,7 @@ trait Resolvers { lazy val (macroImplRef, isBlackbox, macroImplOwner, macroImpl, targs) = typer.silent(_.typed(markMacroImplRef(untypedMacroImplRef)), reportAmbiguousErrors = false) match { case SilentResultValue(macroImplRef @ MacroImplReference(_, isBlackbox, owner, meth, targs)) => (macroImplRef, isBlackbox, owner, meth, targs) - case SilentResultValue(macroImplRef) => MacroImplReferenceWrongShapeError() + case SilentResultValue(_) => MacroImplReferenceWrongShapeError() case ste: SilentTypeError => abort(ste.err.errPos, ste.err.errMsg) } } diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala index 072a7e20db56..99f3bcddf9a4 100644 --- a/src/compiler/scala/reflect/macros/compiler/Validators.scala +++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -127,7 +127,7 @@ trait Validators { */ private lazy val macroImplSig: MacroImplSig = { val tparams = macroImpl.typeParams - val paramss = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => NoSymbol) + val paramss = transformTypeTagEvidenceParams(macroImplRef, (_, _) => NoSymbol) val ret = macroImpl.info.finalResultType MacroImplSig(tparams, paramss, ret) } diff --git a/src/compiler/scala/reflect/macros/contexts/Aliases.scala b/src/compiler/scala/reflect/macros/contexts/Aliases.scala index c43a235c395b..fc6762dc625c 100644 --- a/src/compiler/scala/reflect/macros/contexts/Aliases.scala +++ b/src/compiler/scala/reflect/macros/contexts/Aliases.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala index e0c1b71ca95a..369fbe1cc61f 100644 --- a/src/compiler/scala/reflect/macros/contexts/Context.scala +++ b/src/compiler/scala/reflect/macros/contexts/Context.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala index d9a3e01c519a..50b528c05b6d 100644 --- a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala +++ b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Evals.scala b/src/compiler/scala/reflect/macros/contexts/Evals.scala index d781dfce5198..6ff18a15644f 100644 --- a/src/compiler/scala/reflect/macros/contexts/Evals.scala +++ b/src/compiler/scala/reflect/macros/contexts/Evals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala b/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala index 857386f1ceca..8bac593b1628 100644 --- a/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala +++ b/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala b/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala index 39474ef043a6..292663c2fdb1 100644 --- a/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala +++ b/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala b/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala index c6dfc56d62e4..9d0f1ca47391 100644 --- a/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala +++ b/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Internals.scala b/src/compiler/scala/reflect/macros/contexts/Internals.scala index 267bbdcf9b1c..e7c0e726be13 100644 --- a/src/compiler/scala/reflect/macros/contexts/Internals.scala +++ b/src/compiler/scala/reflect/macros/contexts/Internals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala index 370eebcc2e88..00d1ce7dd4bb 100644 --- a/src/compiler/scala/reflect/macros/contexts/Names.scala +++ b/src/compiler/scala/reflect/macros/contexts/Names.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala index 2dfa8322503c..2084e0e748de 100644 --- a/src/compiler/scala/reflect/macros/contexts/Parsers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Reifiers.scala b/src/compiler/scala/reflect/macros/contexts/Reifiers.scala index 26c72f6ede4d..b8fe0ac6f510 100644 --- a/src/compiler/scala/reflect/macros/contexts/Reifiers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Reifiers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Traces.scala b/src/compiler/scala/reflect/macros/contexts/Traces.scala index 6487adec728d..49a4202a9102 100644 --- a/src/compiler/scala/reflect/macros/contexts/Traces.scala +++ b/src/compiler/scala/reflect/macros/contexts/Traces.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala index 804d5f126ad0..f5510145b22d 100644 --- a/src/compiler/scala/reflect/macros/contexts/Typers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/runtime/AbortMacroException.scala b/src/compiler/scala/reflect/macros/runtime/AbortMacroException.scala index cbdaa5d89300..232a484df032 100644 --- a/src/compiler/scala/reflect/macros/runtime/AbortMacroException.scala +++ b/src/compiler/scala/reflect/macros/runtime/AbortMacroException.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala index 2c0c230fb4ac..51facd4b713e 100644 --- a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala +++ b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala index ac22c3e7ec24..e3d2fb17054d 100644 --- a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala +++ b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/runtime/package.scala b/src/compiler/scala/reflect/macros/runtime/package.scala index 679be9ed9716..f7804661257a 100644 --- a/src/compiler/scala/reflect/macros/runtime/package.scala +++ b/src/compiler/scala/reflect/macros/runtime/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala index 76eb678d6946..16dc123cd9f9 100644 --- a/src/compiler/scala/reflect/macros/util/Helpers.scala +++ b/src/compiler/scala/reflect/macros/util/Helpers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/macros/util/Traces.scala b/src/compiler/scala/reflect/macros/util/Traces.scala index b87d82aae500..d2865b98b7f8 100644 --- a/src/compiler/scala/reflect/macros/util/Traces.scala +++ b/src/compiler/scala/reflect/macros/util/Traces.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/quasiquotes/Holes.scala b/src/compiler/scala/reflect/quasiquotes/Holes.scala index 448a9f740e58..fcf340297660 100644 --- a/src/compiler/scala/reflect/quasiquotes/Holes.scala +++ b/src/compiler/scala/reflect/quasiquotes/Holes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/reflect/quasiquotes/Parsers.scala index eb1310ed0d80..da1991a0b0e6 100644 --- a/src/compiler/scala/reflect/quasiquotes/Parsers.scala +++ b/src/compiler/scala/reflect/quasiquotes/Parsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -42,16 +42,16 @@ trait Parsers { self: Quasiquotes => val posMapList = posMap.toList def containsOffset(start: Int, end: Int) = start <= offset && offset < end def fallbackPosition = posMapList match { - case (pos1, (start1, end1)) :: _ if start1 > offset => pos1 - case _ :+ ((pos2, (start2, end2))) if end2 <= offset => pos2.withPoint(pos2.point + (end2 - start2)) - case x => throw new MatchError(x) + case (pos1, (start1, _)) :: _ if start1 > offset => pos1 + case _ :+ ((pos2, (start2, end2))) if end2 <= offset => pos2.withPoint(pos2.point + (end2 - start2)) + case x => throw new MatchError(x) } posMapList.sliding(2).collect { - case (pos1, (start1, end1)) :: _ if containsOffset(start1, end1) => (pos1, offset - start1) - case (pos1, (start1, end1)) :: (pos2, (start2, _)) :: _ if containsOffset(end1, start2) => (pos1, end1 - start1) - case _ :: (pos2, (start2, end2)) :: _ if containsOffset(start2, end2) => (pos2, offset - start2) - }.map { case (pos, offset) => - pos.withPoint(pos.point + offset) + case (pos1, (start1, end1)) :: _ if containsOffset(start1, end1) => (pos1, offset - start1) + case (pos1, (start1, end1)) :: (_, (start2, _)) :: _ if containsOffset(end1, start2) => (pos1, end1 - start1) + case _ :: (pos2, (start2, end2)) :: _ if containsOffset(start2, end2) => (pos2, offset - start2) + }.map { + case (pos, offset) => pos.withPoint(pos.point + offset) }.toList.headOption.getOrElse(fallbackPosition) } @@ -92,7 +92,7 @@ trait Parsers { self: Quasiquotes => case _ => gen.mkBlock(stats, doFlatten = true) } case nme.unapply => gen.mkBlock(stats, doFlatten = false) - case other => global.abort("unreachable") + case _ => global.abort("unreachable") } // tq"$a => $b" diff --git a/src/compiler/scala/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/reflect/quasiquotes/Placeholders.scala index 565436e7f459..fc4b03e19d9c 100644 --- a/src/compiler/scala/reflect/quasiquotes/Placeholders.scala +++ b/src/compiler/scala/reflect/quasiquotes/Placeholders.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/quasiquotes/Quasiquotes.scala b/src/compiler/scala/reflect/quasiquotes/Quasiquotes.scala index f112e7ccade5..16d28d9126bd 100644 --- a/src/compiler/scala/reflect/quasiquotes/Quasiquotes.scala +++ b/src/compiler/scala/reflect/quasiquotes/Quasiquotes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/reflect/quasiquotes/Reifiers.scala index 06b4c748b140..7143dd977c36 100644 --- a/src/compiler/scala/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/reflect/quasiquotes/Reifiers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -319,7 +319,7 @@ trait Reifiers { self: Quasiquotes => */ def group[T](lst: List[T])(similar: (T, T) => Boolean) = lst.foldLeft[List[List[T]]](List()) { case (Nil, el) => List(List(el)) - case (ll :+ (last @ (lastinit :+ lastel)), el) if similar(lastel, el) => ll :+ (last :+ el) + case (ll :+ (last @ _ :+ lastel), el) if similar(lastel, el) => ll :+ (last :+ el) case (ll, el) => ll :+ List(el) } @@ -363,7 +363,7 @@ trait Reifiers { self: Quasiquotes => case ParamPlaceholder(Hole(tree, DotDot)) => tree case SyntacticPatDef(mods, pat, tpt, rhs) => reifyBuildCall(nme.SyntacticPatDef, mods, pat, tpt, rhs) - case SyntacticValDef(mods, p @ Placeholder(h: ApplyHole), tpt, rhs) if h.tpe <:< treeType => + case SyntacticValDef(mods, Placeholder(h: ApplyHole), tpt, rhs) if h.tpe <:< treeType => mirrorBuildCall(nme.SyntacticPatDef, reify(mods), h.tree, reify(tpt), reify(rhs)) } diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 215633708961..80326d0ba4ac 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/Phases.scala b/src/compiler/scala/reflect/reify/Phases.scala index 873d44050e5b..cacca6b692fa 100644 --- a/src/compiler/scala/reflect/reify/Phases.scala +++ b/src/compiler/scala/reflect/reify/Phases.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index cebbae24fc33..f1e37b059703 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/States.scala b/src/compiler/scala/reflect/reify/States.scala index 979196bc8f61..a8a7dbc1241a 100644 --- a/src/compiler/scala/reflect/reify/States.scala +++ b/src/compiler/scala/reflect/reify/States.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala index 1acccf43ffee..b31d2201fe2f 100644 --- a/src/compiler/scala/reflect/reify/Taggers.scala +++ b/src/compiler/scala/reflect/reify/Taggers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -78,13 +78,13 @@ abstract class Taggers { translatingReificationErrors(materializer) } try c.typecheck(result) - catch { case terr @ TypecheckException(pos, msg) => failTag(result, terr) } + catch { case terr: TypecheckException => failTag(result, terr) } } def materializeExpr(universe: Tree, mirror: Tree, expr: Tree): Tree = { val result = translatingReificationErrors(c.reifyTree(universe, mirror, expr)) try c.typecheck(result) - catch { case terr @ TypecheckException(pos, msg) => failExpr(result, terr) } + catch { case terr: TypecheckException => failExpr(result, terr) } } private def translatingReificationErrors(materializer: => Tree): Tree = { @@ -92,7 +92,7 @@ abstract class Taggers { catch { case ReificationException(pos, msg) => c.abort(pos.asInstanceOf[c.Position], msg) // this cast is a very small price for the confidence of exception handling - case UnexpectedReificationException(pos, err, cause) if cause != null => + case UnexpectedReificationException(_, _, cause) if cause != null => throw cause } } diff --git a/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala index 62504d14d886..a7864168cc9d 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/codegen/GenNames.scala b/src/compiler/scala/reflect/reify/codegen/GenNames.scala index d083eb17daf0..0ae7bd3effce 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenNames.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenNames.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/codegen/GenPositions.scala b/src/compiler/scala/reflect/reify/codegen/GenPositions.scala index 429ee203027d..5d78f2eeea32 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenPositions.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenPositions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -23,6 +23,6 @@ trait GenPositions { // but I can hardly imagine when one would need a position that points to the reified code // usually reified trees are used to compose macro expansions or to be fed to the runtime compiler // however both macros and toolboxes have their own means to report errors in synthetic trees - def reifyPosition(pos: Position): Tree = - reifyMirrorObject(NoPosition) + @annotation.nowarn + def reifyPosition(pos: Position): Tree = reifyMirrorObject(NoPosition) } diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala index 3d79e4a4b2ae..f3217c23ab8e 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala index afd942b86613..a3a1040298b3 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index 560035aeb8ac..f555607c7022 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -46,35 +46,35 @@ trait GenTypes { if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic) Select(Select(reify(tsym), nme.asType), nme.toTypeConstructor) else tpe match { - case tpe : NoType.type => + case tpe: NoType.type => reifyMirrorObject(tpe) - case tpe : NoPrefix.type => + case tpe: NoPrefix.type => reifyMirrorObject(tpe) - case tpe @ ThisType(root) if root.isRoot => + case ThisType(root) if root.isRoot => mirrorBuildCall(nme.thisPrefix, mirrorMirrorSelect(nme.RootClass)) - case tpe @ ThisType(empty) if empty.isEmptyPackageClass => + case ThisType(empty) if empty.isEmptyPackageClass => mirrorBuildCall(nme.thisPrefix, mirrorMirrorSelect(nme.EmptyPackageClass)) - case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => + case ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => val module = reify(clazz.sourceModule) val moduleClass = Select(Select(module, nme.asModule), nme.moduleClass) mirrorBuildCall(nme.ThisType, moduleClass) - case tpe @ ThisType(sym) => + case ThisType(sym) => reifyBuildCall(nme.ThisType, sym) - case tpe @ SuperType(thistpe, supertpe) => + case SuperType(thistpe, supertpe) => reifyBuildCall(nme.SuperType, thistpe, supertpe) - case tpe @ SingleType(pre, sym) => + case SingleType(pre, sym) => reifyBuildCall(nme.SingleType, pre, sym) - case tpe @ ConstantType(value) => + case ConstantType(value) => mirrorBuildCall(nme.ConstantType, reifyProduct(value)) - case tpe @ TypeRef(pre, sym, args) => + case TypeRef(pre, sym, args) => reifyBuildCall(nme.TypeRef, pre, sym, args) - case tpe @ TypeBounds(lo, hi) => + case TypeBounds(lo, hi) => reifyBuildCall(nme.TypeBounds, lo, hi) - case tpe @ NullaryMethodType(restpe) => + case NullaryMethodType(restpe) => reifyBuildCall(nme.NullaryMethodType, restpe) - case tpe @ AnnotatedType(anns, underlying) => + case tpe: AnnotatedType => reifyAnnotatedType(tpe) - case _ => + case tpe => reifyToughType(tpe) } } @@ -165,7 +165,7 @@ trait GenTypes { * I.e. we can compile the code that involves `ru.Type`, but we cannot serialize an instance of `ru.Type`. */ private def reifySemiConcreteTypeMember(tpe: Type): Tree = tpe match { - case tpe @ TypeRef(pre @ SingleType(prepre, presym), sym, args) if sym.isAbstractType && !sym.isExistential => + case TypeRef(pre @ SingleType(_, _), sym, args) if sym.isAbstractType && !sym.isExistential => mirrorBuildCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args)) case x => throw new MatchError(x) } @@ -187,18 +187,18 @@ trait GenTypes { tpe match { case tpe @ RefinedType(parents, decls) => - reifySymDef(tpe.typeSymbol) + List(tpe.typeSymbol).foreach(reifySymDef) mirrorBuildCall(nme.RefinedType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) - case tpe @ ExistentialType(tparams, underlying) => - tparams foreach reifySymDef + case ExistentialType(tparams, underlying) => + tparams.foreach(reifySymDef) reifyBuildCall(nme.ExistentialType, tparams, underlying) case tpe @ ClassInfoType(parents, decls, clazz) => - reifySymDef(clazz) + List(clazz).foreach(reifySymDef) mirrorBuildCall(nme.ClassInfoType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) - case tpe @ MethodType(params, restpe) => + case MethodType(params, restpe) => params foreach reifySymDef reifyBuildCall(nme.MethodType, params, restpe) - case tpe @ PolyType(tparams, underlying) => + case PolyType(tparams, underlying) => tparams foreach reifySymDef reifyBuildCall(nme.PolyType, tparams, underlying) case _ => diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala index ebfca1a27fe0..19f8a84a742e 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -117,7 +117,7 @@ trait GenUtils { @tailrec final def isCrossStageTypeBearer(tree: Tree): Boolean = tree match { case TypeApply(hk, _) => isCrossStageTypeBearer(hk) - case Select(sym @ Select(_, ctor), nme.apply) if ctor == nme.WeakTypeTag || ctor == nme.TypeTag || ctor == nme.Expr => true + case Select(Select(_, nme.WeakTypeTag|nme.TypeTag|nme.Expr), nme.apply) => true case _ => false } diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 423645e4b815..3c4f85abc9b7 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala index 0263a7ea5e0c..b472e7e261ac 100644 --- a/src/compiler/scala/reflect/reify/phases/Calculate.scala +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -43,7 +43,7 @@ trait Calculate { /** * Merely traverses the target and records symbols local to the reifee along with their metalevels. */ - val calculate = new Traverser { + val calculate: Traverser = new Traverser { // see the explanation of metalevels in `Metalevels` var currMetalevel = 1 diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala index ea8c413521eb..88d768c31e4e 100644 --- a/src/compiler/scala/reflect/reify/phases/Metalevels.scala +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -113,7 +113,7 @@ trait Metalevels { * The reasoning from Example 2 still holds here - we do need to inline the freevar that refers to x. * However, we must not touch anything inside the splice'd block, because it's not getting reified. */ - val metalevels = new AstTransformer { + val metalevels: AstTransformer = new AstTransformer { var insideSplice = false val inlineableBindings = mutable.Map[TermName, Tree]() diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala index 02cf4ec09bf8..5c9472823492 100644 --- a/src/compiler/scala/reflect/reify/phases/Reify.scala +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 1dbc5af4df46..b04a64575798 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,7 @@ package scala.reflect.reify package phases -import scala.annotation.tailrec +import scala.annotation.{tailrec, unused} import scala.tools.nsc.symtab.Flags._ trait Reshape { @@ -37,7 +37,7 @@ trait Reshape { * * Transforming Annotated(annot, expr) into Typed(expr, TypeTree(Annotated(annot, _)) * * Non-idempotencies of the typechecker: https://github.com/scala/bug/issues/5464 */ - val reshape = new AstTransformer { + val reshape: AstTransformer = new AstTransformer { var currentSymbol: Symbol = NoSymbol override def transform(tree0: Tree) = { @@ -192,7 +192,7 @@ trait Reshape { @tailrec private def toPreTyperTypedOrAnnotated(tree: Tree): Tree = tree match { - case ty @ Typed(expr1, tpt) => + case ty @ Typed(_, tpt) => if (reifyDebug) println("reify typed: " + tree) val original = tpt match { case tt @ TypeTree() => tt.original @@ -201,11 +201,10 @@ trait Reshape { val annotatedArg = { @tailrec def loop(tree: Tree): Tree = tree match { - case annotated1 @ Annotated(ann, annotated2 @ Annotated(_, _)) => loop(annotated2) - case annotated1 @ Annotated(ann, arg) => arg + case Annotated(_, annotated2 @ Annotated(_, _)) => loop(annotated2) + case Annotated(_, arg) => arg case _ => EmptyTree } - loop(original) } if (annotatedArg != EmptyTree) { @@ -220,7 +219,7 @@ trait Reshape { if (reifyDebug) println("verdict: wasn't annotated, reify as usual") ty } - case at @ Annotated(annot, arg) => + case at @ Annotated(_, arg) => if (reifyDebug) println("reify type annotations for: " + tree) assert(at.tpe.isInstanceOf[AnnotatedType], "%s (%s)".format(at.tpe, at.tpe.kind)) val annot1 = toPreTyperAnnotation(at.tpe.asInstanceOf[AnnotatedType].annotations(0)) @@ -251,7 +250,7 @@ trait Reshape { New(TypeTree(ann.atp) setOriginal extractOriginal(ann.original), List(args)) } - private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = { + private def trimAccessors(@unused deff: Tree, stats: List[Tree]): List[Tree] = { val symdefs = (stats collect { case vodef: ValOrDefDef => vodef } map (vodeff => vodeff.symbol -> vodeff)).toMap val accessors = scala.collection.mutable.Map[ValDef, List[DefDef]]() stats collect { case ddef: DefDef => ddef } foreach (defdef => { @@ -311,7 +310,7 @@ trait Reshape { stats1 } - private def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]): List[Tree] = + private def trimSyntheticCaseClassMembers(@unused deff: Tree, stats: List[Tree]): List[Tree] = stats filterNot (memberDef => memberDef.isDef && { val isSynthetic = memberDef.symbol.isSynthetic // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass) diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala index df88e4d8e1a3..e47933e0016c 100644 --- a/src/compiler/scala/reflect/reify/utils/Extractors.scala +++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -242,8 +242,8 @@ trait Extractors { object TypeRefToFreeType { def unapply(tree: Tree): Option[TermName] = tree match { - case Apply(Select(Select(uref @ Ident(_), typeRef), apply), List(Select(_, noSymbol), Ident(freeType: TermName), nil)) - if (uref.name == nme.UNIVERSE_SHORT && typeRef == nme.TypeRef && noSymbol == nme.NoSymbol && freeType.startsWith(nme.REIFY_FREE_PREFIX)) => + case Apply(Select(Select(Ident(nme.UNIVERSE_SHORT), nme.TypeRef), apply@_), List(Select(_, nme.NoSymbol), Ident(freeType: TermName), _)) + if freeType.startsWith(nme.REIFY_FREE_PREFIX) => Some(freeType) case _ => None diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala index 83f27cb7d73a..b3bfa987038f 100644 --- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala +++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/reflect/reify/utils/StdAttachments.scala b/src/compiler/scala/reflect/reify/utils/StdAttachments.scala index 4a06b500e542..454e6ca669e2 100644 --- a/src/compiler/scala/reflect/reify/utils/StdAttachments.scala +++ b/src/compiler/scala/reflect/reify/utils/StdAttachments.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -23,7 +23,7 @@ trait StdAttachments { def reifyBinding(tree: Tree): Tree = tree.attachments.get[ReifyBindingAttachment] match { case Some(ReifyBindingAttachment(binding)) => binding - case other => Ident(NoSymbol) + case _ => Ident(NoSymbol) } case class ReifyAliasAttachment(sym: Symbol, alias: TermName) diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala index c48b2539d3e5..2b3af81f0367 100644 --- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala +++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,6 +13,7 @@ package scala.reflect.reify package utils +import scala.annotation._ import scala.collection.{immutable, mutable}, mutable.{ArrayBuffer, ListBuffer} import java.lang.System.{lineSeparator => EOL} @@ -89,7 +90,7 @@ trait SymbolTables { new SymbolTable(newSymtab, newAliases) } - def add(sym: Symbol, name0: TermName, reification: Tree): SymbolTable = { + def add(@unused sym: Symbol, name0: TermName, reification: Tree): SymbolTable = { def freshName(name0: TermName): TermName = { var name = name0.toString name = name.replace(".type", "$type") @@ -133,10 +134,11 @@ trait SymbolTables { s"""symtab = [$symtabString], aliases = [$aliasesString]${if (original.isDefined) ", has original" else ""}""" } + @nowarn // spurious unused buf.type def debugString: String = { val buf = new StringBuilder buf.append("symbol table = " + (if (syms.length == 0) "" else "")).append(EOL) - syms foreach (sym => buf.append(symDef(sym)).append(EOL)) + syms.foreach(sym => buf.append(symDef(sym)).append(EOL)) buf.delete(buf.length - EOL.length, buf.length) buf.toString } diff --git a/src/compiler/scala/reflect/reify/utils/Utils.scala b/src/compiler/scala/reflect/reify/utils/Utils.scala index d44d5f3443fb..585ab45c3afe 100644 --- a/src/compiler/scala/reflect/reify/utils/Utils.scala +++ b/src/compiler/scala/reflect/reify/utils/Utils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala b/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala index 606ea902a1e8..2b1819c678d5 100644 --- a/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala +++ b/src/compiler/scala/tools/nsc/ClassPathMemoryConsumptionTester.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -42,7 +42,7 @@ object ClassPathMemoryConsumptionTester { private def doTest(args: Array[String]) = { val settings = loadSettings(args.toList) - val mains = (1 to settings.requiredInstances.value) map (_ => new MainRetainsGlobal) + val mains = (1 to settings.requiredInstances.value).map(_ => new MainRetainsGlobal) // we need original settings without additional params to be able to use them later val baseArgs = argsWithoutRequiredInstances(args) @@ -50,7 +50,7 @@ object ClassPathMemoryConsumptionTester { println(s"Loading classpath ${settings.requiredInstances.value} times") val startTime = System.currentTimeMillis() - mains map (_.process(baseArgs)) + mains.foreach(_.process(baseArgs)) val elapsed = System.currentTimeMillis() - startTime println(s"Operation finished - elapsed $elapsed ms") diff --git a/src/compiler/scala/tools/nsc/CloseableRegistry.scala b/src/compiler/scala/tools/nsc/CloseableRegistry.scala index 4e900641927b..ba5ddcf47564 100644 --- a/src/compiler/scala/tools/nsc/CloseableRegistry.scala +++ b/src/compiler/scala/tools/nsc/CloseableRegistry.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index fe971938438e..a4cb1e81ea5e 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -103,7 +103,7 @@ trait CompilationUnits { global: Global => /** Synthetic definitions generated by namer, eliminated by typer. */ object synthetics { - private val map = mutable.AnyRefMap[Symbol, Tree]() + private val map = mutable.HashMap[Symbol, Tree]() def update(sym: Symbol, tree: Tree): Unit = { debuglog(s"adding synthetic ($sym, $tree) to $self") map.update(sym, tree) @@ -123,7 +123,7 @@ trait CompilationUnits { global: Global => // namer calls typer.computeType(rhs) on DefDef / ValDef when tpt is empty. the result // is cached here and re-used in typedDefDef / typedValDef // Also used to cache imports type-checked by namer. - val transformed = new mutable.AnyRefMap[Tree, Tree] + val transformed = new mutable.HashMap[Tree, Tree] /** things to check at end of compilation unit */ val toCheck = ArrayDeque.empty[CompilationUnit.ToCheck] diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala index 9e2405ee6e66..c74f5efd9637 100644 --- a/src/compiler/scala/tools/nsc/CompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ConsoleWriter.scala b/src/compiler/scala/tools/nsc/ConsoleWriter.scala index e8c9a775d788..2b250c96e49f 100644 --- a/src/compiler/scala/tools/nsc/ConsoleWriter.scala +++ b/src/compiler/scala/tools/nsc/ConsoleWriter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/Driver.scala b/src/compiler/scala/tools/nsc/Driver.scala index 4d5a91dd5700..88cfc4576149 100644 --- a/src/compiler/scala/tools/nsc/Driver.scala +++ b/src/compiler/scala/tools/nsc/Driver.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -28,7 +28,7 @@ abstract class Driver { /** Forward errors to the (current) reporter. */ protected def scalacError(msg: String): Unit = { - reporter.error(FakePos("scalac"), msg + "\n scalac -help gives more information") + reporter.error(FakePos("scalac"), s"$msg\n scalac -help gives more information") } /** True to continue compilation. */ diff --git a/src/compiler/scala/tools/nsc/EvalLoop.scala b/src/compiler/scala/tools/nsc/EvalLoop.scala index 578a1ac5b2bb..33e8a716b26f 100644 --- a/src/compiler/scala/tools/nsc/EvalLoop.scala +++ b/src/compiler/scala/tools/nsc/EvalLoop.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala index a6af42fe5e7a..6afed6a77509 100644 --- a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala +++ b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala index 8590b37bad51..8e5753095217 100644 --- a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala +++ b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index d186ad5c33d4..e816ea58f1b1 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -18,7 +18,7 @@ import java.io.{Closeable, FileNotFoundException, IOException} import java.net.URL import java.nio.charset.{Charset, CharsetDecoder, IllegalCharsetNameException, StandardCharsets, UnsupportedCharsetException}, StandardCharsets.UTF_8 -import scala.annotation.{nowarn, tailrec} +import scala.annotation._ import scala.collection.{immutable, mutable} import scala.reflect.ClassTag import scala.reflect.internal.pickling.PickleBuffer @@ -82,14 +82,18 @@ class Global(var currentSettings: Settings, reporter0: Reporter) def findMemberFromRoot(fullName: Name): Symbol = rootMirror.findMemberFromRoot(fullName) override def openPackageModule(pkgClass: Symbol, force: Boolean): Unit = { - if (force || isPast(currentRun.namerPhase)) super.openPackageModule(pkgClass, force = true) + // presentation compiler uses `compileLate` whioch doesn't advance `globalPhase`, so `isPast` is false. + // therefore checking `isAtPhaseAfter` as well. + val forceNow = force || isPast(currentRun.namerPhase) || isRunGlobalInitialized && isAtPhaseAfter(currentRun.namerPhase) + if (forceNow) super.openPackageModule(pkgClass, force = true) else analyzer.packageObjects.deferredOpen.addOne(pkgClass) } - // alternate constructors ------------------------------------------ override def settings = currentSettings + override def isSymbolLockTracingEnabled = settings.cyclic.value + private[this] var currentReporter: FilteringReporter = null locally { reporter = reporter0 } @@ -146,7 +150,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) def optimizerClassPath(base: ClassPath): ClassPath = base match { case AggregateClassPath(entries) if entries.head.isInstanceOf[CtSymClassPath] => - JrtClassPath(release = None, unsafe = None, closeableRegistry) match { + JrtClassPath(release = None, settings.systemPathValue, unsafe = None, closeableRegistry) match { case jrt :: Nil => AggregateClassPath(entries.drop(1).prepended(jrt)) case _ => base } @@ -374,7 +378,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) def ccon = Class.forName(name).getConstructor(classOf[CharsetDecoder], classOf[InternalReporter]) try Some(ccon.newInstance(charset.newDecoder(), reporter).asInstanceOf[SourceReader]) - catch { case ex: Throwable => + catch { case _: Throwable => globalError("exception while trying to instantiate source reader '" + name + "'") None } @@ -579,7 +583,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) // phaseName = "specialize" object specializeTypes extends { val global: Global.this.type = Global.this - val runsAfter = List("") + val runsAfter = Nil val runsRightAfter = Some("tailcalls") } with SpecializeTypes @@ -593,14 +597,14 @@ class Global(var currentSettings: Settings, reporter0: Reporter) // phaseName = "erasure" override object erasure extends { val global: Global.this.type = Global.this - val runsAfter = List("explicitouter") + val runsAfter = Nil val runsRightAfter = Some("explicitouter") } with Erasure // phaseName = "posterasure" override object postErasure extends { val global: Global.this.type = Global.this - val runsAfter = List("erasure") + val runsAfter = Nil val runsRightAfter = Some("erasure") } with PostErasure @@ -665,7 +669,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) val global: Global.this.type = Global.this } with SubComponent { val phaseName = "terminal" - val runsAfter = List("jvm") + val runsAfter = Nil val runsRightAfter = None override val terminal = true @@ -694,10 +698,10 @@ class Global(var currentSettings: Settings, reporter0: Reporter) /** Add the internal compiler phases to the phases set. * This implementation creates a description map at the same time. */ - protected def computeInternalPhases(): Unit = { + protected def computeInternalPhases(): Unit = // Note: this fits -Xshow-phases into 80 column width, which is // desirable to preserve. - val phs = List( + List( syntaxAnalyzer -> "parse source into ASTs, perform simple desugaring", analyzer.namerFactory -> "resolve names, attach symbols to named trees", analyzer.packageObjects -> "load package objects", @@ -722,9 +726,8 @@ class Global(var currentSettings: Settings, reporter0: Reporter) cleanup -> "platform-specific cleanups, generate reflective calls", terminal -> "the last phase during a compilation run" ) + .foreach((addToPhasesSet _).tupled) - phs foreach (addToPhasesSet _).tupled - } // This is slightly inelegant but it avoids adding a new member to SubComponent, // and attractive -Vphases output is unlikely if the descs span 20 files anyway. private val otherPhaseDescriptions = Map( @@ -732,11 +735,9 @@ class Global(var currentSettings: Settings, reporter0: Reporter) "jvm" -> "generate JVM bytecode" ) withDefaultValue "" - protected def computePlatformPhases() = platform.platformPhases foreach { sub => - addToPhasesSet(sub, otherPhaseDescriptions(sub.phaseName)) - } + protected def computePlatformPhases() = platform.platformPhases.foreach(p => addToPhasesSet(p, otherPhaseDescriptions(p.phaseName))) - // sequences the phase assembly + // compute the order in which phases will run; subclasses may override the template methods used here. protected def computePhaseDescriptors: List[SubComponent] = { /* Allow phases to opt out of the phase assembly. */ def cullPhases(phases: List[SubComponent]) = { @@ -767,7 +768,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) /** The names of the phases. */ lazy val phaseNames = { new Run // force some initialization - phaseDescriptors map (_.phaseName) + phaseDescriptors.map(_.phaseName) } /** A description of the phases that will run in this configuration, or all if -Vdebug. */ @@ -1038,25 +1039,16 @@ class Global(var currentSettings: Settings, reporter0: Reporter) private[this] var curFreshNameCreator: FreshNameCreator = null private[scala] def currentFreshNameCreator_=(fresh: FreshNameCreator): Unit = curFreshNameCreator = fresh - def isGlobalInitialized = ( - definitions.isDefinitionsInitialized - && rootMirror.isMirrorInitialized - ) + def isGlobalInitialized = definitions.isDefinitionsInitialized && rootMirror.isMirrorInitialized + private def isRunGlobalInitialized = (curRun ne null) && isGlobalInitialized + override def isPastTyper = isPast(currentRun.typerPhase) def isBeforeErasure = isBefore(currentRun.erasurePhase) - def isPast(phase: Phase) = ( - (curRun ne null) - && isGlobalInitialized // defense against init order issues - && (globalPhase.id > phase.id) - ) - def isBefore(phase: Phase) = ( - (curRun ne null) - && isGlobalInitialized // defense against init order issues - && (phase match { - case NoPhase => true // if phase is NoPhase then that phase ain't comin', so we're "before it" - case _ => globalPhase.id < phase.id - }) - ) + def isPast(phase: Phase) = isRunGlobalInitialized && (globalPhase.id > phase.id) + def isBefore(phase: Phase) = isRunGlobalInitialized && (phase match { + case NoPhase => true // if phase is NoPhase then that phase ain't comin', so we're "before it" + case _ => globalPhase.id < phase.id + }) // TODO - trim these to the absolute minimum. @inline final def exitingErasure[T](op: => T): T = exitingPhase(currentRun.erasurePhase)(op) @@ -1180,12 +1172,26 @@ class Global(var currentSettings: Settings, reporter0: Reporter) val profiler: Profiler = Profiler(settings) keepPhaseStack = settings.log.isSetByUser - // We hit these checks regularly. They shouldn't change inside the same run, so cache the comparisons here. - @nowarn("cat=deprecation") - val isScala3: Boolean = settings.isScala3.value // reporting.isScala3 - @nowarn("cat=deprecation") - val isScala3Cross: Boolean = settings.isScala3Cross.value // reporting.isScala3Cross - val isScala3ImplicitResolution: Boolean = settings.Yscala3ImplicitResolution.value + val isScala3: Boolean = settings.isScala3: @nowarn + + object sourceFeatures { + private val s = settings + private val o = s.sourceFeatures + import s.XsourceFeatures.contains + def caseApplyCopyAccess = isScala3 && contains(o.caseApplyCopyAccess) + def caseCompanionFunction = isScala3 && contains(o.caseCompanionFunction) + def caseCopyByName = isScala3 && contains(o.caseCopyByName) + def inferOverride = isScala3 && contains(o.inferOverride) + def noInferStructural = isScala3 && contains(o.noInferStructural) + def any2StringAdd = isScala3 && contains(o.any2StringAdd) + def unicodeEscapesRaw = isScala3 && contains(o.unicodeEscapesRaw) + def stringContextScope = isScala3 && contains(o.stringContextScope) + def leadingInfix = isScala3 && contains(o.leadingInfix) + def packagePrefixImplicits = isScala3 && contains(o.packagePrefixImplicits) + def implicitResolution = isScala3 && contains(o.implicitResolution) || settings.Yscala3ImplicitResolution.value + def doubleDefinitions = isScala3 && contains(o.doubleDefinitions) + def etaExpandAlways = isScala3 && contains(o.etaExpandAlways) + } // used in sbt def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings @@ -1215,10 +1221,10 @@ class Global(var currentSettings: Settings, reporter0: Reporter) val compiledFiles = new mutable.HashSet[String] /** A map from compiled top-level symbols to their source files */ - val symSource = new mutable.AnyRefMap[Symbol, AbstractFile] + val symSource = new mutable.HashMap[Symbol, AbstractFile] /** A map from compiled top-level symbols to their picklers */ - val symData = new mutable.AnyRefMap[Symbol, PickleBuffer] + val symData = new mutable.HashMap[Symbol, PickleBuffer] private var phasec: Int = 0 // phases completed private var unitc: Int = 0 // units completed this phase @@ -1271,7 +1277,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) } else skippable || !pd.enabled } - val phs = phaseDescriptors takeWhile unstoppable filterNot skippable + val phs = phaseDescriptors.takeWhile(unstoppable).filterNot(skippable) // Ensure there is a terminal phase at the end, since -Ystop may have limited the phases. if (phs.isEmpty || !phs.last.terminal) { val t = if (phaseDescriptors.last.terminal) phaseDescriptors.last else terminal @@ -1279,10 +1285,13 @@ class Global(var currentSettings: Settings, reporter0: Reporter) } else phs } // Create phases and link them together. We supply the previous, and the ctor sets prev.next. - val last = components.foldLeft(NoPhase: Phase)((prev, c) => c newPhase prev) - val phaseList = Iterator.iterate(last)(_.prev).takeWhile(_ != NoPhase).toList.reverse - val maxId = phaseList.map(_.id).max - nextFrom = Array.tabulate(maxId)(i => infoTransformers.nextFrom(i)) + val phaseList = { + val last = components.foldLeft(NoPhase: Phase)((prev, c) => c.newPhase(prev)) + Iterator.iterate(last)(_.prev).takeWhile(_ != NoPhase).toList.reverse + } + nextFrom = Array.tabulate(phaseList.maxBy(_.id).id)(infoTransformers.nextFrom(_)) + //println(s"nextFrom: ${scala.runtime.ScalaRunTime.stringOf(nextFrom.map(_.pid))}") + //println(s"phaseList: ${scala.runtime.ScalaRunTime.stringOf(phaseList.map(_.name))}") val first = phaseList.head val ss = settings @@ -1313,7 +1322,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) checkPhaseSettings(including = false, exclusions.map(_.value): _*) // Report the overhead of statistics measurements per every run - if (settings.areStatisticsEnabled) + if (settings.areStatisticsEnabled && settings.Ystatistics.value.nonEmpty) statistics.reportStatisticsOverhead(reporter) phase = first //parserPhase @@ -1457,6 +1466,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) private def showMembers() = { // Allows for syntax like scalac -Xshow-class Random@erasure,typer + @nowarn def splitClassAndPhase(str: String, term: Boolean): Name = { def mkName(s: String) = if (term) newTermName(s) else newTypeName(s) (str indexOf '@') match { @@ -1573,7 +1583,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) if (settings.browse.containsPhase(globalPhase)) treeBrowser.browse(phase.name, units) - if ((settings.Yvalidatepos containsPhase globalPhase) && !reporter.hasErrors) + if (!reporter.hasErrors && settings.Yvalidatepos.containsPhase(globalPhase)) currentRun.units.foreach(unit => validatePositions(unit.body)) // move the pointer @@ -1615,7 +1625,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) } symSource.keys foreach (x => resetPackageClass(x.owner)) - if (timePhases) { + if (timePhases && settings.Ystatistics.value.nonEmpty) { statistics.stopTimer(totalCompileTime, startTotal) informTime("total", totalCompileTime.nanos) inform("*** Cumulative timers for phases") @@ -1638,7 +1648,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) compileSources(sources) } catch { - case ex: InterruptedException => reporter.cancelled = true + case _: InterruptedException => reporter.cancelled = true case ex: IOException => globalError(ex.getMessage()) } } @@ -1659,7 +1669,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter) compileSources(sources) } catch { - case ex: InterruptedException => reporter.cancelled = true + case _: InterruptedException => reporter.cancelled = true case ex: IOException => globalError(ex.getMessage()) } } diff --git a/src/compiler/scala/tools/nsc/GlobalSymbolLoaders.scala b/src/compiler/scala/tools/nsc/GlobalSymbolLoaders.scala index ad1cee5d8ac8..6d507ea6e9d2 100644 --- a/src/compiler/scala/tools/nsc/GlobalSymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/GlobalSymbolLoaders.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index 82831dbe955b..8a51321016e0 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/MainBench.scala b/src/compiler/scala/tools/nsc/MainBench.scala index 84b3b6e603e7..d82a29d3cca8 100644 --- a/src/compiler/scala/tools/nsc/MainBench.scala +++ b/src/compiler/scala/tools/nsc/MainBench.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/MainTokenMetric.scala b/src/compiler/scala/tools/nsc/MainTokenMetric.scala index ff8fcfa5c24f..5a9317c7fc22 100644 --- a/src/compiler/scala/tools/nsc/MainTokenMetric.scala +++ b/src/compiler/scala/tools/nsc/MainTokenMetric.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala b/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala index d662bb971dea..11ef67fe93af 100644 --- a/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala +++ b/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ObjectRunner.scala b/src/compiler/scala/tools/nsc/ObjectRunner.scala index 82b50330b1a0..0e09f1908e1a 100644 --- a/src/compiler/scala/tools/nsc/ObjectRunner.scala +++ b/src/compiler/scala/tools/nsc/ObjectRunner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/Parsing.scala b/src/compiler/scala/tools/nsc/Parsing.scala index b78f8feab1f6..2820a106dfaf 100644 --- a/src/compiler/scala/tools/nsc/Parsing.scala +++ b/src/compiler/scala/tools/nsc/Parsing.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala index 42df319f3f13..fa7420ce580f 100644 --- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala +++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,262 +12,278 @@ package scala.tools.nsc -import scala.collection.mutable -import scala.tools.nsc.Reporting.WarningCategory +import java.util.concurrent.atomic.AtomicInteger +import scala.collection.mutable, mutable.ArrayDeque, mutable.ListBuffer +import scala.reflect.io.{File, Path} +import scala.util.chaining._ -/** Converts an unordered morass of components into an order that - * satisfies their mutual constraints. - * @see SIP 00002. You have read SIP 00002? +/** Sorts the global phasesSet according to SubComponent constraints. */ trait PhaseAssembly { - self: Global => + this: Global => - /** - * Aux data structure for solving the constraint system - * The dependency graph container with helper methods for node and edge creation + /** Called by Global#computePhaseDescriptors to compute phase order. + * + * The phases to assemble are provided by `phasesSet`, which must contain + * an `initial` phase. If no phase is `terminal`, then `global.terminal` is added. */ - private[nsc] class DependencyGraph { + def computePhaseAssembly(): List[SubComponent] = { + require(phasesSet.exists(phase => phase.initial || phase.phaseName == DependencyGraph.Parser), "Missing initial phase") + if (!phasesSet.exists(phase => phase.terminal || phase.phaseName == DependencyGraph.Terminal)) { + phasesSet.add(terminal) + reporter.warning(NoPosition, "Added default terminal phase") + } + val warn = !settings.isScaladoc || settings.isDebug || settings.showPhases.value + val graph = DependencyGraph(phasesSet, warn) + for (n <- settings.genPhaseGraph.valueSetByUser; d <- settings.outputDirs.getSingleOutput if !d.isVirtual) + DependencyGraph.graphToDotFile(graph, Path(d.file) / File(s"$n.dot")) + graph.compilerPhaseList().tap(_ => graph.warnings.foreach(msg => reporter.warning(NoPosition, msg))) + } +} - /** Simple edge with to and from refs */ - case class Edge(var frm: Node, var to: Node, var hard: Boolean) +/** A graph with the given number of vertices. + * + * Each vertex is labeled with its phase name. + */ +class DependencyGraph(order: Int, start: String, val components: Map[String, SubComponent]) { + import DependencyGraph.{FollowsNow, Weight} - /** - * Simple node with name and object ref for the phase object, - * also sets of incoming and outgoing dependencies. - */ - case class Node(phasename: String) { - var phaseobj = Option.empty[List[SubComponent]] - var before = new mutable.HashSet[Edge]() - val after = new mutable.HashSet[Edge]() - var visited = false - var level = 0 + //private final val debugging = false - def allPhaseNames: String = phaseobj match { - case None => phasename - case Some(lst) => lst.map(_.phaseName).mkString(",") - } - } + private var messages: List[String] = Nil + def warning(message: String): Unit = messages ::= message + def warnings: List[String] = messages.reverse.tap(_ => messages = Nil) - val nodes = new mutable.HashMap[String, Node]() - val edges = new mutable.HashSet[Edge]() + /** For ith vertex, its outgoing edges. */ + private val adjacency: Array[List[Edge]] = Array.fill(order)(Nil) - /** Given the name of a phase object, get the node for that name. - * If the node object does not exist, then create it. - */ - def getNodeByPhase(name: String): Node = nodes.getOrElseUpdate(name, Node(name)) - def getNodeByPhase(phs: SubComponent): Node = { - val node: Node = getNodeByPhase(phs.phaseName) - if (node.phaseobj.isEmpty) - node.phaseobj = Some(List(phs)) - node - } + /** Directed edge. */ + private case class Edge(from: Int, to: Int, weight: Weight) - def softConnectNodes(frm: Node, to: Node) = connectNodes(Edge(frm, to, hard = false)) - def hardConnectNodes(frm: Node, to: Node) = connectNodes(Edge(frm, to, hard = true)) + // phase names and their vertex index + private val nodeCount = new AtomicInteger + private val nodes = mutable.HashMap.empty[String, Int] // name to index + private val names = Array.ofDim[String](order) // index to name - // Connect the frm and to nodes in the edge and add it to the set of edges. - private def connectNodes(e: Edge): Unit = { - edges += e - e.frm.after += e - e.to.before += e + /** Add the edge between named phases, where `to` follows `from`. + */ + private def addEdge(from: String, to: String, weight: Weight): Unit = { + def getNode(name: String): Int = { + def installName(name: String, n: Int): Unit = + if (n >= names.length) throw new FatalError(names.mkString(s"Extra name $name; names [",",","]")) + else names(n) = name + nodes.getOrElseUpdate(name, nodeCount.getAndIncrement().tap(installName(name, _))) } + val v = getNode(from) + val w = getNode(to) + adjacency(v).find(_.to == w) match { + case None => + adjacency(v) ::= Edge(from = v, to = w, weight) + case Some(_) if weight == FollowsNow => // retain runsRightAfter if there is a competing constraint + adjacency(v) = Edge(from = v, to = w, weight) :: adjacency(v).filterNot(_.to == w) + case _ => + } + } - /* Given the entire graph, collect the phase objects at each level, where the phase - * names are sorted alphabetical at each level, into the compiler phase list - */ - def compilerPhaseList(): List[SubComponent] = - nodes.values.toList.filter(_.level > 0).sortBy(x => (x.level, x.phasename)).flatMap(_.phaseobj).flatten - - // Test for graph cycles, assign levels to the nodes & collapse hard links into nodes. - def collapseHardLinksAndLevels(node: Node, lvl: Int): Unit = { - if (node.visited) { - dump("phase-cycle") - throw new FatalError(s"Cycle in phase dependencies detected at ${node.phasename}, created phase-cycle.dot") + /** Find unreachable vertices. + * Input must be acyclic and a vertex can have only one outgoing FollowsNow edge. + */ + private def validate(warn: Boolean): Set[String] = if (order == 1) Set.empty else { + def checkFollowsNow(v: Int): Unit = + adjacency(v).foldLeft(-1) { (w, e) => + if (e.weight != FollowsNow) w + else if (w == -1) e.to + else throw new FatalError(s"Phases ${names(w)} and ${names(e.to)} both immediately follow ${names(v)}") } - - if (node.level < lvl) - node.level = lvl // level up - else if (node.level != 0) { - node.visited = false - return // no need to revisit + val seen = Array.ofDim[Boolean](order) + val onPath = Array.ofDim[Boolean](order) + val stack = mutable.Stack.empty[(Int, List[Edge])] // a vertex and list of edges remaining to follow + def walk(): Unit = { + nodes(start).tap { start => + stack.push(start -> adjacency(start)) } - - var hardlinks = node.before.filter(_.hard) - while (hardlinks.nonEmpty) { - for (hl <- hardlinks) { - node.phaseobj = Some(node.phaseobj.get ++ hl.frm.phaseobj.get) - node.before = hl.frm.before - nodes -= hl.frm.phasename - edges -= hl - for (edge <- node.before) - edge.to = node + while (!stack.isEmpty) { + val (v, edges) = stack.pop() + if (!seen(v)) { + checkFollowsNow(v) + seen(v) = true + } + onPath(v) = true + edges match { + case Edge(_, to, _) :: edges => + if (onPath(to)) { + var path = v :: to :: Nil + while (path.head != to) + path ::= stack.pop()._1 + throw new FatalError(s"Phases form a cycle: ${path.map(names(_)).mkString(" -> ")}") + } + stack.push(v -> edges) + if (!seen(to)) + stack.push(to -> adjacency(to)) + case _ => onPath(v) = false } - hardlinks = node.before.filter(_.hard) } + } + walk() + names.iterator.zipWithIndex.collect { case (n, i) if !seen(i) => + if (warn) warning(s"Dropping phase ${names(i)}, it is not reachable from $start") + n + }.toSet + } - node.visited = true + def compilerPhaseList(): List[SubComponent] = if (order == 1) List(components(start)) else { + // distance from source to each vertex + val distance = Array.fill[Int](order)(Int.MinValue) - for (edge <- node.before) { - collapseHardLinksAndLevels(edge.frm, lvl + 1) - } + // incoming edge terminating in each vertex for the current path + val edgeTo = Array.ofDim[Edge](order) - node.visited = false - } + // whether vertex is on the queue + val enqueued = Array.ofDim[Boolean](order) + + // vertices to process + val queue = mutable.Queue.empty[Int] + + def enqueue(v: Int): Unit = if (!enqueued(v)) queue.enqueue(v).tap(_ => enqueued(v) = true) + + def dequeue(): Int = queue.dequeue().tap(v => enqueued(v) = false) - /* Find all edges in the given graph that are hard links. - * For each hard link we need to check that it's the only dependency. - * If not, then we will promote the other dependencies down. + //def namedEdge(e: Edge): String = if (e == null) "[no edge]" else s"${names(e.from)} ${if (e.weight == FollowsNow) "=" else "-"}> ${names(e.to)}" + + /** Remove a vertex from the queue and check outgoing edges: + * if an edge improves (increases) the distance at the terminal, + * record that as the new incoming edge and enqueue that vertex + * to propagate updates. */ - def validateAndEnforceHardlinks(): Unit = { - for (hl <- edges if hl.hard) { - if (hl.frm.after.sizeIs > 1) { - dump("phase-order") - throw new FatalError(s"Phase ${hl.frm.phasename} can't follow ${hl.to.phasename}, created phase-order.dot") - } + def relax(): Unit = { + nodes(start).tap { start => + distance(start) = 0 + enqueue(start) } - - var rerun = true - while (rerun) { - rerun = false - for (hl <- edges if hl.hard) { - hl.to.before.filter(_.hard).toList match { - case Seq() => - throw new FatalError("There is no runs right after dependency, where there should be one! This is not supposed to happen!") - case asm @ (head :: _ :: _) => - dump("phase-order") - val following = asm.map(_.frm.phasename).sorted mkString "," - throw new FatalError(s"Multiple phases want to run right after ${head.to.phasename}; followers: $following; created phase-order.dot") - case asm => - val promote = hl.to.before.filter(e => !e.hard) - hl.to.before.clear() - asm.foreach(edge => hl.to.before += edge) - for (edge <- promote) { - rerun = true - val msg = s"promote the dependency of ${edge.frm.phasename}: ${edge.to.phasename} => ${hl.frm.phasename}" - informProgress(msg) - edge.to = hl.frm - hl.frm.before += edge - } + while (!queue.isEmpty) { + val v = dequeue() + //if (debugging) println(s"deq ${names(v)}") + for (e <- adjacency(v)) { + val w = e.to + /* cannot happen as `runsRightAfter: Option[String]` is the only way to introduce a `FollowsNow` + val e2 = edgeTo(w) + if (e.weight == FollowsNow && e2 != null && e2.weight == FollowsNow && e.from != e2.from) + throw new FatalError(s"${names(w)} cannot follow right after both ${names(e.from)} and ${names(e2.from)}") + */ + if (distance(w) < distance(v) + e.weight) { + distance(w) = distance(v) + e.weight + edgeTo(w) = e + enqueue(w) + //if (debugging) println(s"update ${namedEdge(e)} dist = ${distance(w)}, enq ${names(w)}") } } } + //if (debugging) edgeTo.foreach(e => println(namedEdge(e))) } - - /** Remove all nodes in the given graph, that have no phase object. - * Make sure to clean up all edges when removing the node object. - * `Inform` with warnings, if an external phase has a dependency on something that is dropped. + /** Put the vertices in a linear order. + * + * `Follows` edges increase the level, `FollowsNow` don't. + * Partition by "level" or distance from start. + * Partition the level into "anchors" that follow a node in the previous level, and "followers" (nodes + * with a `FollowsNow` edge). + * Starting at the "ends", build the chains of `FollowsNow` nodes within the level. Each chain leads to an anchor. + * The anchors are sorted by name, then the chains are flattened. */ - def removeDanglingNodes(): Unit = { - for (node <- nodes.values if node.phaseobj.isEmpty) { - val msg = s"dropping dependency on node with no phase object: ${node.phasename}" - informProgress(msg) - nodes -= node.phasename - - for (edge <- node.before) { - edges -= edge - edge.frm.after -= edge - if (edge.frm.phaseobj exists (lsc => !lsc.head.internal)) - runReporting.warning(NoPosition, msg, WarningCategory.Other, site = "") + def traverse(): List[SubComponent] = { + def componentOf(i: Int) = components(names(i)) + def sortComponents(c: SubComponent, d: SubComponent): Boolean = + // sort by name only, like the old implementation (pre scala/scala#10687) + /*c.internal && !d.internal ||*/ c.phaseName.compareTo(d.phaseName) < 0 + def sortVertex(i: Int, j: Int): Boolean = sortComponents(componentOf(i), componentOf(j)) + + distance.zipWithIndex.groupBy(_._1).toList.sortBy(_._1) + .flatMap { case (_, dis) => + val vs = dis.map { case (_, i) => i } + val (anchors, followers) = vs.partition(v => edgeTo(v) == null || edgeTo(v).weight != FollowsNow) + //if (debugging) println(s"d=$d, anchors=${anchors.toList.map(n => names(n))}, followers=${followers.toList.map(n => names(n))}") + if (followers.isEmpty) + anchors.toList.map(componentOf).sortWith(sortComponents) + else { + val froms = followers.map(v => edgeTo(v).from).toSet + val ends = followers.iterator.filterNot(froms).toList + val chains: Array[ArrayDeque[Int]] = anchors.map(ArrayDeque(_)) + def drill(v: Int, path: List[Int]): Unit = + edgeTo(v) match { + case e if e != null && e.weight == FollowsNow => drill(e.from, v :: path) + case _ => chains.find(_.apply(0) == v).foreach(deque => path.foreach(deque.append)) + } + ends.foreach(drill(_, Nil)) + chains.sortWith((p, q) => sortVertex(p(0), q(0))).toList.flatten.map(componentOf) } } } - - def dump(title: String) = graphToDotFile(this, s"$title.dot") + relax() + traverse() } - - - /** Called by Global#computePhaseDescriptors to compute phase order. */ - def computePhaseAssembly(): List[SubComponent] = { - - // Add all phases in the set to the graph - val graph = phasesSetToDepGraph(phasesSet) - - val dot = settings.genPhaseGraph.valueSetByUser - - // Output the phase dependency graph at this stage - def dump(stage: Int) = dot foreach (n => graphToDotFile(graph, s"$n-$stage.dot")) - - dump(1) - - // Remove nodes without phaseobj - graph.removeDanglingNodes() - - dump(2) - - // Validate and Enforce hardlinks / runsRightAfter and promote nodes down the tree - graph.validateAndEnforceHardlinks() - - dump(3) - - // test for cycles, assign levels and collapse hard links into nodes - graph.collapseHardLinksAndLevels(graph.getNodeByPhase("parser"), 1) - - dump(4) - - // assemble the compiler - graph.compilerPhaseList() - } - - /** Given the phases set, will build a dependency graph from the phases set - * Using the aux. method of the DependencyGraph to create nodes and edges. +} +object DependencyGraph { + + type Weight = Int + final val FollowsNow = 0 + final val Follows = 1 + + final val Parser = "parser" + final val Terminal = "terminal" + + /** Create a DependencyGraph from the given phases. The graph must be acyclic. + * + * A component must be declared as "initial". + * If no phase is "initial" but a phase is named "parser", it is taken as initial. + * If no phase is "terminal" but a phase is named "terminal", it is taken as terminal. + * Warnings are issued for invalid constraints (runsAfter / runsRightAfter / runsBefore) if `warn` is true. + * Components without a valid "runsAfter" or "runsRightAfter" are dropped with an "unreachable" warning. */ - private[nsc] def phasesSetToDepGraph(phasesSet: Iterable[SubComponent]): DependencyGraph = { - val graph = new DependencyGraph() - - for (phs <- phasesSet) { - val fromnode = graph.getNodeByPhase(phs) - - phs.runsRightAfter match { - case None => - for (phsname <- phs.runsAfter) { - if (phsname != "terminal") { - val tonode = graph.getNodeByPhase(phsname) - graph.softConnectNodes(fromnode, tonode) - } else { - globalError(s"[phase assembly, after dependency on terminal phase not allowed: ${fromnode.phasename} => $phsname]") - } - } - for (phsname <- phs.runsBefore) { - if (phsname != "parser") { - val tonode = graph.getNodeByPhase(phsname) - graph.softConnectNodes(tonode, fromnode) - } else { - globalError(s"[phase assembly, before dependency on parser phase not allowed: $phsname => ${fromnode.phasename}]") - } - } - case Some(phsname) => - if (phsname != "terminal") { - val tonode = graph.getNodeByPhase(phsname) - graph.hardConnectNodes(fromnode, tonode) - } else { - globalError(s"[phase assembly, right after dependency on terminal phase not allowed: ${fromnode.phasename} => $phsname]") - } + def apply(phases: Iterable[SubComponent], warn: Boolean = true): DependencyGraph = { + val start = phases.find(_.initial) + .orElse(phases.find(_.phaseName == Parser)) + .getOrElse(throw new AssertionError("Missing initial component")) + val end = phases.find(_.terminal) + .orElse(phases.find(_.phaseName == Terminal)) + .getOrElse(throw new AssertionError("Missing terminal component")) + val graph = new DependencyGraph(phases.size, start.phaseName, phases.map(p => p.phaseName -> p).toMap) + def phaseTypo(name: String) = + if (graph.components.contains(name)) "" + else graph.components.keysIterator.filter(util.EditDistance.levenshtein(name, _) < 3).toList match { + case Nil => "" + case close => s" - did you mean ${util.StringUtil.oxford(close, "or")}?" } + for (p <- phases) { + require(p.phaseName.nonEmpty, "Phase name must be non-empty.") + def checkConstraint(name: String, constraint: String): Boolean = + graph.components.contains(name).tap(ok => if (!ok && warn) graph.warning(s"No phase `$name` for ${p.phaseName}.$constraint${phaseTypo(name)}")) + for (after <- p.runsRightAfter if after.nonEmpty && checkConstraint(after, "runsRightAfter")) + graph.addEdge(after, p.phaseName, FollowsNow) + for (after <- p.runsAfter if after.nonEmpty && !p.runsRightAfter.contains(after) && checkConstraint(after, "runsAfter")) + graph.addEdge(after, p.phaseName, Follows) + for (before <- p.runsBefore if before.nonEmpty && checkConstraint(before, "runsBefore")) + graph.addEdge(p.phaseName, before, Follows) + // Add "runsBefore terminal" to phases without (or with invalid) runsBefore + if (p != end || p == end && p == start) + if (!p.runsBefore.exists(graph.components.contains)) + graph.addEdge(p.phaseName, end.phaseName, Follows) } - - graph + val unreachable = graph.validate(warn) + if (unreachable.isEmpty) graph + else apply(phases.filterNot(p => unreachable(p.phaseName)), warn).tap(res => graph.warnings.foreach(res.warning)) } - /* This is a helper method, that given a dependency graph will generate a graphviz dot - * file showing its structure. - * Plug-in supplied phases are marked as green nodes and hard links are marked as blue edges. + /** Emit a graphviz dot file for the graph. + * Plug-in supplied phases are marked as green nodes and hard links are marked as blue edges. */ - private def graphToDotFile(graph: DependencyGraph, filename: String): Unit = { - for (d <- settings.outputDirs.getSingleOutput if !d.isVirtual) { - val edges = graph.edges.toSeq - val extnodes = edges.map(_.frm).filter(!_.phaseobj.get.head.internal) - val fatnodes = edges.flatMap(e => List(e.frm, e.to)).filter(_.phaseobj.exists(_.sizeIs > 1)) - - def color(hex: String) = s""" [color="#$hex"]""" - def node(n: graph.Node) = s""""${n.allPhaseNames}(${n.level})"""" - - import scala.reflect.io._ - val f = Path(d.file) / File(filename) - f.printlnAll("digraph G {") - f.printlnAll(edges.map(e => s"${node(e.frm)}->${node(e.to)}" + color(if (e.hard) "0000ff" else "000000")): _*) - f.printlnAll(extnodes.distinct.map(n => node(n) + color("00ff00")): _*) - f.printlnAll(fatnodes.distinct.map(n => node(n) + color("0000ff")): _*) - f.printlnAll("}") - } + def graphToDotFile(graph: DependencyGraph, file: File): Unit = { + def color(hex: String) = s""" [color="#$hex"]""" + val sb = ListBuffer.empty[String] + sb.addOne("digraph G {") + for (edges <- graph.adjacency; e <- edges) + sb.addOne(s"${graph.names(e.from)} -> ${graph.names(e.to)}${if (e.weight == FollowsNow) color("0000ff") else ""}") + for (n <- graph.names) + sb.addOne(s"${n}${if (graph.components(n).internal) "" else color("00ff00")}") + sb.addOne("}") + file.printlnAll(sb.toList: _*) } } diff --git a/src/compiler/scala/tools/nsc/PickleExtractor.scala b/src/compiler/scala/tools/nsc/PickleExtractor.scala index 1be006ea221a..6d53127e849f 100644 --- a/src/compiler/scala/tools/nsc/PickleExtractor.scala +++ b/src/compiler/scala/tools/nsc/PickleExtractor.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/PipelineMain.scala b/src/compiler/scala/tools/nsc/PipelineMain.scala index 23176c19ec42..2cad5a2eb15e 100644 --- a/src/compiler/scala/tools/nsc/PipelineMain.scala +++ b/src/compiler/scala/tools/nsc/PipelineMain.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -67,7 +67,7 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe reporter.echo(NoPosition, msg) } private def reporterError(pos: Position, msg: String): Unit = synchronized { - reporter.echo(msg) + reporter.error(pos, msg) } private object handler extends UncaughtExceptionHandler { diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala index 76ae1cb52a8a..b286c4764a57 100644 --- a/src/compiler/scala/tools/nsc/Properties.scala +++ b/src/compiler/scala/tools/nsc/Properties.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala index ab76e08cc00b..0af9f21a4608 100644 --- a/src/compiler/scala/tools/nsc/Reporting.scala +++ b/src/compiler/scala/tools/nsc/Reporting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -25,11 +25,10 @@ import scala.reflect.internal.util.StringOps.countElementsAsString import scala.reflect.internal.util.{CodeAction, NoSourceFile, Position, ReplBatchSourceFile, SourceFile, TextEdit} import scala.tools.nsc.Reporting.Version.{NonParseableVersion, ParseableVersion} import scala.tools.nsc.Reporting._ -import scala.tools.nsc.settings.NoScalaVersion import scala.util.matching.Regex /** Provides delegates to the reporter doing the actual work. - * PerRunReporting implements per-Run stateful info tracking and reporting + * PerRunReporting implements per-Run stateful info tracking and reporting */ trait Reporting extends internal.Reporting { self: ast.Positions with CompilationUnits with internal.Symbols => def settings: Settings @@ -43,11 +42,6 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio val rootDirPrefix: String = if (settings.rootdir.value.isEmpty) "" else Regex.quote(new java.io.File(settings.rootdir.value).getCanonicalPath.replace("\\", "/")) - @nowarn("cat=deprecation") - val isScala3 = settings.isScala3.value - @nowarn("cat=deprecation") - val isScala3Cross: Boolean = settings.isScala3Cross.value - val isScala3Migration = settings.Xmigration.value != NoScalaVersion lazy val wconf = WConf.parse(settings.Wconf.value, rootDirPrefix) match { case Left(msgs) => val multiHelp = @@ -59,12 +53,29 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio globalError(s"Failed to parse `-Wconf` configuration: ${settings.Wconf.value}\n${msgs.mkString("\n")}$multiHelp") WConf(Nil) case Right(conf) => - if (isScala3 && !conf.filters.exists(_._1.exists { case MessageFilter.Category(WarningCategory.Scala3Migration) => true case _ => false })) { - val migrationAction = if (isScala3Migration) Action.Warning else Action.Error - val migrationCategory = MessageFilter.Category(WarningCategory.Scala3Migration) :: Nil - WConf(conf.filters :+ (migrationCategory, migrationAction)) - } - else conf + // default is "cat=deprecation:ws,cat=feature:ws,cat=optimizer:ws" + // under -deprecation, "cat=deprecation:w", but under -deprecation:false or -nowarn, "cat=deprecation:s" + // similarly for -feature, -Wopt (?) + val needsDefaultAdjustment = settings.deprecation.isSetByUser + val adjusted = + if (needsDefaultAdjustment || settings.nowarn.value) { + val (user, defaults) = conf.filters.splitAt(conf.filters.length - settings.WconfDefault.length) + val Deprecation = MessageFilter.Category(WarningCategory.Deprecation) + val action = if (settings.deprecation.value) Action.Warning else Action.Silent + val fixed = defaults.map { + case (cat @ Deprecation :: Nil, Action.WarningSummary) => cat -> action + case other => other + } + conf.copy(filters = user ::: fixed) + } + else conf + // configure any:s for -nowarn or cat=scala3-migration:e for -Xsource:3 + def Migration = MessageFilter.Category(WarningCategory.Scala3Migration) + if (settings.nowarn.value) + adjusted.copy(filters = adjusted.filters :+ (MessageFilter.Any :: Nil, Action.Silent)) + else if (settings.isScala3: @nowarn) + adjusted.copy(filters = adjusted.filters :+ (Migration :: Nil, Action.Error)) + else adjusted } private lazy val quickfixFilters = { @@ -135,10 +146,13 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio suspendedMessages.clear() } - private def isSuppressed(warning: Message): Boolean = + private def nowarnAction(warning: Message): Action = suppressions.getOrElse(repSrc(warning.pos.source), Nil).find(_.matches(warning)) match { - case Some(s) => s.markUsed(); true - case _ => false + case Some(s) => + s.markUsed() + if (s.verbose) Action.WarningVerbose else Action.Silent + case _ => + Action.Warning } def clearSuppressionsComplete(sourceFile: SourceFile): Unit = suppressionsComplete -= repSrc(sourceFile) @@ -153,7 +167,7 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio def runFinished(hasErrors: Boolean): Unit = { // report suspended messages (in case the run finished before typer) - suspendedMessages.valuesIterator.foreach(_.foreach(issueWarning)) + suspendedMessages.valuesIterator.foreach(_.foreach(issueWarning(_))) // report unused nowarns only if all all phases are done. scaladoc doesn't run all phases. if (!hasErrors && settings.warnUnusedNowarn && !settings.isScaladoc) @@ -185,8 +199,8 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio sm.getOrElseUpdate(category, mutable.LinkedHashMap.empty) } - private def issueWarning(warning: Message): Unit = { - val action = wconf.action(warning) + private def issueWarning(warning: Message, verbose: Boolean = false): Unit = { + val action = if (verbose) Action.WarningVerbose else wconf.action(warning) val quickfixed = { if (!skipRewriteAction(action) && registerTextEdit(warning)) s"[rewritten by -quickfix] ${warning.msg}" @@ -194,21 +208,21 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio else warning.msg } - def ifNonEmpty(kind: String, filter: String) = if (filter.nonEmpty) s", $kind=$filter" else "" - def filterHelp = - s"msg=, cat=${warning.category.name}" + - ifNonEmpty("site", warning.site) + - (warning match { - case Message.Deprecation(_, _, _, origin, version, _) => - ifNonEmpty("origin", origin) + ifNonEmpty("version", version.filterString) - case _ => "" - }) - def scala3migration(isError: Boolean) = - if (isError && isScala3 && warning.category == WarningCategory.Scala3Migration) - "\nScala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings." - else "" - def helpMsg(kind: String, isError: Boolean = false) = - s"$quickfixed${scala3migration(isError)}\nApplicable -Wconf / @nowarn filters for this $kind: $filterHelp" + def helpMsg(level: String, isError: Boolean = false) = { + def ifNonEmpty(kind: String, filter: String) = if (filter.nonEmpty) s", $kind=$filter" else "" + def maybeSite = ifNonEmpty("site", warning.site) + def maybeOrigin = warning match { + case Message.Deprecation(_, _, _, origin, version, _) => + ifNonEmpty("origin", origin) + ifNonEmpty("version", version.filterString) + case _ => "" + } + def filterHelp = s"msg=, cat=${warning.category.name}${maybeSite}${maybeOrigin}" + def scala3migration = + if (isError && warning.category == WarningCategory.Scala3Migration) + "\nScala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress." + else "" + s"$quickfixed$scala3migration\nApplicable -Wconf / @nowarn filters for this $level: $filterHelp" + } action match { case Action.Error => reporter.error(warning.pos, helpMsg("fatal warning", isError = true), warning.actions) @@ -229,9 +243,12 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio def issueIfNotSuppressed(warning: Message): Unit = if (shouldSuspend(warning)) suspendedMessages.getOrElseUpdate(repSrc(warning.pos.source), mutable.LinkedHashSet.empty) += warning - else { - if (!isSuppressed(warning)) + else nowarnAction(warning) match { + case Action.Warning => issueWarning(warning) + case Action.WarningVerbose => + issueWarning(warning, verbose = true) + case _ => } private def summarize(action: Action, category: WarningCategory): Unit = { @@ -299,11 +316,11 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio override def deprecationWarning(pos: Position, msg: String, since: String, site: String, origin: String, actions: List[CodeAction] = Nil): Unit = issueIfNotSuppressed(Message.Deprecation(pos, msg, site, origin, Version.fromString(since), actions)) - // multiple overloads cannot use default args + // multiple overloads cannot have default args def deprecationWarning(pos: Position, origin: Symbol, site: Symbol, msg: String, since: String, actions: List[CodeAction]): Unit = deprecationWarning(pos, msg, since, siteName(site), siteName(origin), actions) def deprecationWarning(pos: Position, origin: Symbol, site: Symbol, msg: String, since: String): Unit = - deprecationWarning(pos, msg, since, siteName(site), siteName(origin)) + deprecationWarning(pos, msg, since, siteName(site), siteName(origin), actions = Nil) def deprecationWarning(pos: Position, origin: Symbol, site: Symbol): Unit = { val version = origin.deprecationVersion.getOrElse("") @@ -354,15 +371,18 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio def warning(pos: Position, msg: String, category: WarningCategory, site: String, actions: List[CodeAction]): Unit = issueIfNotSuppressed(Message.Plain(pos, msg, category, site, actions)) def warning(pos: Position, msg: String, category: WarningCategory, site: String): Unit = - warning(pos, msg, category, site, Nil) + warning(pos, msg, category, site, actions = Nil) // Preferred over the overload above whenever a site symbol is available def warning(pos: Position, msg: String, category: WarningCategory, site: Symbol, actions: List[CodeAction] = Nil): Unit = warning(pos, msg, category, siteName(site), actions) // Provide an origin for the warning. + def warning(pos: Position, msg: String, category: WarningCategory, site: Symbol, origin: String, actions: List[CodeAction]): Unit = + issueIfNotSuppressed(Message.Origin(pos, msg, category, siteName(site), origin, actions)) + // convenience overload for source compatibility def warning(pos: Position, msg: String, category: WarningCategory, site: Symbol, origin: String): Unit = - issueIfNotSuppressed(Message.Origin(pos, msg, category, siteName(site), origin, actions = Nil)) + warning(pos, msg, category, site, origin, actions = Nil) def codeAction(title: String, pos: Position, newText: String, desc: String, expected: Option[(String, CompilationUnit)] = None) = CodeAction(title, pos, newText, desc, expected.forall(e => e._1 == e._2.source.sourceAt(pos))) @@ -393,23 +413,29 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio var seenMacroExpansionsFallingBack = false // i.e., summarize warnings - def summarizeErrors(): Unit = if (!reporter.hasErrors && !settings.nowarn.value) { - for (c <- summarizedWarnings.keys.toList.sortBy(_.name)) + def summarizeErrors(): Unit = if (!reporter.hasErrors) { + val warnOK = !settings.nowarn.value + if (warnOK) for (c <- summarizedWarnings.keys.toList.sortBy(_.name)) summarize(Action.WarningSummary, c) for (c <- summarizedInfos.keys.toList.sortBy(_.name)) summarize(Action.InfoSummary, c) - if (seenMacroExpansionsFallingBack) + if (warnOK && seenMacroExpansionsFallingBack) warning(NoPosition, "some macros could not be expanded and code fell back to overridden methods;"+ "\nrecompiling with generated classfiles on the classpath might help.", WarningCategory.Other, site = "") // todo: migrationWarnings - if (settings.fatalWarnings.value && reporter.hasWarnings) + if (warnOK && settings.fatalWarnings.value && reporter.hasWarnings) reporter.error(NoPosition, "No warnings can be incurred under -Werror.") } private object quickfix { + + private def nofix(msg: String): Unit = nofixAt(NoPosition, msg) + private def nofixAt(pos: Position, msg: String): Unit = + issueWarning(Message.Plain(pos, msg, WarningCategory.Other, site = "", actions = Nil)) + /** Source code at a position. Either a line with caret (offset), else the code at the range position. */ def codeOf(pos: Position, source: SourceFile): String = if (pos.start < pos.end) new String(source.content.slice(pos.start, pos.end)) @@ -420,7 +446,6 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio s"$code\n$caret" } - def checkNoOverlap(patches: List[TextEdit], source: SourceFile): Boolean = { var ok = true for (List(p1, p2) <- patches.sliding(2) if p1.position.end > p2.position.start) { @@ -433,7 +458,7 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio | |add `${p2.newText}` at |${codeOf(p2.position, source)}""".stripMargin.trim - issueWarning(Message.Plain(p1.position, msg, WarningCategory.Other, "", Nil)) + nofixAt(p1.position, msg) } ok } @@ -448,7 +473,7 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio Option(source.file.file).map(_.toPath) val r = p.filter(Files.exists(_)) if (r.isEmpty) - issueWarning(Message.Plain(NoPosition, s"Failed to apply quick fixes, file does not exist: ${source.file}", WarningCategory.Other, "", Nil)) + nofix(s"Failed to apply quick fixes, file does not exist: ${source.file}") r } @@ -456,42 +481,44 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio def insertEdits(sourceChars: Array[Char], edits: List[TextEdit], file: Path): Array[Byte] = { val patchedChars = new Array[Char](sourceChars.length + edits.iterator.map(_.delta).sum) - @tailrec def loop(edits: List[TextEdit], inIdx: Int, outIdx: Int): Unit = { + @tailrec + def loop(edits: List[TextEdit], inIdx: Int, outIdx: Int): Unit = { def copy(upTo: Int): Int = { val untouched = upTo - inIdx System.arraycopy(sourceChars, inIdx, patchedChars, outIdx, untouched) outIdx + untouched } edits match { - case e :: es => + case e :: edits => val outNew = copy(e.position.start) e.newText.copyToArray(patchedChars, outNew) - loop(es, e.position.end, outNew + e.newText.length) + loop(edits, e.position.end, outNew + e.newText.length) case _ => val outNew = copy(sourceChars.length) if (outNew != patchedChars.length) - issueWarning(Message.Plain(NoPosition, s"Unexpected content length when applying quick fixes; verify the changes to ${file.toFile.getAbsolutePath}", WarningCategory.Other, "", Nil)) + nofix(s"Unexpected content length when applying quick fixes; verify the changes to ${file.toFile.getAbsolutePath}") } } - loop(edits, 0, 0) new String(patchedChars).getBytes(encoding) } - def apply(edits: mutable.Set[TextEdit]): Unit = { - for ((source, edits) <- edits.groupBy(_.position.source).view.mapValues(_.toList.sortBy(_.position.start))) { - if (checkNoOverlap(edits, source)) { - underlyingFile(source) foreach { file => + def apply(edits: mutable.Set[TextEdit]): Unit = + for ((source, edits) <- edits.groupBy(_.position.source).view.mapValues(_.toList.sortBy(_.position.start))) + if (checkNoOverlap(edits, source)) + underlyingFile(source).foreach { file => val sourceChars = new String(Files.readAllBytes(file), encoding).toCharArray - try Files.write(file, insertEdits(sourceChars, edits, file)) + val lastPos = edits.last.position + val trimmed = // SourceFile.content can add a NL, so trim any edit position past EOF + if (lastPos.start >= sourceChars.length) edits.filterNot(_.position.start >= sourceChars.length) + else if (lastPos.end > sourceChars.length) edits.init :+ edits.last.copy(position = lastPos.withEnd(sourceChars.length)) + else edits + try Files.write(file, insertEdits(sourceChars, trimmed, file)) catch { case e: IOException => - issueWarning(Message.Plain(NoPosition, s"Failed to apply quick fixes to ${file.toFile.getAbsolutePath}\n${e.getMessage}", WarningCategory.Other, "", Nil)) + nofix(s"Failed to apply quick fixes to ${file.toFile.getAbsolutePath}\n${e.getMessage}") } } - } - } - } } } } @@ -522,6 +549,7 @@ object Reporting { def includes(o: WarningCategory): Boolean = this eq o def summaryCategory: WarningCategory = this lazy val name: String = WarningCategory.nameOf(this) + override def toString = name } object WarningCategory { @@ -578,6 +606,8 @@ object Reporting { WFlagExtraImplicit, WFlagNumericWiden, WFlagSelfImplicit, + WFlagUnnamedBooleanLiteral, + WFlagTostringInterpolated, WFlagValueDiscard = wflag() @@ -606,6 +636,7 @@ object Reporting { val LintAdaptedArgs, LintNullaryUnit, LintInaccessible, + LintStructuralType, LintInferAny, LintMissingInterpolator, LintDocDetached, @@ -626,12 +657,12 @@ object Reporting { LintBynameImplicit, LintRecurseWithDefault, LintUnitSpecialization, - LintMultiargInfix, LintPerformance, LintIntDivToFloat, LintUniversalMethods, - LintNumericMethods, - LintNamedBooleans + LintCloneable, + LintOverload, + LintNumericMethods = lint() sealed class Feature extends WarningCategory { @@ -722,7 +753,7 @@ object Reporting { } object MessageFilter { - object Any extends MessageFilter { + case object Any extends MessageFilter { def matches(message: Message): Boolean = true } @@ -768,7 +799,9 @@ object Reporting { } } - sealed trait Action + sealed trait Action { + override def toString = s"Action[${getClass.getSimpleName.stripSuffix("$")}]" + } object Action { object Error extends Action @@ -870,7 +903,7 @@ object Reporting { } } - case class Suppression(annotPos: Position, filters: List[MessageFilter], start: Int, end: Int, synthetic: Boolean = false) { + case class Suppression(annotPos: Position, filters: List[MessageFilter], start: Int, end: Int, synthetic: Boolean = false, verbose: Boolean = false) { private[this] var _used = false def used: Boolean = _used def markUsed(): Unit = { _used = true } diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala index 0f7c74d85754..9af40d88c239 100644 --- a/src/compiler/scala/tools/nsc/ScriptRunner.scala +++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 4c43b89dacd5..098223aed46d 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/SubComponent.scala b/src/compiler/scala/tools/nsc/SubComponent.scala index 2c51116554f7..d44ad38484bb 100644 --- a/src/compiler/scala/tools/nsc/SubComponent.scala +++ b/src/compiler/scala/tools/nsc/SubComponent.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -53,6 +53,11 @@ abstract class SubComponent { /** SubComponents are added to a HashSet and two phases are the same if they have the same name. */ override def hashCode() = phaseName.hashCode() + override def equals(other: Any) = other match { + case other: SubComponent => phaseName.equals(other.phaseName) + case _ => false + } + /** New flags defined by the phase which are not valid before */ def phaseNewFlags: Long = 0 diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index f883cac5ad95..5a33f9ce81fb 100644 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -60,8 +60,15 @@ trait DocComments { self: Global => private def allInheritedOverriddenSymbols(sym: Symbol): List[Symbol] = { val getter: Symbol = sym.getter val symOrGetter = getter.orElse(sym) - if (!symOrGetter.owner.isClass) Nil - else symOrGetter.owner.ancestors map (symOrGetter overriddenSymbol _) filter (_ != NoSymbol) + if (symOrGetter.owner.isClass) + symOrGetter.owner.ancestors + .flatMap { ancestor => + symOrGetter.overriddenSymbol(ancestor) match { + case NoSymbol => Nil + case matching => List(matching) + } + } + else Nil } def fillDocComment(sym: Symbol, comment: DocComment): Unit = { @@ -69,7 +76,6 @@ trait DocComments { self: Global => comment.defineVariables(sym) } - def replaceInheritDocToInheritdoc(docStr: String):String = { docStr.replaceAll("""\{@inheritDoc\p{Zs}*\}""", "@inheritdoc") } @@ -185,7 +191,7 @@ trait DocComments { self: Global => } def mergeSection(srcSec: Option[(Int, Int)], dstSec: Option[(Int, Int)]) = dstSec match { - case Some((start, end)) => + case Some((_, end)) => if (end > tocopy) tocopy = end case None => srcSec match { @@ -292,30 +298,41 @@ trait DocComments { self: Global => out.toString } - /** Maps symbols to the variable -> replacement maps that are defined - * in their doc comments + /** Maps symbols to the `variable -> replacement` maps that are defined + * in their doc comments. */ - private val defs = mutable.HashMap[Symbol, Map[String, String]]() withDefaultValue Map() + private val defs = mutable.HashMap.empty[Symbol, Map[String, String]].withDefaultValue(Map()) - /** Lookup definition of variable. + /** Look up definition of variable. + * + * - For a module, try the companion class first. + * - For classes with a self type, search on that basis. + * - Search for definitions on base classes, then on enclosing elements. * * @param vble The variable for which a definition is searched * @param site The class for which doc comments are generated */ @tailrec - final def lookupVariable(vble: String, site: Symbol): Option[String] = site match { - case NoSymbol => None - case _ => - val searchList = - if (site.isModule) site :: site.info.baseClasses - else site.info.baseClasses - - searchList collectFirst { case x if defs(x) contains vble => defs(x)(vble) } match { - case Some(str) if str startsWith "$" => lookupVariable(str.tail, site) - case s @ Some(str) => s - case None => lookupVariable(vble, site.owner) + final def lookupVariable(vble: String, site: Symbol): Option[String] = + if (site == NoSymbol) None + else { + val searchList = { + var bases = List.empty[Symbol] + def include(k: Symbol): Unit = bases ::= k + def examine(k: Symbol): Unit = { + val bs = if (k.hasSelfType) k.typeOfThis.baseClasses else k.baseClasses + bs.foreach(include) + } + if (site.isModule) examine(site.companionClass) + examine(site) + bases.reverse.distinct } - } + searchList.collectFirst { case x if defs(x).contains(vble) => defs(x)(vble) } match { + case Some(str) if str.startsWith("$") => lookupVariable(str.tail, site) + case s @ Some(str) => defs(site) += vble -> str; s + case None => lookupVariable(vble, site.owner) + } + } /** Expand variable occurrences in string `str`, until a fix point is reached or * an expandLimit is exceeded. @@ -363,13 +380,13 @@ trait DocComments { self: Global => case Some(replacement) => replaceWith(replacement) case None => val pos = docCommentPos(sym) - val loc = pos withPoint (pos.start + vstart + 1) + val loc = if (pos.isDefined) pos.withPoint(pos.start + vstart + 1) else NoPosition runReporting.warning(loc, s"Variable $vname undefined in comment for $sym in $site", WarningCategory.Scaladoc, sym) } } } } - if (out.length == 0) str + if (out.isEmpty) str else { out append str.substring(copied) expandInternal(out.toString, depth + 1) @@ -381,7 +398,6 @@ trait DocComments { self: Global => expandInternal(initialStr, 0).replace("""\$""", "$") } - // !!! todo: inherit from Comment? case class DocComment(raw: String, pos: Position = NoPosition, codePos: Position = NoPosition) { /** Returns: @@ -421,23 +437,20 @@ trait DocComments { self: Global => else { val start1 = pos.start + start val end1 = pos.start + end - pos withStart start1 withPoint start1 withEnd end1 + pos.copyRange(start1, start1, end1) } - def defineVariables(sym: Symbol) = { - val Trim = "(?s)^[\\s&&[^\n\r]]*(.*?)\\s*$".r - - defs(sym) ++= defines.map { - str => { - val start = skipWhitespace(str, "@define".length) - val (key, value) = str.splitAt(skipVariable(str, start)) - key.drop(start) -> value + def defineVariables(sym: Symbol) = + defs(sym) ++= defines.map { str => + val start = skipWhitespace(str, "@define".length) + str.splitAt(skipVariable(str, start)) match { + case (key, DocComment.Trim(value)) => variableName(key.drop(start)) -> value.replaceAll("\\s+\\*+$", "") + case x => throw new MatchError(x) } - } map { - case (key, Trim(value)) => variableName(key) -> value.replaceAll("\\s+\\*+$", "") - case x => throw new MatchError(x) } - } + } + object DocComment { + private val Trim = "(?s)^[\\s&&[^\n\r]]*(.*?)\\s*$".r } case class UseCase(comment: DocComment, body: String, pos: Position) { @@ -560,5 +573,5 @@ trait DocComments { self: Global => } } - class ExpansionLimitExceeded(str: String) extends Exception + class ExpansionLimitExceeded(str: String) extends Exception(str) } diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index a0a007634e2f..3f5b06281197 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -89,7 +89,7 @@ abstract class NodePrinters { tree match { case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) - case id @ Ident(name) => showNameAndPos(id) + case id: Ident => showNameAndPos(id) case _ => "" + tree } } @@ -124,6 +124,7 @@ abstract class NodePrinters { } } def println(s: String) = printLine(s, "") + def print(s: String) = buf.append(s) def printLine(value: String, comment: String): Unit = { buf append " " * level @@ -214,7 +215,7 @@ abstract class NodePrinters { } def traverse(tree: Tree): Unit = { - showPosition(tree) + print(showPosition(tree)) tree match { case ApplyDynamic(fun, args) => applyCommon(tree, fun, args) @@ -234,7 +235,6 @@ abstract class NodePrinters { case ld @ LabelDef(name, params, rhs) => printMultiline(tree) { - showNameAndPos(ld) traverseList("()", "params")(params) traverse(rhs) } @@ -358,7 +358,7 @@ abstract class NodePrinters { tree match { case t: RefTree => println(showRefTree(t)) case t if t.productArity == 0 => println(treePrefix(t)) - case t => printMultiline(tree)(tree.productIterator foreach traverseAny) + case _ => printMultiline(tree)(tree.productIterator foreach traverseAny) } } } diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala index 391a48a107be..3c7060d87c72 100644 --- a/src/compiler/scala/tools/nsc/ast/Positions.scala +++ b/src/compiler/scala/tools/nsc/ast/Positions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/Printers.scala b/src/compiler/scala/tools/nsc/ast/Printers.scala index 261d125b96c5..254871fbfa92 100644 --- a/src/compiler/scala/tools/nsc/ast/Printers.scala +++ b/src/compiler/scala/tools/nsc/ast/Printers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -34,7 +34,7 @@ trait Printers extends scala.reflect.internal.Printers { this: Global => printTree( if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) { tree match { - case ClassDef(_, _, _, impl @ Template(ps, noSelfType, body)) + case ClassDef(_, _, _, impl @ Template(ps, `noSelfType`, body)) if (tree.symbol.thisSym != tree.symbol) => ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body)) case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl) @@ -150,8 +150,8 @@ trait Printers extends scala.reflect.internal.Printers { this: Global => // if a Block only continues one actual statement, just print it. case Block(stats, expr) => allStatements(tree) match { - case List(x) => printTree(x) - case xs => s() + case List(x) => printTree(x) + case _ => s() } // We get a lot of this stuff diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala index ae55c09c3387..a309eecfe874 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -282,7 +282,7 @@ abstract class TreeBrowsers { // skip through 1-ary trees def expando(tree: Tree): List[Tree] = tree.children match { case only :: Nil => only :: expando(only) - case other => tree :: Nil + case _ => tree :: Nil } val path = new TreePath((treeModel.getRoot :: unit :: expando(unit.unit.body)).toArray[AnyRef]) // targ necessary to disambiguate Object and Object[] ctors @@ -465,10 +465,10 @@ abstract class TreeBrowsers { case Super(qualif, mix) => List(qualif) - case This(qualif) => + case This(_) => Nil - case Select(qualif, selector) => + case Select(qualif, _) => List(qualif) case Ident(name) => @@ -486,7 +486,7 @@ abstract class TreeBrowsers { case SingletonTypeTree(ref) => List(ref) - case SelectFromTypeTree(qualif, selector) => + case SelectFromTypeTree(qualif, _) => List(qualif) case CompoundTypeTree(templ) => @@ -619,13 +619,13 @@ abstract class TreeBrowsers { toDocument(hi) :: ")") ) - case RefinedType(parents, defs) => + case RefinedType(parents, _) => Document.group( Document.nest(4, "RefinedType(" :/: toDocument(parents) :: ")") ) - case ClassInfoType(parents, defs, clazz) => + case ClassInfoType(parents, _, clazz) => Document.group( Document.nest(4,"ClassInfoType(" :/: toDocument(parents) :: ", " :/: diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index f3979f6c94a2..811d91043b5d 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 67166665cf12..b9f2062bac97 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,12 +13,11 @@ package scala.tools.nsc package ast -import scala.annotation.tailrec +import scala.annotation.{tailrec, unused} import scala.collection.mutable.ListBuffer -import symtab.Flags._ -import scala.reflect.internal.util.FreshNameCreator -import scala.reflect.internal.util.ListOfNil +import scala.reflect.internal.util.{FreshNameCreator, ListOfNil} import scala.util.chaining._ +import symtab.Flags._ /** XXX to resolve: TreeGen only assumes global is a SymbolTable, but * TreeDSL at the moment expects a Global. Can we get by with SymbolTable? @@ -304,7 +303,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { * @param name name for the new method * @param additionalFlags flags to be put on the method in addition to FINAL */ - private def mkMethodForFunctionBody(localTyper: analyzer.Typer) + private def mkMethodForFunctionBody(@unused localTyper: analyzer.Typer) (owner: Symbol, fun: Function, name: TermName) (methParamProtos: List[Symbol] = fun.vparams.map(_.symbol), resTp: Type = functionResultType(fun.tpe), diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index e7a0cce45ee2..a16dbfe4260a 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -62,8 +62,8 @@ abstract class TreeInfo extends scala.reflect.internal.TreeInfo with MacroAnnoti // new B(v). Returns B and v. object Box { def unapply(t: Tree): Option[(Tree, Type)] = t match { - case Apply(sel @ Select(New(tpt), nme.CONSTRUCTOR), v :: Nil) => Some((v, tpt.tpe.finalResultType)) - case _ => None + case Apply(Select(New(tpt), nme.CONSTRUCTOR), v :: Nil) => Some((v, tpt.tpe.finalResultType)) + case _ => None } } // (new B(v)).unbox. returns v. diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 8ba674a4a823..1c8ff6a8fd70 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -204,7 +204,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => tree, transformer.transform(arg)) case _: TypeTreeWithDeferredRefCheck => transformer.treeCopy.TypeTreeWithDeferredRefCheck(tree) - case x => super.xtransform(transformer, tree) + case _ => super.xtransform(transformer, tree) } // Finally, no one uses resetAllAttrs anymore, so I'm removing it from the compiler. diff --git a/src/compiler/scala/tools/nsc/ast/parser/BracePair.scala b/src/compiler/scala/tools/nsc/ast/parser/BracePair.scala index 8fbdec3db35c..fa5aa4bf3324 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/BracePair.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/BracePair.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/parser/BracePatch.scala b/src/compiler/scala/tools/nsc/ast/parser/BracePatch.scala index d062319658bc..56dfdbc3217c 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/BracePatch.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/BracePatch.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/parser/Change.scala b/src/compiler/scala/tools/nsc/ast/parser/Change.scala index 664cc9879c47..dd3003c112bd 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Change.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Change.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala b/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala index a3b858c34fbc..e935ff77b54b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/CommonTokens.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 5efd9e7251ed..e0a21b66a788 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -137,7 +137,7 @@ trait MarkupParsers { try handle.parseAttribute(r2p(start, mid, curOffset), tmp) catch { - case e: RuntimeException => + case _: RuntimeException => errorAndResult("error parsing attribute value", parser.errorTermTree) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 14dd845076f1..66fbcfe3659f 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -23,6 +23,7 @@ import scala.reflect.internal.util.{CodeAction, FreshNameCreator, ListOfNil, Pos import scala.reflect.internal.{Precedence, ModifierFlags => Flags} import scala.tools.nsc.Reporting.WarningCategory import scala.tools.nsc.ast.parser.Tokens._ +import scala.util.chaining._ /** Historical note: JavaParsers started life as a direct copy of Parsers * but at a time when that Parsers had been replaced by a different one. @@ -155,7 +156,7 @@ self => val global: Global import global._ - case class OpInfo(lhs: Tree, operator: TermName, targs: List[Tree], offset: Offset) { + case class OpInfo(lhs: Tree, operator: TermName, targs: List[Tree], operatorPos: Position, targsPos: Position) { def precedence = Precedence(operator.toString) } @@ -218,7 +219,7 @@ self => override def blockExpr(): Tree = skipBraces(EmptyTree) - override def templateBody(isPre: Boolean) = skipBraces((noSelfType, EmptyTree.asList)) + override def templateBody() = skipBraces((noSelfType, EmptyTree.asList)) } class UnitParser(override val unit: global.CompilationUnit, patches: List[BracePatch]) extends SourceFileParser(unit.source) { uself => @@ -585,15 +586,18 @@ self => def syntaxError(offset: Offset, msg: String, actions: List[CodeAction] = Nil): Unit - private def syntaxError(pos: Position, msg: String, skipIt: Boolean): Unit = syntaxError(pos, msg, skipIt, Nil) + private def syntaxError(pos: Position, msg: String, skipIt: Boolean): Unit = + syntaxError(pos, msg, skipIt, actions = Nil) private def syntaxError(pos: Position, msg: String, skipIt: Boolean, actions: List[CodeAction]): Unit = syntaxError(pos pointOrElse in.offset, msg, skipIt, actions) - def syntaxError(msg: String, skipIt: Boolean): Unit = syntaxError(msg, skipIt, Nil) + def syntaxError(msg: String, skipIt: Boolean): Unit = + syntaxError(msg, skipIt, actions = Nil) def syntaxError(msg: String, skipIt: Boolean, actions: List[CodeAction]): Unit = syntaxError(in.offset, msg, skipIt, actions) - def syntaxError(offset: Offset, msg: String, skipIt: Boolean): Unit = syntaxError(offset, msg, skipIt, Nil) + def syntaxError(offset: Offset, msg: String, skipIt: Boolean): Unit = + syntaxError(offset, msg, skipIt, actions = Nil) def syntaxError(offset: Offset, msg: String, skipIt: Boolean, actions: List[CodeAction]): Unit = { if (offset > lastErrorOffset) { syntaxError(offset, msg, actions) @@ -603,8 +607,10 @@ self => skip(UNDEF) } - def warning(msg: String, category: WarningCategory): Unit = warning(in.offset, msg, category, Nil) - def warning(msg: String, category: WarningCategory, actions: List[CodeAction]): Unit = warning(in.offset, msg, category, actions) + def warning(msg: String, category: WarningCategory): Unit = + warning(in.offset, msg, category, actions = Nil) + def warning(msg: String, category: WarningCategory, actions: List[CodeAction]): Unit = + warning(in.offset, msg, category, actions) def syntaxErrorOrIncomplete(msg: String, skipIt: Boolean, actions: List[CodeAction] = Nil): Unit = { if (in.token == EOF) @@ -617,22 +623,18 @@ self => and } - // warn under -Xsource:3 - def migrationWarning(offset: Offset, msg: String, since: String, actions: List[CodeAction] = Nil): Unit = - if (currentRun.isScala3) - warning(offset, msg, WarningCategory.Scala3Migration, actions) - - // warn under -Xsource:3, otherwise deprecation - def hardMigrationWarning(offset: Offset, msg: String, since: String, actions: List[CodeAction] = Nil): Unit = + // warn under -Xsource:3; otherwise if since is nonEmpty, issue a deprecation + def migrationWarning(offset: Offset, msg: String, since: String = "", actions: List[CodeAction] = Nil): Unit = if (currentRun.isScala3) warning(offset, msg, WarningCategory.Scala3Migration, actions) - else deprecationWarning(offset, msg, since, actions) + else if (!since.isEmpty) deprecationWarning(offset, msg, since, actions) // deprecation or migration under -Xsource:3, with different messages - def hardMigrationWarning(offset: Offset, depr: => String, migr: => String, since: String, actions: String => List[CodeAction]): Unit = - if (currentRun.isScala3) warning(offset, migr, WarningCategory.Scala3Migration, actions(migr)) - else deprecationWarning(offset, depr, since, actions(depr)) - def hardMigrationWarning(offset: Offset, depr: => String, migr: => String, since: String): Unit = - hardMigrationWarning(offset, depr, migr, since, _ => Nil) + def migrationWarning(offset: Offset, depr: => String, migr: => String, since: String, actions: String => List[CodeAction]): Unit = { + val msg = if (currentRun.isScala3) migr else depr + migrationWarning(offset, msg, since, actions(msg)) + } + def migrationWarning(offset: Offset, depr: => String, migr: => String, since: String): Unit = + migrationWarning(offset, depr, migr, since, (_: String) => Nil) def expectedMsgTemplate(exp: String, fnd: String) = s"$exp expected but $fnd found." def expectedMsg(token: Token): String = @@ -819,7 +821,7 @@ self => def actions = if (tree.pos.isRange) runReporting.codeAction("add parentheses", tree.pos, s"(${unit.source.sourceAt(tree.pos)})", msg) else Nil - migrationWarning(tree.pos.point, wrn, "2.13.11", actions) + migrationWarning(tree.pos.point, wrn, /*since="2.13.11",*/ actions = actions) List(convertToParam(tree)) case _ => List(convertToParam(tree)) } @@ -933,52 +935,6 @@ self => case _ => t } - /** Create tree representing (unencoded) binary operation expression or pattern. */ - def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position, targs: List[Tree] = Nil): Tree = { - require(isExpr || targs.isEmpty || targs.exists(_.isErroneous), - s"Incompatible args to makeBinop: !isExpr but targs=$targs") - - val rightAssoc = !nme.isLeftAssoc(op) - - def mkSelection(t: Tree) = { - val pos = (opPos union t.pos) makeTransparentIf rightAssoc - val sel = atPos(pos)(Select(stripParens(t), op.encode)) - if (targs.isEmpty) sel - else { - /* if it's right-associative, `targs` are between `op` and `t` so make the pos transparent */ - atPos((pos union targs.last.pos) makeTransparentIf rightAssoc) { - TypeApply(sel, targs) - } - } - } - def mkNamed(args: List[Tree]) = if (isExpr) args.map(treeInfo.assignmentToMaybeNamedArg) else args - var isMultiarg = false - val arguments = right match { - case Parens(Nil) => literalUnit :: Nil - case Parens(args @ (_ :: Nil)) => mkNamed(args) - case Parens(args) => isMultiarg = true ; mkNamed(args) - case _ => right :: Nil - } - def mkApply(fun: Tree, args: List[Tree]) = { - val apply = Apply(fun, args).updateAttachment(InfixAttachment) - if (isMultiarg) apply.updateAttachment(MultiargInfixAttachment) - apply - } - if (isExpr) { - if (rightAssoc) { - import symtab.Flags._ - val x = freshTermName(nme.RIGHT_ASSOC_OP_PREFIX) - val liftedArg = atPos(left.pos) { - ValDef(Modifiers(FINAL | SYNTHETIC | ARTIFACT), x, TypeTree(), stripParens(left)) - } - val apply = mkApply(mkSelection(right), List(Ident(x) setPos left.pos.focus)) - Block(liftedArg :: Nil, apply) - } else - mkApply(mkSelection(left), arguments) - } else - mkApply(Ident(op.encode), stripParens(left) :: arguments) - } - /** Is current ident a `*`, and is it followed by a `)` or `, )`? */ def followingIsScala3Vararg(): Boolean = currentRun.isScala3 && isRawStar && lookingAhead { @@ -1005,15 +961,18 @@ self => private def headPrecedence = opHead.precedence private def popOpInfo(): OpInfo = try opHead finally opstack = opstack.tail private def pushOpInfo(top: Tree): Unit = { - val name = in.name - val offset = in.offset + val name = in.name + val nameStart = in.offset ident() + val operatorPos = Position.range(source, nameStart, nameStart, in.lastOffset) //offset + operator.length) + val targsStart = in.offset val targs = if (in.token == LBRACKET) exprTypeArgs() else Nil - val opinfo = OpInfo(top, name, targs, offset) + val targsPos = if (targs.nonEmpty) Position.range(source, targsStart, targsStart, in.lastOffset) else NoPosition + val opinfo = OpInfo(top, name, targs, operatorPos, targsPos) opstack ::= opinfo } - def checkHeadAssoc(leftAssoc: Boolean) = checkAssoc(opHead.offset, opHead.operator, leftAssoc) + def checkHeadAssoc(leftAssoc: Boolean) = checkAssoc(opHead.operatorPos.point, opHead.operator, leftAssoc) def checkAssoc(offset: Offset, op: Name, leftAssoc: Boolean) = ( if (nme.isLeftAssoc(op) != leftAssoc) syntaxError(offset, "left- and right-associative operators with same precedence may not be mixed", skipIt = false) @@ -1021,39 +980,75 @@ self => def finishPostfixOp(start: Int, base: List[OpInfo], opinfo: OpInfo): Tree = { if (opinfo.targs.nonEmpty) - syntaxError(opinfo.offset, "type application is not allowed for postfix operators") + syntaxError(opinfo.targsPos.point, "type application is not allowed for postfix operators") val lhs = reduceExprStack(base, opinfo.lhs) - makePostfixSelect(if (lhs.pos.isDefined) lhs.pos.start else start, opinfo.offset, stripParens(lhs), opinfo.operator) + val at = if (lhs.pos.isDefined) lhs.pos.start else start + atPos(opinfo.operatorPos.withStart(at)) { + Select(stripParens(lhs), opinfo.operator.encode).updateAttachment(PostfixAttachment) + } } - def finishBinaryOp(isExpr: Boolean, opinfo: OpInfo, rhs: Tree): Tree = { - import opinfo._ - val operatorPos: Position = Position.range(rhs.pos.source, offset, offset, offset + operator.length) - val pos = lhs.pos.union(rhs.pos).union(operatorPos).withEnd(in.lastOffset).withPoint(offset) + /** Create tree representing (unencoded) binary operation expression or pattern. */ + def finishBinaryOp(isExpr: Boolean, opinfo: OpInfo, right: Tree): Tree = { + import opinfo.{lhs => left, operator, targs, operatorPos, targsPos} + val pos = operatorPos.union(left.pos).union(right.pos).withEnd(in.lastOffset) if (targs.nonEmpty) { - val qual = unit.source.sourceAt(lhs.pos) - val fun = s"${CodeAction.maybeWrapInParens(qual)}.${unit.source.sourceAt(operatorPos.withEnd(rhs.pos.start))}".trim - val fix = s"$fun${CodeAction.wrapInParens(unit.source.sourceAt(rhs.pos))}" + require(isExpr || targs.isEmpty || targs.exists(_.isErroneous), s"Binary op !isExpr but targs=$targs") + val qual = unit.source.sourceAt(left.pos) + val fun = s"${CodeAction.maybeWrapInParens(qual)}.${unit.source.sourceAt(operatorPos.withEnd(right.pos.start))}" + val fix = s"${fun.trim}${CodeAction.wrapInParens(unit.source.sourceAt(right.pos))}" val msg = "type application is not allowed for infix operators" - migrationWarning(offset, msg, "2.13.11", - runReporting.codeAction("use selection", pos, fix, msg)) + // omit since="2.13.11" to avoid deprecation + migrationWarning(targsPos.point, msg, actions = runReporting.codeAction("use selection", pos, fix, msg)) + } + val rightAssoc = !nme.isLeftAssoc(operator) + def mkSelection(t: Tree) = { + // if it's right-associative, `targs` are between `op` and `t` so make the pos transparent + val selPos = operatorPos.union(t.pos).makeTransparentIf(rightAssoc) + val sel = atPos(selPos)(Select(stripParens(t), operator.encode)) + if (targs.isEmpty) sel + else atPos(selPos.union(targsPos).makeTransparentIf(rightAssoc)) { TypeApply(sel, targs) } + } + def mkNamed(args: List[Tree]) = if (!isExpr) args else + args.map(treeInfo.assignmentToMaybeNamedArg(_)) + .tap(res => if (currentRun.isScala3 && args.lengthCompare(1) == 0 && (args.head ne res.head)) + deprecationWarning(args.head.pos.point, "named argument is deprecated for infix syntax", since="2.13.16")) + var isMultiarg = false + val arguments = right match { + case Parens(Nil) => literalUnit :: Nil + case Parens(args @ (_ :: Nil)) => mkNamed(args) + case Parens(args) => isMultiarg = true; mkNamed(args) + case _ => right :: Nil + } + def mkApply(fun: Tree, args: List[Tree]) = + Apply(fun, args) + .updateAttachment(InfixAttachment) + .tap(apply => if (isMultiarg) apply.updateAttachment(MultiargInfixAttachment)) + atPos(pos) { + if (!isExpr) + mkApply(Ident(operator.encode), stripParens(left) :: arguments) + else if (!rightAssoc) + mkApply(mkSelection(left), arguments) + else { + import symtab.Flags._ + val x = freshTermName(nme.RIGHT_ASSOC_OP_PREFIX) + val liftedArg = atPos(left.pos) { + ValDef(Modifiers(FINAL | SYNTHETIC | ARTIFACT), x, TypeTree(), stripParens(left)) + } + val apply = mkApply(mkSelection(right), List(Ident(x) setPos left.pos.focus)) + Block(liftedArg :: Nil, apply) + } } - atPos(pos)(makeBinop(isExpr, lhs, operator, rhs, operatorPos, targs)) } - def reduceExprStack(base: List[OpInfo], top: Tree): Tree = reduceStack(isExpr = true, base, top) - def reducePatternStack(base: List[OpInfo], top: Tree): Tree = reduceStack(isExpr = false, base, top) + def reduceExprStack(base: List[OpInfo], top: Tree): Tree = reduceStack(isExpr = true, base, top) def reduceStack(isExpr: Boolean, base: List[OpInfo], top: Tree): Tree = { val opPrecedence = if (isIdent) Precedence(in.name.toString) else Precedence(0) - val leftAssoc = !isIdent || (nme isLeftAssoc in.name) + val leftAssoc = !isIdent || nme.isLeftAssoc(in.name) - reduceStack(isExpr, base, top, opPrecedence, leftAssoc) - } - - def reduceStack(isExpr: Boolean, base: List[OpInfo], top: Tree, opPrecedence: Precedence, leftAssoc: Boolean): Tree = { def isDone = opstack == base def lowerPrecedence = !isDone && (opPrecedence < headPrecedence) def samePrecedence = !isDone && (opPrecedence == headPrecedence) @@ -1066,7 +1061,7 @@ self => def loop(top: Tree): Tree = if (canReduce) { val info = popOpInfo() if (!isExpr && info.targs.nonEmpty) { - syntaxError(info.offset, "type application is not allowed in pattern") + syntaxError(info.targsPos.point, "type application is not allowed in pattern") info.targs.foreach(_.setType(ErrorType)) } loop(finishBinaryOp(isExpr, info, top)) @@ -1291,7 +1286,7 @@ self => val parents = ListBuffer.empty[Tree] var otherInfixOp: Tree = EmptyTree def collect(tpt: Tree): Unit = tpt match { - case AppliedTypeTree(op @ Ident(tpnme.AND), List(left, right)) => + case AppliedTypeTree(Ident(tpnme.AND), List(left, right)) => collect(left) collect(right) case AppliedTypeTree(op, args) if args.exists(arg => arg.pos.start < op.pos.point) => @@ -1359,7 +1354,6 @@ self => def selector(start: Offset, t0: Tree): Tree = { val t = stripParens(t0) val point = if (isIdent) in.offset else in.lastOffset //scala/bug#8459 - //assert(t.pos.isDefined, t) if (t != EmptyTree) Select(t, ident(skipIt = false)) setPos r2p(start, point, in.lastOffset) else @@ -1556,7 +1550,7 @@ self => // Scala 2 allowed uprooted Ident for purposes of virtualization val t1 = - if (currentRun.isScala3Cross) atPos(o2p(start)) { Select(Select(Ident(nme.ROOTPKG), nme.scala_), nme.StringContextName) } + if (currentRun.sourceFeatures.stringContextScope) atPos(o2p(start)) { Select(Select(Ident(nme.ROOTPKG), nme.scala_), nme.StringContextName) } else atPos(o2p(start)) { Ident(nme.StringContextName).updateAttachment(VirtualStringContext) } val t2 = atPos(start) { Apply(t1, partsBuf.toList) } updateAttachment InterpolatedString t2 setPos t2.pos.makeTransparent @@ -1624,8 +1618,8 @@ self => accept(RPAREN) if (isWildcard(r)) placeholderParams.head.tpt match { - case tpt @ TypeTree() => tpt.setType(definitions.BooleanTpe) - case _ => + case TypeTree() => placeholderParams.head.updateAttachment(BooleanParameterType) + case _ => } r } else { @@ -1734,12 +1728,13 @@ self => if (in.token == LBRACE) inBracesOrNil(enumerators()) else inParensOrNil(enumerators()) newLinesOpt() - if (in.token == YIELD) { - in.nextToken() - gen.mkFor(enums, gen.Yield(expr())) - } else { - gen.mkFor(enums, expr()) - } + val body = + if (in.token == YIELD) { + in.nextToken() + gen.Yield(expr()) + } else + expr() + gen.mkFor(enums, body) } def adjustStart(tree: Tree) = if (tree.pos.isRange && start < tree.pos.start) @@ -2114,7 +2109,7 @@ self => def msg(what: String, instead: String): String = s"`val` keyword in for comprehension is $what: $instead" if (hasEq) { val without = "instead, bind the value without `val`" - hardMigrationWarning(in.offset, msg("deprecated", without), msg("unsupported", without), "2.10.0", actions) + migrationWarning(in.offset, msg("deprecated", without), msg("unsupported", without), since="2.10.0", actions=actions(_)) } else { val m = msg("unsupported", "just remove `val`") syntaxError(in.offset, m, actions(m)) @@ -2202,13 +2197,10 @@ self => */ def pattern1(): Tree = pattern2() match { case p @ Ident(name) if in.token == COLON => - if (nme.isVariableName(name)) { - p.removeAttachment[BackquotedIdentifierAttachment.type] - atPos(p.pos.start, in.skipToken())(Typed(p, compoundType())) - } else { - syntaxError(in.offset, "Pattern variables must start with a lower-case letter. (SLS 8.1.1.)") - p - } + if (!nme.isVariableName(name)) + syntaxError(p.pos.point, "Pattern variables must start with a lower-case letter. (SLS 8.1.1.)") + p.removeAttachment[BackquotedIdentifierAttachment.type] + atPos(p.pos.start, in.skipToken())(Typed(p, compoundType())) case p => p } @@ -2262,8 +2254,8 @@ self => } else EmptyTree @tailrec - def loop(top: Tree): Tree = reducePatternStack(base, top) match { - case next if isIdent && !isRawBar => pushOpInfo(next) ; loop(simplePattern(() => badPattern3())) + def loop(top: Tree): Tree = reduceStack(isExpr = false, base, top) match { + case next if isIdent && !isRawBar => pushOpInfo(next); loop(simplePattern(() => badPattern3())) case next => next } checkWildStar orElse stripParens(loop(top)) @@ -2274,9 +2266,9 @@ self => def isDelimiter = in.token == RPAREN || in.token == RBRACE def isCommaOrDelimiter = isComma || isDelimiter val (isUnderscore, isStar) = opstack match { - case OpInfo(Ident(nme.WILDCARD), nme.STAR, _, _) :: _ => (true, true) - case OpInfo(_, nme.STAR, _, _) :: _ => (false, true) - case _ => (false, false) + case OpInfo(Ident(nme.WILDCARD), nme.STAR, _, _, _) :: _ => (true, true) + case OpInfo(_, nme.STAR, _, _, _) :: _ => (false, true) + case _ => (false, false) } def isSeqPatternClose = isUnderscore && isStar && isSequenceOK && isDelimiter val preamble = "bad simple pattern:" @@ -2669,7 +2661,7 @@ self => val pname: TypeName = if (in.token == USCORE) { if (!isAbstractOwner) - hardMigrationWarning(in.offset, "Top-level wildcard is not allowed", "2.13.7") + migrationWarning(in.offset, "Top-level wildcard is not allowed", since = "2.13.7") in.nextToken() freshTypeName("_$$") } @@ -2682,7 +2674,7 @@ self => def msg(what: String) = s"""view bounds are $what; use an implicit parameter instead. | example: instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`""".stripMargin while (in.token == VIEWBOUND) { - hardMigrationWarning(in.offset, msg("deprecated"), msg("unsupported"), "2.12.0") + migrationWarning(in.offset, msg("deprecated"), msg("unsupported"), since = "2.12.0") contextBoundBuf += atPos(in.skipToken())(makeFunctionTypeTree(List(Ident(pname)), typ())) } while (in.token == COLON) { @@ -2732,7 +2724,7 @@ self => case Nil => Nil case t :: rest => // The first import should start at the position of the keyword. - t.setPos(t.pos.withStart(offset)) + if (t.pos.isRange) t.setPos(t.pos.withStart(offset)) t :: rest } } @@ -2759,10 +2751,11 @@ self => val selectors: List[ImportSelector] = in.token match { case USCORE => List(wildImportSelector()) // import foo.bar._ - case IDENTIFIER if currentRun.isScala3 && in.name == raw.STAR => - List(wildImportSelector()) // import foo.bar.* + case IDENTIFIER if currentRun.isScala3 && (in.name == raw.STAR || in.name == nme.`given`) => + if (in.name == raw.STAR) List(wildImportSelector()) // import foo.bar.* + else List(importSelector()) // import foo.bar.given case LBRACE => - importSelectors() // import foo.bar.{ x, y, z } + importSelectors() // import foo.bar.{x, y, z, given, *} case _ => if (currentRun.isScala3 && lookingAhead { isRawIdent && in.name == nme.as }) List(importSelector()) // import foo.bar as baz @@ -2775,7 +2768,7 @@ self => in.nextToken() return loop(t) } - // import foo.bar.Baz; + // import foo.Bar else List(makeImportSelector(name, nameOffset)) } } @@ -2804,23 +2797,28 @@ self => * }}} */ def importSelectors(): List[ImportSelector] = { - def isWilder(sel: ImportSelector) = sel.isWildcard || currentRun.isScala3 && !sel.isRename && sel.name == nme.`given` + def isWilder(sel: ImportSelector) = sel.isWildcard || sel.isGiven // error on duplicate target names, import x.{a=>z, b=>z}, and fix import x.{given, *} to x._ def checkSelectors(xs: List[ImportSelector]): List[ImportSelector] = xs match { case h :: t => - // wildcards must come last, and for -Xsource:3, take trailing given, * (or *, given) as _ + // wildcards must come last, and for -Xsource:3, accept trailing given and/or *, converting {given, *} to * if (isWilder(h)) { - if (t.exists(!isWilder(_))) - syntaxError(h.namePos, "wildcard import must be in last position") - xs.filter(_.isWildcard) match { - case ws @ (_ :: Nil) => ws - case Nil => - syntaxError(h.namePos, "given requires a wildcard selector") - ImportSelector.wildAt(h.namePos) :: Nil - case ws @ (w :: _) => - syntaxError(w.namePos, "duplicate wildcard selector") - w :: Nil - } + val wildcard = + if (t.exists(!isWilder(_))) { + syntaxError(h.namePos, "wildcard import must be in last position") + h + } + else t match { + case Nil => h + case other :: Nil if h.isWildcard != other.isWildcard => + if (h.isWildcard) h else other + case _ => + val (wilds, givens) = xs.partition(_.isWildcard) + val dupes = if (wilds.length > 1) wilds else givens + syntaxError(dupes(1).namePos, "duplicate wildcard selector") + h + } + wildcard :: Nil } else { if (!h.isMask) @@ -2851,17 +2849,15 @@ self => val start = in.offset val bbq = in.token == BACKQUOTED_IDENT val name = wildcardOrIdent() - val (rename, renameOffset) = - if (in.token == ARROW || (currentRun.isScala3 && isRawIdent && in.name == nme.as)) { - in.nextToken() - if (name == nme.WILDCARD && !bbq) syntaxError(in.offset, "Wildcard import cannot be renamed") - val pos = in.offset - (wildcardOrIdent(), pos) - } - else if (name == nme.WILDCARD && !bbq) (null, -1) - else (name, start) - - ImportSelector(name, start, rename, renameOffset) + if (in.token == ARROW || (currentRun.isScala3 && isRawIdent && in.name == nme.as)) { + in.nextToken() + if (name == nme.WILDCARD && !bbq) syntaxError(in.offset, "Wildcard import cannot be renamed") + val renamePos = in.offset + ImportSelector(name, start, rename = wildcardOrIdent(), renamePos = renamePos) + } + else if (name == nme.WILDCARD && !bbq) ImportSelector.wildAt(start) + else if (currentRun.isScala3 && name == nme.`given` && !bbq) ImportSelector.givenAt(start) + else makeImportSelector(name, start) } def wildImportSelector(): ImportSelector = { @@ -2901,7 +2897,7 @@ self => private def caseAwareTokenOffset = if (in.token == CASECLASS || in.token == CASEOBJECT) in.prev.offset else in.offset - def nonLocalDefOrDcl : List[Tree] = { + def nonLocalDefOrDcl: List[Tree] = { val annots = annotations(skipNewLines = true) defOrDcl(caseAwareTokenOffset, modifiers() withAnnotations annots) } @@ -2912,67 +2908,83 @@ self => * VarDef ::= PatDef | Id {`,` Id} `:` Type `=` `_` * }}} */ - def patDefOrDcl(pos : Int, mods: Modifiers): List[Tree] = { - var newmods = mods + def patDefOrDcl(start: Int, mods: Modifiers): List[Tree] = { + def mkDefs(mods: Modifiers, pat: Tree, rhs: Tree, rhsPos: Position, defPos: Position, isMulti: Boolean) = { + val trees = makePatDef(mods, pat, rhs, rhsPos) + def fixPoint(d: Tree, transparent: Boolean): Unit = { + val p = defPos.withPoint(d.pos.start) + d.setPos(if (transparent) p.makeTransparent else p) + } + trees match { + case d :: Nil => fixPoint(d, transparent = isMulti) + case trees => trees.tail.foreach(fixPoint(_, transparent = true)) // skip match expr + } + if (mods.isDeferred) + trees match { + case ValDef(_, _, _, EmptyTree) :: Nil => + if (mods.isLazy) syntaxError(pat.pos, "lazy values may not be abstract", skipIt = false) + else () + case _ => syntaxError(pat.pos, "pattern definition may not be abstract", skipIt = false) + } + trees + } + // begin in.nextToken() checkKeywordDefinition() - val lhs = commaSeparated { - val start = in.offset + val lhs: List[Tree] = commaSeparated { + val nameStart = in.offset noSeq.pattern2() match { case t @ Ident(_) => - val namePos = NamePos(r2p(start, start)) + val namePos = NamePos(r2p(nameStart, nameStart)) stripParens(t).updateAttachment(namePos) case t => stripParens(t) } } val tp = typedOpt() - val (rhs, rhsPos) = - if (!tp.isEmpty && in.token != EQUALS) { - newmods = newmods | Flags.DEFERRED - (EmptyTree, NoPosition) - } else { + val (rhs, rhsPos, newmods) = + if (!tp.isEmpty && in.token != EQUALS) + (EmptyTree, NoPosition, mods | Flags.DEFERRED) + else { accept(EQUALS) expr() match { - case x if !tp.isEmpty && newmods.isMutable && lhs.forall(_.isInstanceOf[Ident]) && isWildcard(x) => + case x if !tp.isEmpty && mods.isMutable && lhs.forall(_.isInstanceOf[Ident]) && isWildcard(x) => tp match { case SingletonTypeTree(Literal(Constant(_))) => syntaxError(tp.pos, "default initialization prohibited for literal-typed vars", skipIt = false) case _ => } placeholderParams = placeholderParams.tail - newmods = newmods | Flags.DEFAULTINIT - (EmptyTree, x.pos) - case x => (x, x.pos) - } - } - def mkDefs(p: Tree, tp: Tree, rhs: Tree): List[Tree] = { - val trees = { - val pat = if (tp.isEmpty) p else Typed(p, tp) setPos (p.pos union tp.pos) - val ts = makePatDef(newmods, pat, rhs, rhsPos) - val positioned = pat match { - case id @ Ident(_) => id - case Typed(id @ Ident(_), _) => id - case _ => EmptyTree + (EmptyTree, x.pos, mods | Flags.DEFAULTINIT) + case x => (x, x.pos, mods) } - if (!positioned.isEmpty && ts.lengthCompare(1) == 0) - positioned.getAndRemoveAttachment[NamePos].foreach(att => ts.head.updateAttachment[NamePos](att)) - ts } - if (newmods.isDeferred) { - trees match { - case List(ValDef(_, _, _, EmptyTree)) => - if (mods.isLazy) syntaxError(p.pos, "lazy values may not be abstract", skipIt = false) - case _ => syntaxError(p.pos, "pattern definition may not be abstract", skipIt = false) + // each valdef gets transparent defPos with point at name and NamePos + val lhsPos = wrappingPos(lhs) + val defPos = + if (lhsPos.isRange) lhsPos.copyRange(start = start, end = in.lastOffset) + else o2p(start) + def typedPat(pat: Tree, tp: Tree, isLast: Boolean): Tree = + if (tp.isEmpty) pat + else Typed(pat, tp) + .setPos { + if (isLast) pat.pos | tp.pos + else ((pat.pos | tp.pos).makeTransparent) // pos may extend over other patterns } - } - trees - } - val trees = lhs.toList.init.flatMap(mkDefs(_, tp.duplicate, rhs.duplicate)) ::: mkDefs(lhs.last, tp, rhs) - val hd = trees.head - hd.setPos(hd.pos.withStart(pos)) - ensureNonOverlapping(hd, trees.tail) - if (trees.lengthCompare(1) > 0) trees.foreach(_.updateAttachment(MultiDefAttachment)) - trees + def expandPatDefs(lhs: List[Tree], expansion: List[Tree], isMulti: Boolean): List[Tree] = + lhs match { + case pat :: Nil => + // reuse tree on last (or only) expansion + expansion ::: mkDefs(newmods, typedPat(pat, tp, isLast = true), rhs, rhsPos, defPos, isMulti) + case pat :: lhs => + val ts = mkDefs(newmods, typedPat(pat, tp.duplicate, isLast = false), rhs.duplicate, rhsPos, defPos, isMulti) + expandPatDefs(lhs, expansion = expansion ::: ts, isMulti) + case x => throw new MatchError(x) // lhs must not be empty + } + expandPatDefs(lhs, expansion = Nil, lhs.lengthCompare(1) != 0) + .tap(trees => + if (trees.lengthCompare(1) > 0) + trees.foreach(_.updateAttachment[MultiDefAttachment.type](MultiDefAttachment)) + ) } /** {{{ @@ -3017,18 +3029,17 @@ self => if (in.token == THIS) { def missingEquals() = { val msg = "procedure syntax is deprecated for constructors: add `=`, as in method definition" - hardMigrationWarning(in.lastOffset, msg, "2.13.2", - runReporting.codeAction("replace procedure syntax", o2p(in.lastOffset), " =", msg)) + migrationWarning(in.lastOffset, msg, since = "2.13.2", actions = runReporting.codeAction("replace procedure syntax", o2p(in.lastOffset), " =", msg)) } atPos(start, in.skipToken()) { - val vparamss = paramClauses(nme.CONSTRUCTOR, classContextBounds map (_.duplicate), ofCaseClass = false) + val vparamss = paramClauses(nme.CONSTRUCTOR, classContextBounds.map(_.duplicate), ofCaseClass = false) newLineOptWhenFollowedBy(LBRACE) val rhs = if (in.token == LBRACE) { - missingEquals(); atPos(in.offset) { constrBlock(vparamss) } + missingEquals(); atPos(in.offset) { constrBlock() } } else { - accept(EQUALS) ; atPos(in.offset) { constrExpr(vparamss) } + accept(EQUALS) ; atPos(in.offset) { constrExpr() } } DefDef(mods, nme.CONSTRUCTOR, List(), vparamss, TypeTree(), rhs) } @@ -3061,13 +3072,13 @@ self => val rhs = if (isStatSep || in.token == RBRACE) { if (restype.isEmpty) { - hardMigrationWarning(in.lastOffset, msg("deprecated", ": Unit"), msg("unsupported", ": Unit"), "2.13.0", declActions) + migrationWarning(in.lastOffset, msg("deprecated", ": Unit"), msg("unsupported", ": Unit"), since = "2.13.0", actions = declActions) restype = scalaUnitConstr } newmods |= Flags.DEFERRED EmptyTree } else if (restype.isEmpty && in.token == LBRACE) { - hardMigrationWarning(in.offset, msg("deprecated", ": Unit ="), msg("unsupported", ": Unit ="), "2.13.0", defnActions) + migrationWarning(in.offset, msg("deprecated", ": Unit ="), msg("unsupported", ": Unit ="), since = "2.13.0", actions = defnActions) restype = scalaUnitConstr blockExpr() } else { @@ -3089,10 +3100,10 @@ self => val o = nameOffset + name.decode.length runReporting.codeAction("remove ()", r2p(o, o, o + 2), "", msg, expected = Some(("()", unit))) } - def warnNilary() = hardMigrationWarning(nameOffset, unaryMsg("deprecated"), unaryMsg("unsupported"), "2.13.4", action) + def warnNilary() = migrationWarning(nameOffset, unaryMsg("deprecated"), unaryMsg("unsupported"), since = "2.13.4", actions = action) vparamss match { - case List(List()) => warnNilary() - case List(List(), x :: xs) if x.mods.isImplicit => warnNilary() + case List(List()) => warnNilary() + case List(List(), x :: _) if x.mods.isImplicit => warnNilary() case _ => // ok } } @@ -3107,15 +3118,15 @@ self => * | ConstrBlock * }}} */ - def constrExpr(vparamss: List[List[ValDef]]): Tree = - if (in.token == LBRACE) constrBlock(vparamss) - else Block(selfInvocation(vparamss) :: Nil, literalUnit) + def constrExpr(): Tree = + if (in.token == LBRACE) constrBlock() + else Block(selfInvocation() :: Nil, literalUnit) /** {{{ * SelfInvocation ::= this ArgumentExprs {ArgumentExprs} * }}} */ - def selfInvocation(vparamss: List[List[ValDef]]): Tree = + def selfInvocation(): Tree = atPos(accept(THIS)) { newLineOptWhenFollowedBy(LBRACE) var t = Apply(Ident(nme.CONSTRUCTOR), argumentExprs()) @@ -3131,9 +3142,9 @@ self => * ConstrBlock ::= `{` SelfInvocation {semi BlockStat} `}` * }}} */ - def constrBlock(vparamss: List[List[ValDef]]): Tree = + def constrBlock(): Tree = atPos(in.skipToken()) { - val stats = selfInvocation(vparamss) :: { + val stats = selfInvocation() :: { if (isStatSep) { in.nextToken(); blockStatSeq() } else Nil } @@ -3220,7 +3231,7 @@ self => val nameOffset = in.offset val name = identForType() if (currentRun.isScala3 && in.token == LBRACKET && isAfterLineEnd) - hardMigrationWarning(in.offset, "type parameters should not follow newline", "2.13.7") + migrationWarning(in.offset, "type parameters should not follow newline", since = "2.13.7") def orStart(p: Offset) = if (name == tpnme.ERROR) start else p val namePos = NamePos(r2p(orStart(nameOffset), orStart(nameOffset))) atPos(start, orStart(nameOffset)) { @@ -3324,12 +3335,12 @@ self => if (in.token == LBRACE) { val braceOffset = in.offset // @S: pre template body cannot stub like post body can! - val (self, body) = templateBody(isPre = true) + val (self, body) = templateBody() if (in.token == WITH && (self eq noSelfType)) { val advice = if (currentRun.isScala3) "use trait parameters instead." else "they will be replaced by trait parameters in 3.0, see the migration guide on avoiding var/val in traits." - hardMigrationWarning(braceOffset, s"early initializers are deprecated; $advice", "2.13.0") + migrationWarning(braceOffset, s"early initializers are deprecated; $advice", since = "2.13.0") val earlyDefs: List[Tree] = body.map(ensureEarlyDef).filter(_.nonEmpty) in.nextToken() val parents = templateParents() @@ -3350,7 +3361,7 @@ self => copyValDef(vdef)(mods = mods | Flags.PRESUPER) case tdef @ TypeDef(mods, name, tparams, rhs) => def msg(what: String): String = s"early type members are $what: move them to the regular body; the semantics are the same" - hardMigrationWarning(tdef.pos.point, msg("deprecated"), msg("unsupported"), "2.11.0") + migrationWarning(tdef.pos.point, msg("deprecated"), msg("unsupported"), since = "2.11.0") treeCopy.TypeDef(tdef, mods | Flags.PRESUPER, name, tparams, rhs) case docdef @ DocDef(comm, rhs) => treeCopy.DocDef(docdef, comm, rhs) @@ -3406,16 +3417,15 @@ self => /** {{{ * TemplateBody ::= [nl] `{` TemplateStatSeq `}` * }}} - * @param isPre specifies whether in early initializer (true) or not (false) */ - def templateBody(isPre: Boolean) = inBraces(templateStatSeq(isPre)) match { + def templateBody() = inBraces(templateStatSeq()) match { case (selfTypeVal, Nil) => (selfTypeVal, EmptyTree.asList) case result => result } def templateBodyOpt(parenMeansSyntaxError: Boolean): (ValDef, List[Tree]) = { newLineOptWhenFollowedBy(LBRACE) if (in.token == LBRACE) { - templateBody(isPre = false) + templateBody() } else { if (in.token == LPAREN) { if (parenMeansSyntaxError) syntaxError(s"traits or objects may not have parameters", skipIt = true) @@ -3478,9 +3488,8 @@ self => /** {{{ * TemplateStatSeq ::= [id [`:` Type] `=>`] TemplateStats * }}} - * @param isPre specifies whether in early initializer (true) or not (false) */ - def templateStatSeq(isPre : Boolean): (ValDef, List[Tree]) = { + def templateStatSeq(): (ValDef, List[Tree]) = { var self: ValDef = noSelfType var firstOpt: Option[Tree] = None if (isExprIntro) checkNoEscapingPlaceholders { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Patch.scala b/src/compiler/scala/tools/nsc/ast/parser/Patch.scala index 618d594a7fe3..67a632af1cdf 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Patch.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Patch.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,5 +12,7 @@ package scala.tools.nsc.ast.parser -class Patch(off: Int, change: Change) +import scala.annotation.unused + +class Patch(@unused off: Int, @unused change: Change) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 1b6a62deb85a..99edf1e42dc5 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -350,7 +350,7 @@ trait Scanners extends ScannersCommon { /** Are we in a `${ }` block? such that RBRACE exits back into multiline string. */ private def inMultiLineInterpolatedExpression = { sepRegions match { - case RBRACE :: STRINGLIT :: STRINGPART :: rest => true + case RBRACE :: STRINGLIT :: STRINGPART :: _ => true case _ => false } } @@ -528,13 +528,12 @@ trait Scanners extends ScannersCommon { (sepRegions.isEmpty || sepRegions.head == RBRACE)) { if (pastBlankLine()) insertNL(NEWLINES) else if (!isLeadingInfixOperator) insertNL(NEWLINE) - else if (!currentRun.isScala3Cross) { - val msg = """|Line starts with an operator that in future - |will be taken as an infix expression continued from the previous line. - |To force the previous interpretation as a separate statement, - |add an explicit `;`, add an empty line, or remove spaces after the operator.""" - if (currentRun.isScala3) warning(offset, msg.stripMargin, Scala3Migration) - else if (infixMigration) deprecationWarning(msg.stripMargin, "2.13.2") + else if (!currentRun.sourceFeatures.leadingInfix) { + val msg = + sm"""Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). + |To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator.""" + if (currentRun.isScala3) warning(offset, msg, Scala3Migration) + else if (infixMigration) deprecationWarning(msg, "2.13.2") insertNL(NEWLINE) } } @@ -966,19 +965,19 @@ trait Scanners extends ScannersCommon { if (strVal != null) try { val processed = StringContext.processUnicode(strVal) - if (processed != strVal && !currentRun.isScala3Cross) { + if (processed != strVal && !currentRun.sourceFeatures.unicodeEscapesRaw) { val diffPosition = processed.zip(strVal).zipWithIndex.collectFirst { case ((r, o), i) if r != o => i }.getOrElse(processed.length - 1) val pos = offset + 3 + diffPosition def msg(what: String) = s"Unicode escapes in triple quoted strings are $what; use the literal character instead" if (currentRun.isScala3) - warning(pos, msg("ignored in Scala 3"), WarningCategory.Scala3Migration) + warning(pos, msg("ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw)"), WarningCategory.Scala3Migration) else deprecationWarning(pos, msg("deprecated"), since="2.13.2") strVal = processed } } catch { case ue: StringContext.InvalidUnicodeEscapeException => - if (!currentRun.isScala3Cross) + if (!currentRun.sourceFeatures.unicodeEscapesRaw) syntaxError(offset + 3 + ue.index, ue.getMessage()) } @@ -1568,7 +1567,7 @@ trait Scanners extends ScannersCommon { case COMMA => "','" case CASECLASS => "case class" case CASEOBJECT => "case object" - case XMLSTART => "$XMLSTART$<" + case XMLSTART => s"$$XMLSTART$$<" case _ => (token2name get token) match { case Some(name) => "'" + name + "'" @@ -1793,10 +1792,10 @@ trait Scanners extends ScannersCommon { def insertRBrace(): List[BracePatch] = { def insert(bps: List[BracePair]): List[BracePatch] = bps match { case List() => patches - case (bp @ BracePair(loff, lindent, roff, rindent, nested)) :: bps1 => + case BracePair(loff, lindent, roff, rindent, nested) :: bps1 => if (lindent <= rindent) insert(bps1) else { -// println("patch inside "+bp+"/"+line(loff)+"/"+lineStart(line(loff))+"/"+lindent"/"+rindent)//DEBUG +// println("patch inside "+bps.head+"/"+line(loff)+"/"+lineStart(line(loff))+"/"+lindent"/"+rindent)//DEBUG val patches1 = insert(nested) if (patches1 ne patches) patches1 else { diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index a96034ffbc43..b9aeaa629b85 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,10 +13,11 @@ package scala.tools.nsc package ast.parser +import scala.annotation.unused import scala.collection.mutable -import symtab.Flags.MUTABLE import scala.reflect.internal.util.ListOfNil import scala.reflect.internal.util.StringOps.splitWhere +import symtab.Flags.MUTABLE /** This class builds instance of `Tree` that represent XML. * @@ -28,7 +29,7 @@ import scala.reflect.internal.util.StringOps.splitWhere * * @author Burak Emir */ -abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { +abstract class SymbolicXMLBuilder(@unused p: Parsers#Parser, @unused preserveWS: Boolean) { val global: Global import global._ @@ -176,8 +177,8 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { /** could optimize if args.length == 0, args.length == 1 AND args(0) is <: Node. */ def makeXMLseq(pos: Position, args: scala.collection.Seq[Tree]) = { - val buffer = ValDef(NoMods, _buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil)) - val applies = args filterNot isEmptyText map (t => Apply(Select(Ident(_buf), _plus), List(t))) + val buffer = atPos(pos)(ValDef(NoMods, _buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil))) + val applies = args.filterNot(isEmptyText).map(t => atPos(t.pos)(Apply(Select(Ident(_buf), _plus), List(t)))) atPos(pos)( gen.mkBlock(buffer :: applies.toList ::: List(Ident(_buf))) ) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala index 8f655ff68199..4183cc163715 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -38,12 +38,12 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse md.mods.isSynthetic || md.mods.isParamAccessor || nme.isConstructorName(md.name) - || (md.name containsName nme.ANON_CLASS_NAME) + || md.name.containsName(nme.ANON_CLASS_NAME) ) override def traverse(t: Tree): Unit = t match { case md: MemberDef if prune(md) => - case md @ PackageDef(_, stats) => traverseTrees(stats) + case PackageDef(_, stats) => traverseTrees(stats) case md: ImplDef => onMember(md) ; lower(traverseTrees(md.impl.body)) case md: ValOrDefDef => onMember(md) ; lower(traverse(md.rhs)) case _ => super.traverse(t) @@ -106,7 +106,7 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse unit.body = initialUnitBody(unit) if (settings.Ymemberpos.isSetByUser) - new MemberPosReporter(unit) show (style = settings.Ymemberpos.value) + new MemberPosReporter(unit).show(style = settings.Ymemberpos.value) } } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index c846cc55ec81..09a61d5680fd 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index b5c3c0abd269..8f0eb3c13e1d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -55,11 +55,6 @@ abstract class TreeBuilder { def makeSelfDef(name: TermName, tpt: Tree): ValDef = ValDef(Modifiers(PRIVATE), name, tpt, EmptyTree) - /** Tree for `od op`, start is start0 if od.pos is borked. */ - def makePostfixSelect(start: Int, end: Int, od: Tree, op: Name): Tree = { - atPos(r2p(start, end, end + op.length)) { Select(od, op.encode) }.updateAttachment(PostfixAttachment) - } - /** Create tree representing a while loop */ def makeWhile(startPos: Int, cond: Tree, body: Tree): Tree = { val lname = freshTermName(nme.WHILE_PREFIX) diff --git a/src/compiler/scala/tools/nsc/ast/parser/xml/MarkupParserCommon.scala b/src/compiler/scala/tools/nsc/ast/parser/xml/MarkupParserCommon.scala index 2ff9688761b6..158c1d4ec3d2 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/xml/MarkupParserCommon.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/xml/MarkupParserCommon.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala b/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala index 911ae51fee96..54dba43e83a1 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/xml/Utility.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala index bfd01ee3abde..7656eec9e704 100644 --- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala +++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/Platform.scala b/src/compiler/scala/tools/nsc/backend/Platform.scala index b732b821112d..c701ba581b8f 100644 --- a/src/compiler/scala/tools/nsc/backend/Platform.scala +++ b/src/compiler/scala/tools/nsc/backend/Platform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -41,7 +41,7 @@ trait Platform { * Tells whether a class with both a binary and a source representation * (found in classpath and in sourcepath) should be re-compiled. Behaves * on the JVM similar to javac, i.e. if the source file is newer than the classfile, - * a re-compile is triggered. On .NET by contrast classfiles always take precedence. + * a re-compile is triggered. */ def needCompile(bin: AbstractFile, src: AbstractFile): Boolean } diff --git a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala index 5a11272499ef..716a7e598dd6 100644 --- a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala +++ b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala index 25e25ec48d57..45bf38465b39 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 48ed602817ba..d6d858e85840 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -341,10 +341,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { generatedDest = jumpDest } - case app : Apply => + case app: Apply => generatedType = genApply(app, expectedType) - case app @ ApplyDynamic(qual, Literal(Constant(bootstrapMethodRef: Symbol)) :: staticAndDynamicArgs) => + case ApplyDynamic(qual, Literal(Constant(bootstrapMethodRef: Symbol)) :: staticAndDynamicArgs) => val numDynamicArgs = qual.symbol.info.params.length val (staticArgs, dynamicArgs) = staticAndDynamicArgs.splitAt(staticAndDynamicArgs.length - numDynamicArgs) val bootstrapDescriptor = staticHandleFromSymbol(bootstrapMethodRef) @@ -373,7 +373,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } } - case Select(Ident(nme.EMPTY_PACKAGE_NAME), module) => + case Select(Ident(nme.EMPTY_PACKAGE_NAME), _) => assert(tree.symbol.isModule, s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.pos}") genLoadModule(tree) @@ -381,7 +381,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { val sym = tree.symbol generatedType = symInfoTK(sym) val qualSafeToElide = treeInfo isQualifierSafeToElide qualifier - def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } } + def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree, drop = true) } } // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError, scala/bug#4283 def receiverClass = qualifier.tpe.typeSymbol if (sym.isModule) { @@ -564,7 +564,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { case Nil => // not an assertion: !shouldEmitCleanup (at least not yet, pendingCleanups() may still have to run, and reset `shouldEmitCleanup`. genLoadTo(expr, returnType, LoadDestination.Return) - case nextCleanup :: rest => + case nextCleanup :: _ => genLoad(expr, returnType) lineNumber(r) val saveReturnValue = (returnType != UNIT) @@ -665,7 +665,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { * elemKind = new BType(BType.ARRAY, arr.off + argsSize, arr.len - argsSize) * however the above does not enter a TypeName for each nested arrays in chrs. */ - for (i <- args.length until dims) elemKind = ArrayBType(elemKind) + for (_ <- args.length until dims) elemKind = ArrayBType(elemKind) } argsSize match { case 1 => bc newarray elemKind @@ -834,7 +834,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { var switchBlocks: List[Tuple2[asm.Label, Tree]] = Nil // collect switch blocks and their keys, but don't emit yet any switch-block. - for (caze @ CaseDef(pat, guard, body) <- tree.cases) { + for (CaseDef(pat, guard, body) <- tree.cases) { assert(guard == EmptyTree, guard) val switchBlockPoint = new asm.Label switchBlocks ::= ((switchBlockPoint, body)) @@ -1054,10 +1054,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } /* Emit code to Load the qualifier of `tree` on top of the stack. */ - def genLoadQualifier(tree: Tree): Unit = { + def genLoadQualifier(tree: Tree, drop: Boolean = false): Unit = { lineNumber(tree) tree match { - case Select(qualifier, _) => genLoad(qualifier) + case Select(qualifier, _) => genLoad(qualifier, if (drop) UNIT else tpeTK(qualifier)) case _ => abort(s"Unknown qualifier $tree") } } @@ -1098,7 +1098,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { if (!tree.symbol.isPackageClass) tree.symbol else tree.symbol.info.packageObject match { case NoSymbol => abort(s"scala/bug#5604: Cannot use package as value: $tree") - case s => abort(s"scala/bug#5604: found package class where package object expected: $tree") + case _ => abort(s"scala/bug#5604: found package class where package object expected: $tree") } ) lineNumber(tree) @@ -1242,7 +1242,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { recipe.append(s) } - case other => + case _ => totalArgSlots += elemSlots recipe.append(TagArg) val tpe = tpeTK(elem) @@ -1356,7 +1356,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { val result = ListBuffer[Tree]() def loop(tree: Tree): Unit = { tree match { - case Apply(fun@Select(larg, method), rarg :: Nil) + case Apply(fun@Select(larg, _), rarg :: Nil) if (isPrimitive(fun.symbol) && scalaPrimitives.getPrimitive(fun.symbol) == scalaPrimitives.CONCAT) => loop(larg) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 58b7622e1143..eecbe0dc5105 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,14 +15,13 @@ package tools.nsc package backend.jvm import scala.PartialFunction.cond -import scala.annotation.tailrec -import scala.tools.asm -import scala.tools.asm.{ClassWriter, Label} +import scala.annotation.{tailrec, unused} +import scala.tools.asm, asm.{ClassWriter, Label} import scala.tools.nsc.Reporting.WarningCategory import scala.tools.nsc.backend.jvm.BCodeHelpers.ScalaSigBytes import scala.tools.nsc.backend.jvm.BackendReporting._ import scala.tools.nsc.reporters.NoReporter -import scala.util.chaining.scalaUtilChainingOps +import scala.util.chaining._ /* * Traits encapsulating functionality to convert Scala AST Trees into ASM ClassNodes. @@ -266,7 +265,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic { /* * must-single-thread */ - def apply(sym: Symbol, csymCompUnit: CompilationUnit, mainClass: Option[String]): Boolean = sym.hasModuleFlag && { + def apply(sym: Symbol, @unused csymCompUnit: CompilationUnit, mainClass: Option[String]): Boolean = sym.hasModuleFlag && { val warn = mainClass.fold(true)(_ == sym.fullNameString) def warnBadMain(msg: String, pos: Position): Unit = if (warn) runReporting.warning(pos, s"""|not a valid main method for ${sym.fullName('.')}, @@ -429,7 +428,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic { * * must-single-thread */ - def getAnnotPickle(jclassName: String, sym: Symbol): Option[AnnotationInfo] = { + def getAnnotPickle(@unused jclassName: String, sym: Symbol): Option[AnnotationInfo] = { currentRun.symData get sym match { case Some(pickle) if !sym.isModuleClass => // pickles for module classes are in the companion / mirror class val scalaAnnot = { @@ -830,7 +829,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic { * * must-single-thread */ - def addForwarders(jclass: asm.ClassVisitor, jclassName: String, moduleClass: Symbol): Unit = { + def addForwarders(jclass: asm.ClassVisitor, @unused jclassName: String, moduleClass: Symbol): Unit = { assert(moduleClass.isModuleClass, moduleClass) val linkedClass = moduleClass.companionClass diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala index b56711f8d7ac..89d87386ba8e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -674,7 +674,7 @@ abstract class BCodeIdiomatic { * */ class LabelDefsFinder(rhs: Tree) extends InternalTraverser { - val result = mutable.AnyRefMap.empty[Tree, List[LabelDef]] + val result = mutable.HashMap.empty[Tree, List[LabelDef]] var acc: List[LabelDef] = Nil var directResult: List[LabelDef] = Nil diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala index 983e40d4ec08..b169e0e9d645 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,9 +14,10 @@ package scala.tools.nsc package backend package jvm +import scala.annotation.unused import scala.collection.{immutable, mutable} -import scala.tools.nsc.symtab._ import scala.tools.asm +import scala.tools.nsc.symtab._ import GenBCode._ import BackendReporting._ @@ -181,7 +182,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { /* * must-single-thread */ - private def initJClass(jclass: asm.ClassVisitor): Unit = { + private def initJClass(@unused jclass: asm.ClassVisitor): Unit = { val bType = classBTypeFromSymbol(claszSymbol) val superClass = bType.info.get.superClass.getOrElse(ObjectRef).internalName @@ -396,7 +397,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { */ object locals { - private val slots = mutable.AnyRefMap.empty[Symbol, Local] // (local-or-param-sym -> Local(BType, name, idx, isSynth)) + private val slots = mutable.HashMap.empty[Symbol, Local] // (local-or-param-sym -> Local(BType, name, idx, isSynth)) private var nxtIdx = -1 // next available index for local-var @@ -710,7 +711,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { * * TODO document, explain interplay with `fabricateStaticInit()` */ - private def appendToStaticCtor(dd: DefDef): Unit = { + private def appendToStaticCtor(@unused dd: DefDef): Unit = { def insertBefore( location: asm.tree.AbstractInsnNode, diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala index 56b6b17ffb99..ebffa98620a5 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala index 964ba2e5ef6c..2303edbb8fae 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromClassfile.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromClassfile.scala index fabaa259f4bc..ebc7c99d27bc 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromClassfile.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromClassfile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.nsc.backend.jvm -import scala.annotation.switch +import scala.annotation.{switch, unused} import scala.collection.mutable import scala.jdk.CollectionConverters._ import scala.tools.asm.Opcodes @@ -82,7 +82,7 @@ abstract class BTypesFromClassfile { } } - private def computeClassInfoFromClassNode(classNode: ClassNode, classBType: ClassBType): Right[Nothing, ClassInfo] = { + private def computeClassInfoFromClassNode(classNode: ClassNode, @unused classBType: ClassBType): Right[Nothing, ClassInfo] = { val superClass = classNode.superName match { case null => assert(classNode.name == ObjectRef.internalName, s"class with missing super type: ${classNode.name}") diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala index 4b5c7b3e13fa..7cce66038f97 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -643,7 +643,7 @@ abstract class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { def mirrorClassClassBType(moduleClassSym: Symbol): ClassBType = { assert(isTopLevelModuleClass(moduleClassSym), s"not a top-level module class: $moduleClassSym") val internalName = moduleClassSym.javaBinaryNameString.stripSuffix(nme.MODULE_SUFFIX_STRING) - ClassBType(internalName, moduleClassSym, fromSymbol = true) { (c: ClassBType, moduleClassSym) => + ClassBType(internalName, moduleClassSym, fromSymbol = true) { (_: ClassBType, moduleClassSym) => val shouldBeLazy = moduleClassSym.isJavaDefined || !currentRun.compiles(moduleClassSym) val nested = Lazy.withLockOrEager(shouldBeLazy, exitingPickler(memberClassesForInnerClassTable(moduleClassSym)) map classBTypeFromSymbol) Right(ClassInfo( diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala index 7b9ad0d99a12..69ebfc21c0bd 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -203,6 +203,9 @@ object BackendReporting { case SynchronizedMethod(_, _, _, _) => s"Method $calleeMethodSig cannot be inlined because it is synchronized." + case _: NoBytecode => + s"Method $calleeMethodSig cannot be inlined because it does not have any instructions, even though it is not abstract. The class may come from a signature jar file (such as a Bazel 'hjar')." + case StrictfpMismatch(_, _, _, _, callsiteClass, callsiteName, callsiteDesc) => s"""The callsite method ${BackendReporting.methodSignature(callsiteClass, callsiteName, callsiteDesc)} |does not have the same strictfp mode as the callee $calleeMethodSig. @@ -229,6 +232,7 @@ object BackendReporting { final case class MethodWithHandlerCalledOnNonEmptyStack(calleeDeclarationClass: InternalName, name: String, descriptor: String, annotatedInline: Boolean, callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning final case class SynchronizedMethod(calleeDeclarationClass: InternalName, name: String, descriptor: String, annotatedInline: Boolean) extends CannotInlineWarning + final case class NoBytecode(calleeDeclarationClass: InternalName, name: String, descriptor: String, annotatedInline: Boolean) extends CannotInlineWarning final case class StrictfpMismatch(calleeDeclarationClass: InternalName, name: String, descriptor: String, annotatedInline: Boolean, callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning case class ResultingMethodTooLarge(calleeDeclarationClass: InternalName, name: String, descriptor: String, annotatedInline: Boolean, diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BackendStats.scala b/src/compiler/scala/tools/nsc/backend/jvm/BackendStats.scala index 6388a41bd4b1..b0ee4f2e044d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BackendStats.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BackendStats.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/ClassNode1.java b/src/compiler/scala/tools/nsc/backend/jvm/ClassNode1.java index 5a4874d7d90e..0159edd7af54 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/ClassNode1.java +++ b/src/compiler/scala/tools/nsc/backend/jvm/ClassNode1.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/ClassfileWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/ClassfileWriters.scala index 5f9623735dd5..781d528a9762 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/ClassfileWriters.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/ClassfileWriters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -235,9 +235,9 @@ abstract class ClassfileWriters { } private final class DirEntryWriter(base: Path) extends FileWriter { + import scala.util.Properties.{isWin => isWindows} val builtPaths = new ConcurrentHashMap[Path, java.lang.Boolean]() val noAttributes = Array.empty[FileAttribute[_]] - private val isWindows = scala.util.Properties.isWin private def checkName(component: Path): Unit = if (isWindows) { val specials = raw"(?i)CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9]".r @@ -268,7 +268,7 @@ abstract class ClassfileWriters { checkName(filePath.getFileName()) } - // the common case is that we are are creating a new file, and on MS Windows the create and truncate is expensive + // the common case is that we are creating a new file, and on MS Windows the create and truncate is expensive // because there is not an options in the windows API that corresponds to this so the truncate is applied as a separate call // even if the file is new. // as this is rare, its best to always try to create a new file, and it that fails, then open with truncate if that fails diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CodeGen.scala b/src/compiler/scala/tools/nsc/backend/jvm/CodeGen.scala index 2765c063f17f..045916faeaab 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/CodeGen.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/CodeGen.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala index 98d293f855c9..95c50f184001 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -245,11 +245,11 @@ abstract class CoreBTypesFromSymbols[G <: Global] extends CoreBTypes { // Z -> MethodNameAndType(boxToBoolean,(Z)Ljava/lang/Boolean;) def srBoxesRuntimeBoxToMethods: Map[BType, MethodNameAndType] = _srBoxesRuntimeBoxToMethods.get - private[this] lazy val _srBoxesRuntimeBoxToMethods: LazyVar[Map[BType, MethodNameAndType]] = runLazy(srBoxesRuntimeMethods((primitive, boxed) => "boxTo" + boxed)) + private[this] lazy val _srBoxesRuntimeBoxToMethods: LazyVar[Map[BType, MethodNameAndType]] = runLazy(srBoxesRuntimeMethods((_, boxed) => "boxTo" + boxed)) // Z -> MethodNameAndType(unboxToBoolean,(Ljava/lang/Object;)Z) def srBoxesRuntimeUnboxToMethods: Map[BType, MethodNameAndType] = _srBoxesRuntimeUnboxToMethods.get - private[this] lazy val _srBoxesRuntimeUnboxToMethods: LazyVar[Map[BType, MethodNameAndType]] = runLazy(srBoxesRuntimeMethods((primitive, boxed) => "unboxTo" + primitive)) + private[this] lazy val _srBoxesRuntimeUnboxToMethods: LazyVar[Map[BType, MethodNameAndType]] = runLazy(srBoxesRuntimeMethods((primitive, _) => "unboxTo" + primitive)) private def singleParamOfClass(cls: Symbol) = (s: Symbol) => s.paramss match { case List(List(param)) => param.info.typeSymbol == cls diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala index 87414bbffb82..62e8c75c106a 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GeneratedClassHandler.scala b/src/compiler/scala/tools/nsc/backend/jvm/GeneratedClassHandler.scala index 945d9b539bca..a637192797a6 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GeneratedClassHandler.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GeneratedClassHandler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/LabelNode1.java b/src/compiler/scala/tools/nsc/backend/jvm/LabelNode1.java index b119ed90625a..5242dd5872bb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/LabelNode1.java +++ b/src/compiler/scala/tools/nsc/backend/jvm/LabelNode1.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/MethodNode1.java b/src/compiler/scala/tools/nsc/backend/jvm/MethodNode1.java index 0c8cfbd3a889..82babe00c31d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/MethodNode1.java +++ b/src/compiler/scala/tools/nsc/backend/jvm/MethodNode1.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/PerRunInit.scala b/src/compiler/scala/tools/nsc/backend/jvm/PerRunInit.scala index 89e6e7af6ae9..6147213165a8 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/PerRunInit.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/PerRunInit.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/PostProcessor.scala b/src/compiler/scala/tools/nsc/backend/jvm/PostProcessor.scala index beac14fea2df..29bbcd1d8638 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/PostProcessor.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/PostProcessor.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -18,10 +18,11 @@ import java.util.concurrent.ConcurrentHashMap import scala.collection.mutable import scala.reflect.internal.util.{NoPosition, Position} import scala.reflect.io.AbstractFile -import scala.tools.asm.ClassWriter +import scala.tools.asm.{ByteVector, ClassVisitor, ClassWriter, MethodVisitor, Opcodes} import scala.tools.asm.tree.ClassNode import scala.tools.nsc.backend.jvm.analysis.BackendUtils import scala.tools.nsc.backend.jvm.opt._ +import scala.util.control.NonFatal /** * Implements late stages of the backend that don't depend on a Global instance, i.e., @@ -77,6 +78,7 @@ abstract class PostProcessor extends PerRunInit { // TODO fail fast rather than continuing to write the rest of the class files? if (frontendAccess.compilerSettings.debug) ex.printStackTrace() backendReporting.error(NoPosition, s"Error while emitting $internalName\n${ex.getMessage}") + if (NonFatal(ex)) checkConformance(classNode) null } @@ -88,6 +90,37 @@ abstract class PostProcessor extends PerRunInit { } } + // Provide more useful messaging when class writing fails. -Xverify verifies always. + private def checkConformance(classNode: ClassNode): Unit = { + val visitor = new ClassVisitor(Opcodes.ASM9) { + override def visitMethod(access: Int, name: String, descriptor: String, signature: String, exceptions: Array[String]) = { + val site = s"Method $name" + checkString(site, "name")(name) + checkString(site, "descriptor")(descriptor) + checkString(site, "signature")(signature) + new MethodVisitor(Opcodes.ASM9) { + override def visitLdcInsn(value: Object): Unit = { + value match { + case value: String => + checkString(site, "String constant")(value) + case _ => + } + } + } + } + private final val max = 0xFFFF + private final val threshold = 0xFFFF / 6 // char never expands to more than 6 bytes + private def checkString(site: String, which: String)(s: String): Unit = if (s != null && s.length > threshold) { + def fail() = backendReporting.error(NoPosition, s"$site in class ${classNode.name} has a bad $which of length ${s.length}${ if (frontendAccess.compilerSettings.debug) s":\n$s" else "" }") + if (s.length > max) fail() + else + try new ByteVector(s.length).putUTF8(s) + catch { case _: IllegalArgumentException => fail() } + } + } + classNode.accept(visitor) + } + private def warnCaseInsensitiveOverwrite(clazz: GeneratedClass): Unit = { val name = clazz.classNode.name val lowercaseJavaClassName = name.toLowerCase diff --git a/src/compiler/scala/tools/nsc/backend/jvm/PostProcessorFrontendAccess.scala b/src/compiler/scala/tools/nsc/backend/jvm/PostProcessorFrontendAccess.scala index cce594a7fbe4..081ccd08a656 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/PostProcessorFrontendAccess.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/PostProcessorFrontendAccess.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/AliasingAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/AliasingAnalyzer.scala index 3b5fe32d4d01..2ace193be5cf 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/AliasingAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/AliasingAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -463,7 +463,7 @@ class AliasSet(var set: Object /*SmallBitSet | Array[Long]*/, var size: Int) { bsAdd(this, value) } } - case bits: Array[Long] => + case _: Array[Long] => bsAdd(this, value) } @@ -485,7 +485,7 @@ class AliasSet(var set: Object /*SmallBitSet | Array[Long]*/, var size: Int) { else if (value == s.c) { s.c = s.d; s.d = -1; size = 3 } else if (value == s.d) { s.d = -1; size = 3 } } - case bits: Array[Long] => + case _: Array[Long] => bsRemove(this, value) if (this.size == 4) this.set = bsToSmall(this.set.asInstanceOf[Array[Long]]) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/AsmAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/AsmAnalyzer.scala index 11a12062864d..8eed053541ad 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/AsmAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/AsmAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala index 8e9dea035eea..e83c8cef1b17 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -86,6 +86,9 @@ abstract class BackendUtils extends PerRunInit { case "20" => asm.Opcodes.V20 case "21" => asm.Opcodes.V21 case "22" => asm.Opcodes.V22 + case "23" => asm.Opcodes.V23 + case "24" => asm.Opcodes.V24 + case "25" => asm.Opcodes.V25 // to be continued... }) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala index f0c21f090269..b5da4522f923 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/InstructionStackEffect.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala index 81923fe80461..bea98549a151 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala index ab1c75cb5a0c..9a2316cdaa95 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -423,8 +423,8 @@ class ProdConsAnalyzer(methodNode: MethodNode, classInternalName: InternalName) res } - private val _initialProducersCache: mutable.AnyRefMap[(AbstractInsnNode, Int), Set[AbstractInsnNode]] = mutable.AnyRefMap.empty - private val _ultimateConsumersCache: mutable.AnyRefMap[(AbstractInsnNode, Int), Set[AbstractInsnNode]] = mutable.AnyRefMap.empty + private val _initialProducersCache: mutable.HashMap[(AbstractInsnNode, Int), Set[AbstractInsnNode]] = mutable.HashMap.empty + private val _ultimateConsumersCache: mutable.HashMap[(AbstractInsnNode, Int), Set[AbstractInsnNode]] = mutable.HashMap.empty } /** @@ -469,7 +469,9 @@ class InitialProducerSourceInterpreter extends SourceInterpreter(scala.tools.asm } override def newExceptionValue(tryCatchBlockNode: TryCatchBlockNode, handlerFrame: Frame[SourceValue], exceptionType: Type): SourceValue = { - val handlerStackTop = handlerFrame.stackTop + 1 // +1 because this value is about to be pushed onto `handlerFrame`. + // -1 to go from the number of locals to the (0-based) index of the last local + // +1 because this value is about to be pushed onto `handlerFrame` + val handlerStackTop = handlerFrame.getLocals - 1 + 1 new SourceValue(1, ExceptionProducer(tryCatchBlockNode.handler, handlerStackTop)) } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowAnalyzer.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowAnalyzer.scala index 160626b2e824..0fa174c63ab9 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/TypeFlowAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala index 9ba60e975c3a..b5b8f6e61795 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala index 227b52311bab..faa89a1ad68d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,7 +14,7 @@ package scala.tools.nsc package backend.jvm package opt -import scala.annotation.tailrec +import scala.annotation.{tailrec, unused} import scala.collection.AbstractIterator import scala.collection.mutable import scala.jdk.CollectionConverters._ @@ -767,7 +767,7 @@ abstract class BoxUnbox { } } - def checkRefConsumer(insn: AbstractInsnNode, kind: Ref, prodCons: ProdConsAnalyzer): Option[BoxConsumer] = insn match { + def checkRefConsumer(insn: AbstractInsnNode, kind: Ref, @unused prodCons: ProdConsAnalyzer): Option[BoxConsumer] = insn match { case fi: FieldInsnNode if fi.owner == kind.refClass && fi.name == "elem" => if (fi.getOpcode == GETFIELD) Some(StaticGetterOrInstanceRead(fi)) else if (fi.getOpcode == PUTFIELD) Some(StaticSetterOrInstanceWrite(fi)) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala index e21c3c19466f..9fc54055cb8f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -56,7 +56,8 @@ abstract class ByteCodeRepository extends PerRunInit { * Note - although this is typed a mutable.Map, individual simple get and put operations are threadsafe as the * underlying data structure is synchronized. */ - val parsedClasses: mutable.Map[InternalName, Either[ClassNotFound, ClassNode]] = recordPerRunCache(LruMap[InternalName, Either[ClassNotFound, ClassNode]](maxCacheSize, threadsafe = true)) + val parsedClasses: mutable.Map[InternalName, Either[ClassNotFound, ClassNode]] = + recordPerRunCache(FifoCache[InternalName, Either[ClassNotFound, ClassNode]](maxCacheSize, threadsafe = true)) /** * Contains the internal names of all classes that are defined in Java source files of the current diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala index 5b58d29ecd6b..fa45ab167870 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala index 999783f18d1e..0f57f7f628d7 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala index 7ea32da7723b..ac8615dbedd4 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala index 177c1c54a1bb..f3775c03a4ef 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/FifoCache.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/FifoCache.scala new file mode 100644 index 000000000000..887d5e63fd60 --- /dev/null +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/FifoCache.scala @@ -0,0 +1,56 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.tools.nsc.backend.jvm.opt + +import java.util.concurrent.{ConcurrentHashMap, ConcurrentLinkedQueue} +import java.util.{LinkedHashMap, Map => JMap} +import scala.collection.mutable +import scala.jdk.CollectionConverters._ + +object FifoCache { + def apply[K,V](maxSize: Int, threadsafe: Boolean): mutable.Map[K,V] = { + require(maxSize > 0) + if (threadsafe) new ConcFifoCache(maxSize) else new FifoCache[K, V](maxSize).asScala + } + + private class FifoCache[K, V](maxSize: Int) extends LinkedHashMap[K,V] { + override def removeEldestEntry(eldest: JMap.Entry[K, V]): Boolean = { + size() > maxSize + } + } + + private class ConcFifoCache[K, V](maxSize: Int) extends mutable.Map[K,V] { + private val cache: ConcurrentHashMap[K, V] = new ConcurrentHashMap() + private val queue: ConcurrentLinkedQueue[K] = new ConcurrentLinkedQueue() + + def get(key: K): Option[V] = Option(cache.get(key)) + + def subtractOne(key: K): this.type = { + cache.remove(key) + queue.remove(key) + this + } + + def addOne(elem: (K, V)): this.type = { + while (cache.size() >= maxSize) { + val oldest = queue.poll() + if (oldest != null) cache.remove(oldest) + } + queue.add(elem._1) + cache.put(elem._1, elem._2) + this + } + + def iterator: Iterator[(K, V)] = cache.entrySet.iterator.asScala.map(e => (e.getKey, e.getValue)) + } +} diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala index 06e8356cc6a0..c2a832ba5bf0 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index 34bb2c680c8d..a1cb4d09d826 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -217,7 +217,7 @@ abstract class Inliner { } val indentString = " " * indent this match { - case s @ InlineLogSuccess(r, sizeBefore, sizeAfter) => + case InlineLogSuccess(r, sizeBefore, sizeAfter) => s"${indentString}inlined ${calleeString(r)} (${r.logText}). Before: $sizeBefore ins, after: $sizeAfter ins." case InlineLogRewrite(closureInit, invocations) => @@ -1010,6 +1010,8 @@ abstract class Inliner { Some(StrictfpMismatch( calleeDeclarationClass.internalName, callee.name, callee.desc, callsite.isInlineAnnotated, callsiteClass.internalName, callsiteMethod.name, callsiteMethod.desc)) + } else if (callee.instructions.size == 0) { + Some(NoBytecode(calleeDeclarationClass.internalName, callee.name, callee.desc, callsite.isInlineAnnotated)) } else None } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala index de804a9479ba..fb094ed18331 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala index 5c62f560de57..1a03b1a83bd9 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -905,7 +905,7 @@ object LocalOptImpls { // Ensure the length of `renumber`. Unused variable indices are mapped to -1. val minLength = if (isWide) index + 2 else index + 1 - for (i <- renumber.length until minLength) renumber += -1 + for (_ <- renumber.length until minLength) renumber += -1 renumber(index) = index if (isWide) renumber(index + 1) = index @@ -965,7 +965,7 @@ object LocalOptImpls { @tailrec def isEmpty(node: AbstractInsnNode): Boolean = node.getNext match { case null => true - case l: LineNumberNode => true + case _: LineNumberNode => true case n if n.getOpcode >= 0 => false case n => isEmpty(n) } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LruMap.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LruMap.scala deleted file mode 100644 index d73e3a6c1a4a..000000000000 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LruMap.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Scala (https://www.scala-lang.org) - * - * Copyright EPFL and Lightbend, Inc. - * - * Licensed under Apache License 2.0 - * (http://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package scala.tools.nsc.backend.jvm.opt - -import scala.collection.mutable.Map -import scala.jdk.CollectionConverters._ -import java.util.{LinkedHashMap, Collections, Map => JMap} - -object LruMap{ - def apply[K,V](maxSize: Int, threadsafe: Boolean): Map[K,V] = { - require(maxSize > 0) - val basic = new LruMapImpl[K,V](maxSize) - val threaded = if (threadsafe) Collections.synchronizedMap(basic) else basic - - threaded.asScala - } - - private class LruMapImpl[K,V](maxSize: Int) extends LinkedHashMap[K,V] { - override def removeEldestEntry(eldest: JMap.Entry[K, V]): Boolean = { - size() > maxSize - } - } -} diff --git a/src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala b/src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala index c1d273d562e4..857f1220cee6 100644 --- a/src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala +++ b/src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/classpath/ClassPath.scala b/src/compiler/scala/tools/nsc/classpath/ClassPath.scala index 9de64fd4a7ad..ffbd6f850032 100644 --- a/src/compiler/scala/tools/nsc/classpath/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/classpath/ClassPath.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,6 +12,7 @@ package scala.tools.nsc.classpath +import scala.annotation.unused import scala.reflect.io.AbstractFile import scala.tools.nsc.util.ClassRepresentation @@ -78,10 +79,10 @@ private[nsc] case class PackageEntryImpl(name: String) extends PackageEntry private[nsc] trait NoSourcePaths { final def asSourcePathString: String = "" - final private[nsc] def sources(inPackage: PackageName): Seq[SourceFileEntry] = Seq.empty + final private[nsc] def sources(@unused inPackage: PackageName): Seq[SourceFileEntry] = Seq.empty } private[nsc] trait NoClassPaths { final def findClassFile(className: String): Option[AbstractFile] = None - private[nsc] final def classes(inPackage: PackageName): Seq[ClassFileEntry] = Seq.empty + private[nsc] final def classes(@unused inPackage: PackageName): Seq[ClassFileEntry] = Seq.empty } diff --git a/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala b/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala index 58e7147827e2..f463c9e8aa5a 100644 --- a/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala +++ b/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala index 15202e73b547..ab821e4e6752 100644 --- a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala +++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,6 +15,7 @@ package scala.tools.nsc.classpath import java.io.{Closeable, File} import java.net.{URI, URL} import java.nio.file._ +import java.util.Collections import scala.jdk.CollectionConverters._ import scala.reflect.internal.JDK9Reflectors @@ -137,9 +138,9 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo } object JrtClassPath { - private val jrtClassPathCache = new FileBasedCache[Unit, JrtClassPath]() + private val jrtClassPathCache = new FileBasedCache[Option[String], JrtClassPath]() private val ctSymClassPathCache = new FileBasedCache[String, CtSymClassPath]() - def apply(release: Option[String], unsafe: Option[List[String]], closeableRegistry: CloseableRegistry): List[ClassPath] = + def apply(release: Option[String], systemPath: Option[String], unsafe: Option[List[String]], closeableRegistry: CloseableRegistry): List[ClassPath] = if (!isJavaAtLeast("9")) Nil else { // TODO escalate errors once we're sure they are fatal @@ -155,14 +156,14 @@ object JrtClassPath { val ct = createCt(version, closeableRegistry) unsafe match { case Some(pkgs) if pkgs.nonEmpty => - createJrt(closeableRegistry) match { + createJrt(systemPath, closeableRegistry) match { case Nil => ct case jrts => ct.appended(new FilteringJrtClassPath(jrts.head, pkgs: _*)) } case _ => ct } case _ => - createJrt(closeableRegistry) + createJrt(systemPath, closeableRegistry) } } private def createCt(v: String, closeableRegistry: CloseableRegistry): List[ClassPath] = @@ -176,10 +177,15 @@ object JrtClassPath { } catch { case NonFatal(_) => Nil } - private def createJrt(closeableRegistry: CloseableRegistry): List[JrtClassPath] = + private def createJrt(systemPath: Option[String], closeableRegistry: CloseableRegistry): List[JrtClassPath] = try { - val fs = FileSystems.getFileSystem(URI.create("jrt:/")) - val classPath = jrtClassPathCache.getOrCreate((), Nil, () => new JrtClassPath(fs), closeableRegistry, checkStamps = false) + val classPath = jrtClassPathCache.getOrCreate(systemPath, Nil, () => { + val fs = systemPath match { + case Some(javaHome) => FileSystems.newFileSystem(URI.create("jrt:/"), Collections.singletonMap("java.home", javaHome)) + case None => FileSystems.getFileSystem(URI.create("jrt:/")) + } + new JrtClassPath(fs, systemPath.isDefined) + }, closeableRegistry, checkStamps = false) List(classPath) } catch { case _: ProviderNotFoundException | _: FileSystemNotFoundException => Nil @@ -207,7 +213,7 @@ final class FilteringJrtClassPath(delegate: JrtClassPath, allowed: String*) exte * * The implementation assumes that no classes exist in the empty package. */ -final class JrtClassPath(fs: FileSystem) extends ClassPath with NoSourcePaths { +final class JrtClassPath(fs: FileSystem, closeFS: Boolean) extends ClassPath with NoSourcePaths with Closeable { type F = Path private val dir: Path = fs.getPath("/packages") @@ -253,6 +259,9 @@ final class JrtClassPath(fs: FileSystem) extends ClassPath with NoSourcePaths { }.take(1).toList.headOption } } + + def close(): Unit = + if (closeFS) fs.close() } /** @@ -274,7 +283,7 @@ final class CtSymClassPath(ctSym: java.nio.file.Path, release: Int) extends Clas // e.g. "java.lang" -> Seq(/876/java/lang, /87/java/lang, /8/java/lang)) private val packageIndex: scala.collection.Map[String, scala.collection.Seq[Path]] = { - val index = collection.mutable.AnyRefMap[String, collection.mutable.ListBuffer[Path]]() + val index = collection.mutable.HashMap[String, collection.mutable.ListBuffer[Path]]() val isJava12OrHigher = isJavaAtLeast("12") rootsForRelease.foreach(root => Files.walk(root).iterator().asScala.filter(Files.isDirectory(_)).foreach { p => val moduleNamePathElementCount = if (isJava12OrHigher) 1 else 0 diff --git a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala index fa3a5faf0318..d47c5db08c4c 100644 --- a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala +++ b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala b/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala index c589bcc6598a..dcb6eced0372 100644 --- a/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala +++ b/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala index 5896d78bf7e6..ca895f6c0862 100644 --- a/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala +++ b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala index 5ec8cfbc6aae..43a24e0f4d26 100644 --- a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala +++ b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -252,7 +252,7 @@ final class FileBasedCache[K, T] { if (disableCache) Left("caching is disabled due to a policy setting") else if (!checkStamps) Right(paths) else { - val nonJarZips = urlsAndFiles.filter { case (url, file) => file == null || !Jar.isJarOrZip(file.file) } + val nonJarZips = urlsAndFiles.filter { case (_, file) => file == null || !Jar.isJarOrZip(file.file) } if (nonJarZips.nonEmpty) Left(s"caching is disabled because of the following classpath elements: ${nonJarZips.map(_._1).mkString(", ")}.") else Right(paths) } @@ -267,7 +267,7 @@ final class FileBasedCache[K, T] { val fileKey = attrs.fileKey() Stamp(lastModified, attrs.size(), if (fileKey == null) NoFileKey else fileKey) } catch { - case ex: java.nio.file.NoSuchFileException => + case _: java.nio.file.NoSuchFileException => // Dummy stamp for (currently) non-existent file. Stamp(FileTime.fromMillis(0), -1, new Object) } diff --git a/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala b/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala index ccfefefbd053..e6f9b6cc717a 100644 --- a/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala +++ b/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/fsc/CompileClient.scala b/src/compiler/scala/tools/nsc/fsc/CompileClient.scala index bb162e68ca3e..00bea3d0ddab 100644 --- a/src/compiler/scala/tools/nsc/fsc/CompileClient.scala +++ b/src/compiler/scala/tools/nsc/fsc/CompileClient.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/fsc/CompileServer.scala b/src/compiler/scala/tools/nsc/fsc/CompileServer.scala index 16e36f894657..8a49b7eff6d6 100644 --- a/src/compiler/scala/tools/nsc/fsc/CompileServer.scala +++ b/src/compiler/scala/tools/nsc/fsc/CompileServer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -152,7 +152,7 @@ class StandardCompileServer(fixPort: Int = 0) extends SocketServer(fixPort) { val c = compiler try new c.Run() compile command.files catch { - case ex @ FatalError(msg) => + case FatalError(msg) => reporter.error(null, "fatal error: " + msg) clearCompiler() case ex: Throwable => diff --git a/src/compiler/scala/tools/nsc/fsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/fsc/CompileSocket.scala index c77ae98b9bb6..b64f09567620 100644 --- a/src/compiler/scala/tools/nsc/fsc/CompileSocket.scala +++ b/src/compiler/scala/tools/nsc/fsc/CompileSocket.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -105,7 +105,7 @@ class CompileSocket extends CompileOutputCommon { if (portsDir.list.toList.exists(_.name == fixPort.toString)) fixPort else -1 } else portsDir.list.toList match { case Nil => -1 - case x :: xs => try x.name.toInt catch { + case x :: _ => try x.name.toInt catch { case e: Exception => x.delete() ; throw e } } @@ -161,8 +161,8 @@ class CompileSocket extends CompileOutputCommon { @tailrec def getsock(attempts: Int): Option[Socket] = attempts match { - case 0 => warn("Unable to establish connection to compilation daemon") ; None - case num => + case 0 => warn("Unable to establish connection to compilation daemon") ; None + case _ => val port = if (create) getPort(vmArgs) else pollPort() if (port < 0) return None diff --git a/src/compiler/scala/tools/nsc/fsc/FscSettings.scala b/src/compiler/scala/tools/nsc/fsc/FscSettings.scala index 1696b4cea88d..6261c0d00208 100644 --- a/src/compiler/scala/tools/nsc/fsc/FscSettings.scala +++ b/src/compiler/scala/tools/nsc/fsc/FscSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/fsc/OfflineCompilerCommand.scala b/src/compiler/scala/tools/nsc/fsc/OfflineCompilerCommand.scala index 2d950c8d15d3..428bc8209ab9 100644 --- a/src/compiler/scala/tools/nsc/fsc/OfflineCompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/fsc/OfflineCompilerCommand.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/fsc/ResidentScriptRunner.scala b/src/compiler/scala/tools/nsc/fsc/ResidentScriptRunner.scala index 03b715002196..b32503b0523c 100644 --- a/src/compiler/scala/tools/nsc/fsc/ResidentScriptRunner.scala +++ b/src/compiler/scala/tools/nsc/fsc/ResidentScriptRunner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,6 +13,7 @@ package scala.tools.nsc package fsc +import scala.annotation.unused import scala.reflect.io.Path import scala.util.control.NonFatal @@ -38,7 +39,7 @@ class ResidentScriptRunner(settings: GenericRunnerSettings) extends AbstractScri } } -final class DaemonKiller(settings: GenericRunnerSettings) extends ScriptRunner { +final class DaemonKiller(@unused settings: GenericRunnerSettings) extends ScriptRunner { def runScript(script: String, scriptArgs: List[String]) = shutdownDaemon() def runScriptText(script: String, scriptArgs: List[String]) = shutdownDaemon() diff --git a/src/compiler/scala/tools/nsc/fsc/Socket.scala b/src/compiler/scala/tools/nsc/fsc/Socket.scala index e122faaa0b52..3636c02632bd 100644 --- a/src/compiler/scala/tools/nsc/fsc/Socket.scala +++ b/src/compiler/scala/tools/nsc/fsc/Socket.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/fsc/SocketServer.scala b/src/compiler/scala/tools/nsc/fsc/SocketServer.scala index 8a0c515b794d..cc3c3b09b6c4 100644 --- a/src/compiler/scala/tools/nsc/fsc/SocketServer.scala +++ b/src/compiler/scala/tools/nsc/fsc/SocketServer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala index 6e25ade030a6..8503d5f4a802 100644 --- a/src/compiler/scala/tools/nsc/io/Jar.scala +++ b/src/compiler/scala/tools/nsc/io/Jar.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/io/SourceReader.scala b/src/compiler/scala/tools/nsc/io/SourceReader.scala index ae481f8c3ce4..082fb6af5261 100644 --- a/src/compiler/scala/tools/nsc/io/SourceReader.scala +++ b/src/compiler/scala/tools/nsc/io/SourceReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala index 3a0502ae6169..aa88275dcec4 100644 --- a/src/compiler/scala/tools/nsc/io/package.scala +++ b/src/compiler/scala/tools/nsc/io/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index f54ce5feca93..be88aa4207e4 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -297,7 +297,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { if (in.token == FINAL) in.nextToken() if (in.token == IDENTIFIER) { var t = typeArgs(atPos(in.currentPos)(Ident(ident()))) - // typeSelect generates Select nodes is the lhs is an Ident or Select, + // typeSelect generates Select nodes if the lhs is an Ident or Select, // SelectFromTypeTree otherwise. See #3567. // Select nodes can be later // converted in the typechecker to SelectFromTypeTree if the class @@ -306,8 +306,11 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { case Ident(_) | Select(_, _) => Select(t, name) case _ => SelectFromTypeTree(t, name.toTypeName) } + if (in.token == DOT) + t.updateAttachment(RootSelection) while (in.token == DOT) { in.nextToken() + annotations() // TODO: fix scala/bug#9883 (JSR 308) t = typeArgs(atPos(in.currentPos)(typeSelect(t, ident()))) } convertToTypeId(t) @@ -375,7 +378,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { * // We only support a subset of the Java syntax that can form constant expressions. * // https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.29 * // - * // Luckily, we can just parse matching `(` and `)` to find our way to the end of the the argument list. + * // Luckily, we can just parse matching `(` and `)` to find our way to the end of the argument list. * // and drop the arguments until we implement full support for Java constant expressions * // * ConditionalExpressionSubset := Literal @@ -387,7 +390,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { * ElementValueList ::= ElementValue {`,` ElementValue} */ def annotation(): Tree = { - object LiteralK { def unapply(token: Token) = tryLiteral() } + object LiteralK { def unapply(@unused token: Token) = tryLiteral() } def elementValue(): Tree = in.token match { case LiteralK(k) => in.nextToken(); atPos(in.currentPos)(Literal(k)) @@ -445,16 +448,16 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { } } - def modifiers(inInterface: Boolean): Modifiers = { + def modifiers(inInterface: Boolean, annots0: List[Tree] = Nil): Modifiers = { var flags: Long = Flags.JAVA // assumed true unless we see public/private/protected var isPackageAccess = true - var annots: List[Tree] = Nil + var annots: List[Tree] = annots0 def addAnnot(sym: Symbol) = annots :+= New(sym.tpe) while (true) { in.token match { - case AT if (in.lookaheadToken != INTERFACE) => + case AT if in.lookaheadToken != INTERFACE => in.nextToken() val annot = annotation() if (annot.nonEmpty) annots :+= annot @@ -871,17 +874,12 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { val interfaces = interfacesOpt() val (statics, body) = typeBody(RECORD) - // Generate accessors, if not already manually specified - var generateAccessors = header - .view - .map { case ValDef(mods, name, tpt, _) => (name, (tpt, mods.annotations)) } - .toMap - for (DefDef(_, name, List(), List(params), _, _) <- body if generateAccessors.contains(name) && params.isEmpty) - generateAccessors -= name - - val accessors = generateAccessors - .map { case (name, (tpt, annots)) => - DefDef(Modifiers(Flags.JAVA) withAnnotations annots, name, List(), List(), tpt.duplicate, blankExpr) + // Generate accessors, if not already explicitly specified. Record bodies tend to be trivial. + val existing = body.iterator.collect { case DefDef(_, name, Nil, ListOfNil, _, _) => name }.toSet + val accessors = header.iterator + .collect { + case ValDef(mods, name, tpt, _) if !existing(name) => + DefDef(Modifiers(Flags.JAVA).withAnnotations(mods.annotations), name, tparams = Nil, vparamss = ListOfNil, tpt.duplicate, blankExpr) } .toList @@ -1091,28 +1089,34 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { else Some(Constant(l)) } - /** CompilationUnit ::= [package QualId semi] TopStatSeq + /** CompilationUnit ::= [[Annotation] package QualId semi] {Import} {TypeDecl} //TopStatSeq */ def compilationUnit(): Tree = { + val buf = ListBuffer.empty[Tree] var pos = in.currentPos + val leadingAnnots = if (in.token == AT) annotations() else Nil val pkg: RefTree = - if (in.token == AT || in.token == PACKAGE) { - annotations() // TODO: put these somewhere? - pos = in.currentPos + if (in.token == PACKAGE) { + if (!leadingAnnots.isEmpty) { // TODO: put these somewhere? + //if (unit.source.file.name != "package-info.java") + // syntaxError(pos, "package annotations must be in file package-info.java") + pos = in.currentPos + } accept(PACKAGE) - val pkg = qualId().asInstanceOf[RefTree] - accept(SEMI) - pkg - } else { + qualId().asInstanceOf[RefTree].tap(_ => accept(SEMI)) + } + else { + if (!leadingAnnots.isEmpty) + buf ++= typeDecl(modifiers(inInterface = false, annots0 = leadingAnnots)) Ident(nme.EMPTY_PACKAGE_NAME) } thisPackageName = gen.convertToTypeName(pkg) match { case Some(t) => t.name.toTypeName case _ => tpnme.EMPTY } - val buf = new ListBuffer[Tree] - while (in.token == IMPORT) - buf ++= importDecl() + if (buf.isEmpty) + while (in.token == IMPORT) + buf ++= importDecl() while (in.token != EOF && in.token != RBRACE) { while (in.token == SEMI) in.nextToken() if (in.token != EOF) diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index 131db5feac03..a7341dc228d5 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/javac/JavaTokens.scala b/src/compiler/scala/tools/nsc/javac/JavaTokens.scala index 66fcdf7c069c..6f296bc9e672 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaTokens.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaTokens.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/package.scala b/src/compiler/scala/tools/nsc/package.scala index 10c2a9ac9af7..0326aba538ac 100644 --- a/src/compiler/scala/tools/nsc/package.scala +++ b/src/compiler/scala/tools/nsc/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/plugins/OutputFileWriter.scala b/src/compiler/scala/tools/nsc/plugins/OutputFileWriter.scala index ce19a22275a4..5a86eeef433b 100644 --- a/src/compiler/scala/tools/nsc/plugins/OutputFileWriter.scala +++ b/src/compiler/scala/tools/nsc/plugins/OutputFileWriter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala index 5588f1c8ff6a..9ba109da6c5f 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala b/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala index 3b8d7e290f35..989bab940ffa 100644 --- a/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala +++ b/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala b/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala index 9eface4a4b23..e31a1cc269f2 100644 --- a/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala +++ b/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala index 81a07cdd9e52..6f79043e6330 100644 --- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala +++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -97,7 +97,7 @@ trait Plugins { global: Global => val cache = pluginClassLoadersCache val checkStamps = policy == settings.CachePolicy.LastModified.name cache.checkCacheability(classpath.map(_.toURL), checkStamps, disableCache) match { - case Left(msg) => + case Left(_) => val loader = newLoader() closeableRegistry.registerCloseable(loader) loader diff --git a/src/compiler/scala/tools/nsc/profile/ExtendedThreadMxBean.java b/src/compiler/scala/tools/nsc/profile/ExtendedThreadMxBean.java index f580e16ba496..5409a19f280a 100644 --- a/src/compiler/scala/tools/nsc/profile/ExtendedThreadMxBean.java +++ b/src/compiler/scala/tools/nsc/profile/ExtendedThreadMxBean.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/profile/ExternalToolHook.java b/src/compiler/scala/tools/nsc/profile/ExternalToolHook.java index b8ee01090407..e89231f63e2e 100644 --- a/src/compiler/scala/tools/nsc/profile/ExternalToolHook.java +++ b/src/compiler/scala/tools/nsc/profile/ExternalToolHook.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/profile/Profiler.scala b/src/compiler/scala/tools/nsc/profile/Profiler.scala index 9b9e67e1a965..eca33695cd86 100644 --- a/src/compiler/scala/tools/nsc/profile/Profiler.scala +++ b/src/compiler/scala/tools/nsc/profile/Profiler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -22,7 +22,7 @@ import java.util.concurrent.atomic.AtomicInteger import javax.management.openmbean.CompositeData import javax.management.{Notification, NotificationEmitter, NotificationListener} -import scala.annotation.nowarn +import scala.annotation.{nowarn, unused} import scala.collection.mutable.ArrayBuffer import scala.reflect.internal.util.ChromeTrace import scala.reflect.io.AbstractFile @@ -195,7 +195,7 @@ private [profile] class RealProfiler(reporter : ProfileReporter, val settings: S //we may miss a GC event if gc is occurring as we call this RealProfiler.gcMx foreach { case emitter: NotificationEmitter => emitter.removeNotificationListener(this) - case gc => + case _ => } reporter.close(this) if (chromeTrace != null) { @@ -335,13 +335,12 @@ private [profile] class RealProfiler(reporter : ProfileReporter, val settings: S } } - private def completionName(root: Global#Symbol, associatedFile: AbstractFile): String = { + private def completionName(root: Global#Symbol, @unused associatedFile: AbstractFile): String = if (root.hasPackageFlag || root.isTopLevel) root.javaBinaryNameString else { val enclosing = root.enclosingTopLevelClass enclosing.javaBinaryNameString + "::" + root.rawname.toString } - } } object EventType extends Enumeration { diff --git a/src/compiler/scala/tools/nsc/profile/ProfilerPlugin.scala b/src/compiler/scala/tools/nsc/profile/ProfilerPlugin.scala index f0f37f9b84a3..4c830d8ff214 100644 --- a/src/compiler/scala/tools/nsc/profile/ProfilerPlugin.scala +++ b/src/compiler/scala/tools/nsc/profile/ProfilerPlugin.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/profile/ThreadPoolFactory.scala b/src/compiler/scala/tools/nsc/profile/ThreadPoolFactory.scala index c9b23bb95fff..b8d5486de873 100644 --- a/src/compiler/scala/tools/nsc/profile/ThreadPoolFactory.scala +++ b/src/compiler/scala/tools/nsc/profile/ThreadPoolFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,6 +16,7 @@ import java.util.concurrent.ThreadPoolExecutor.AbortPolicy import java.util.concurrent._ import java.util.concurrent.atomic.AtomicInteger +import scala.annotation._ import scala.tools.nsc.{Global, Phase} sealed trait ThreadPoolFactory { @@ -44,7 +45,7 @@ object ThreadPoolFactory { private def childGroup(name: String) = new ThreadGroup(baseGroup, name) // Invoked when a new `Worker` is created, see `CommonThreadFactory.newThread` - protected def wrapWorker(worker: Runnable, shortId: String): Runnable = worker + protected def wrapWorker(worker: Runnable, @unused shortId: String): Runnable = worker protected final class CommonThreadFactory( shortId: String, diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala index ce0bd3186389..490e3d505b03 100644 --- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -26,7 +26,7 @@ class ConsoleReporter(val settings: Settings, val reader: BufferedReader, val wr override def finish(): Unit = { import reflect.internal.util.StringOps.countElementsAsString - if (!settings.nowarn.value && hasWarnings) + if (hasWarnings && !settings.nowarn.value) writer.println(countElementsAsString(warningCount, WARNING.toString.toLowerCase)) if (hasErrors) writer.println(countElementsAsString(errorCount, ERROR.toString.toLowerCase)) diff --git a/src/compiler/scala/tools/nsc/reporters/ForwardingReporter.scala b/src/compiler/scala/tools/nsc/reporters/ForwardingReporter.scala index 61a7751c737b..1529893b39e1 100644 --- a/src/compiler/scala/tools/nsc/reporters/ForwardingReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/ForwardingReporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/reporters/NoReporter.scala b/src/compiler/scala/tools/nsc/reporters/NoReporter.scala index 95bec3701ef6..73af7d1ee729 100644 --- a/src/compiler/scala/tools/nsc/reporters/NoReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/NoReporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/reporters/PrintReporter.scala b/src/compiler/scala/tools/nsc/reporters/PrintReporter.scala index 3d7a0175d9e3..af0306ecef2b 100644 --- a/src/compiler/scala/tools/nsc/reporters/PrintReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/PrintReporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala index aa8cd85c8060..a8bcb6e93305 100644 --- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -60,7 +60,6 @@ object Reporter { /** The reporter used in a Global instance. * * It filters messages based on - * - settings.nowarn * - settings.maxerrs / settings.maxwarns * - positions (only one error at a position, no duplicate messages on a position) */ diff --git a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala index 07d3545e3c2f..1fa79cd19a93 100644 --- a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -43,6 +43,6 @@ class StoreReporter(val settings: Settings) extends FilteringReporter { } object StoreReporter { case class Info(pos: Position, msg: String, severity: Severity, actions: List[CodeAction]) { - override def toString: String = s"pos: $pos $msg $severity${if (actions.isEmpty) "" else " " + actions}" + override def toString: String = s"pos: $pos $msg $severity${if (actions.isEmpty) "" else actions}" } } diff --git a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala index 72b3fbdc7d29..7f56cdcb2144 100644 --- a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 35ca94407aad..1cd44c846d15 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -212,11 +212,11 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) add(new IntSetting(name, descr, default, range, parser)) def MultiStringSetting(name: String, arg: String, descr: String, default: List[String] = Nil, helpText: Option[String] = None, prepend: Boolean = false) = add(new MultiStringSetting(name, arg, descr, default, helpText, prepend)) - def MultiChoiceSetting[E <: MultiChoiceEnumeration](name: String, helpArg: String, descr: String, domain: E, default: Option[List[String]] = None) = - add(new MultiChoiceSetting[E](name, helpArg, descr, domain, default)) + def MultiChoiceSetting[E <: MultiChoiceEnumeration](name: String, helpArg: String, descr: String, domain: E, default: Option[List[String]] = None, helpText: Option[String] = None) = + add(new MultiChoiceSetting[E](name, helpArg, descr, domain, default, helpText)) def OutputSetting(default: String) = add(new OutputSetting(default)) def PhasesSetting(name: String, descr: String, default: String = "") = add(new PhasesSetting(name, descr, default)) - def StringSetting(name: String, arg: String, descr: String, default: String, helpText: Option[String] = None) = add(new StringSetting(name, arg, descr, default, helpText)) + def StringSetting(name: String, arg: String, descr: String, default: String = "", helpText: Option[String] = None) = add(new StringSetting(name, arg, descr, default, helpText)) def ScalaVersionSetting(name: String, arg: String, descr: String, initial: ScalaVersion, default: Option[ScalaVersion] = None, helpText: Option[String] = None) = add(new ScalaVersionSetting(name, arg, descr, initial, default, helpText)) def PathSetting(name: String, descr: String, default: String): PathSetting = { @@ -286,14 +286,11 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) /** Return the output directory for the given file. */ - def outputDirFor(src: AbstractFile): AbstractFile = { - def isBelow(srcDir: AbstractFile, outDir: AbstractFile) = src.path.startsWith(srcDir.path) - - singleOutDir.getOrElse(outputs.find((isBelow _).tupled) match { + def outputDirFor(src: AbstractFile): AbstractFile = + singleOutDir.getOrElse(outputs.find { case (srcDir, _) => src.path.startsWith(srcDir.path) } match { case Some((_, d)) => d case _ => throw new FatalError(s"Could not find an output directory for ${src.path} in ${outputs}") }) - } /** Return the source file path(s) which correspond to the given * classfile path and SourceFile attribute value, subject to the @@ -312,19 +309,16 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) * output directory there will be two or more candidate source file * paths. */ - def srcFilesFor(classFile : AbstractFile, srcPath : String) : List[AbstractFile] = { - def isBelow(srcDir: AbstractFile, outDir: AbstractFile) = classFile.path.startsWith(outDir.path) - + def srcFilesFor(classFile : AbstractFile, srcPath : String) : List[AbstractFile] = singleOutDir match { case Some(_: VirtualDirectory | _: io.ZipArchive) => Nil case Some(d) => List(d.lookupPathUnchecked(srcPath, directory = false)) case None => - (outputs filter (isBelow _).tupled) match { + outputs.filter { case (_, outDir) => classFile.path.startsWith(outDir.path) } match { case Nil => Nil case matches => matches.map(_._1.lookupPathUnchecked(srcPath, directory = false)) } } - } } /** A base class for settings of all types. @@ -333,7 +327,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) abstract class Setting(val name: String, val helpDescription: String) extends AbsSetting with SettingValue { /** Will be called after this Setting is set for any extra work. */ - private[this] var _postSetHook: this.type => Unit = (x: this.type) => () + private[this] var _postSetHook: this.type => Unit = (_: this.type) => () override def postSetHook(): Unit = _postSetHook(this) def withPostSetHook(f: this.type => Unit): this.type = { _postSetHook = f ; this } @@ -355,6 +349,8 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) private[this] var _deprecationMessage: Option[String] = None override def deprecationMessage = _deprecationMessage def withDeprecationMessage(msg: String): this.type = { _deprecationMessage = Some(msg) ; this } + + def reset(): Unit } /** A setting represented by an integer. */ @@ -419,6 +415,8 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) else List(name, value.toString) withHelpSyntax(s"$name ") + + override def reset() = v = default } /** A setting that is a boolean flag, with default as specified. */ @@ -443,6 +441,10 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) } else errorAndValue(s"'$x' is not a valid choice for '$name'", None) case _ => errorAndValue(s"'$name' accepts only one boolean value", None) } + override def reset() = { + v = default + setByUser = false + } } /** A special setting for accumulating arguments like -Dfoo=bar. */ @@ -464,6 +466,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) def tryToSetColon(args: List[String]): Option[ResultOfTryToSet] = errorAndValue(s"bad argument for $name", None) override def respondsTo(token: String) = token startsWith prefix def unparse: List[String] = value + override def reset() = v = Nil } /** A setting represented by a string, (`default` unless set) */ @@ -495,6 +498,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) override def isHelping: Boolean = sawHelp override def help = helpText.get + override def reset() = v = default } /** A setting represented by a Scala version. @@ -536,6 +540,8 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) override def help = helpText.get withHelpSyntax(s"${name}:<${arg}>") + + override def reset() = v = initial } class PathSetting private[nsc]( @@ -555,10 +561,11 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) super.value, appendPath.value ) + override def reset() = () } /** Set the output directory for all sources. */ - class OutputSetting private[nsc](default: String) extends StringSetting("-d", "directory|jar", "destination for generated classfiles.", default, None) + class OutputSetting private[nsc](default: String) extends StringSetting("-d", "directory|jar", "Destination for generated artifacts.", default, None) /** * Each [[MultiChoiceSetting]] takes a MultiChoiceEnumeration as domain. The enumeration may @@ -609,7 +616,8 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) val helpArg: String, descr: String, val domain: E, - val default: Option[List[String]] + val default: Option[List[String]], + val helpText: Option[String] ) extends Setting(name, descr) with Clearable { withHelpSyntax(s"$name:<${helpArg}s>") @@ -700,7 +708,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) } def tryToSet(args: List[String]) = tryToSetArgs(args, halting = true) - def tryToSetColon(args: List[String]) = tryToSetArgs(args, halting = false) + def tryToSetColon(args: List[String]) = tryToSetArgs(args, halting = false) override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide /** Try to set args, handling "help" and default. @@ -780,7 +788,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) case _ => default } val orelse = verboseDefault.map(_.mkString(f"%nDefault: ", ", ", f"%n")).getOrElse("") - choices.zipAll(descriptions, "", "").map(describe).mkString(f"${descr}%n", f"%n", orelse) + choices.zipAll(descriptions, "", "").map(describe).mkString(f"${helpText.getOrElse(descr)}%n", f"%n", orelse) } def clear(): Unit = { @@ -793,6 +801,7 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) } def unparse: List[String] = value.toList.map(s => s"$name:$s") def contains(s: String) = domain.values.find(_.toString == s).exists(value.contains) + override def reset() = clear() } /** A setting that accumulates all strings supplied to it, @@ -817,17 +826,17 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) @tailrec def loop(seen: List[String], args: List[String]): (List[String], List[String]) = args match { case Optionlike() :: _ if halting => (seen, args) - case "help" :: rest if helpText.isDefined => sawHelp = true ; loop(seen, rest) - case head :: rest => loop(head :: seen, rest) + case "help" :: args if helpText.isDefined => sawHelp = true; loop(seen, args) + case head :: args => loop(head :: seen, args) case Nil => (seen, Nil) } val (seen, rest) = loop(Nil, args) - if (prepend) value = value.prependedAll(seen.reverse) + if (prepend) value = value.prependedAll(seen) else value = value.appendedAll(seen.reverse) Some(rest) } def tryToSet(args: List[String]) = tryToSetArgs(args, halting = true) - def tryToSetColon(args: List[String]) = tryToSetArgs(args, halting = false) + def tryToSetColon(args: List[String]) = tryToSetArgs(args, halting = false) override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide def clear(): Unit = (v = Nil) @@ -837,6 +846,11 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) override def isHelping: Boolean = sawHelp override def help = helpText.get + + override def reset() = { + v = default + setByUser = false + } } /** A setting represented by a string in a given set of `choices`, @@ -884,13 +898,15 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) case List("help") => sawHelp = true; SomeOfNil case List(x) if choices contains x => value = x ; SomeOfNil case List(x) => errorAndValue("'" + x + "' is not a valid choice for '" + name + "'", None) - case xs => errorAndValue("'" + name + "' does not accept multiple arguments.", None) + case _ => errorAndValue("'" + name + "' does not accept multiple arguments.", None) } def unparse: List[String] = if (value == default) Nil else List(name + ":" + value) override def tryToSetFromPropertyValue(s: String) = tryToSetColon(s::Nil) // used from ide withHelpSyntax(name + ":<" + helpArg + ">") + + override def reset() = v = default } private def mkPhasesHelp(descr: String, default: String) = { @@ -914,14 +930,13 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) private[this] var _v: T = Nil private[this] var _numbs: List[(Int,Int)] = Nil private[this] var _names: T = Nil - //protected var v: T = Nil protected def v: T = _v protected def v_=(t: T): Unit = { // throws NumberFormat on bad range (like -5-6) - def asRange(s: String): (Int,Int) = (s indexOf '-') match { + def asRange(s: String): (Int,Int) = s.indexOf('-') match { case -1 => (s.toInt, s.toInt) case 0 => (-1, s.tail.toInt) - case i if s.last == '-' => (s.init.toInt, Int.MaxValue) + case _ if s.last == '-' => (s.init.toInt, Int.MaxValue) case i => (s.take(i).toInt, s.drop(i+1).toInt) } val numsAndStrs = t filter (_.nonEmpty) partition (_ forall (ch => ch.isDigit || ch == '-')) @@ -971,6 +986,8 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) if (default == "") name + ":" else name + "[:phases]" ) + + override def reset() = clear() } /** Internal use - syntax enhancements. */ diff --git a/src/compiler/scala/tools/nsc/settings/PathFactory.scala b/src/compiler/scala/tools/nsc/settings/PathFactory.scala index eac093a750b0..d16b8de36009 100644 --- a/src/compiler/scala/tools/nsc/settings/PathFactory.scala +++ b/src/compiler/scala/tools/nsc/settings/PathFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 381829e8a798..57b41f3a5255 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -95,13 +95,11 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett val elidebelow = IntSetting ("-Xelide-below", "Calls to @elidable methods are omitted if method priority is lower than argument", elidable.MINIMUM, None, elidable.byName get _) val noForwarders = BooleanSetting ("-Xno-forwarders", "Do not generate static forwarders in mirror classes.") - val genPhaseGraph = StringSetting ("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "") + val genPhaseGraph = StringSetting ("-Vphase-graph", arg="file", descr="Generate phase graph to -*.dot.").withAbbreviation("-Xgenerate-phase-graph") val maxerrs = IntSetting ("-Xmaxerrs", "Maximum errors to print", 100, None, _ => None) val maxwarns = IntSetting ("-Xmaxwarns", "Maximum warnings to print", 100, None, _ => None) val Xmigration = ScalaVersionSetting ("-Xmigration", "version", "Warn about constructs whose behavior may have changed since version.", initial = NoScalaVersion, default = Some(AnyScalaVersion)) val Xnojline = BooleanSetting ("-Xnojline", "Do not use JLine for editing.") - .withDeprecationMessage("Replaced by -Xjline:off") - .withPostSetHook(_ => Xjline.value = "off") val Xjline = ChoiceSetting ( name = "-Xjline", helpArg = "mode", @@ -112,6 +110,8 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett "emacs key bindings.", "vi key bindings", "No JLine editing.")) + .withDeprecationMessage("Replaced by use of '~/.inputrc'. Set 'editing-mode' to 'vi', 'emacs' or 'dumb'") + val Xverify = BooleanSetting ("-Xverify", "Verify generic signatures in generated bytecode.") val plugin = MultiStringSetting ("-Xplugin", "paths", "Load a plugin from each classpath.") val disable = MultiStringSetting ("-Xplugin-disable", "plugin", "Disable plugins by name.") @@ -125,14 +125,17 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "") val reporter = StringSetting ("-Xreporter", "classname", "Specify a custom subclass of FilteringReporter for compiler messages.", "scala.tools.nsc.reporters.ConsoleReporter") private val XsourceHelp = - sm"""|-Xsource:3 is for migrating a codebase, -Xsource:3-cross is for cross-building. + sm"""|-Xsource:3 is for migrating a codebase. -Xsource-features can be added for + |cross-building to adopt certain Scala 3 behaviors. + | + |See also "Scala 2 with -Xsource:3" on docs.scala-lang.org. | |-Xsource:3 issues migration warnings in category `cat=scala3-migration`, - | which by default are promoted to errors under the `-Wconf` configuration. - | Examples of promoted warnings: + |which are promoted to errors by default using a `-Wconf` configuration. + |Examples of promoted warnings: | * Implicit definitions must have an explicit type | * (x: Any) + "" is deprecated - | * Args not adapted to unit value + | * An empty argument list is not adapted to the unit value | * Member classes cannot shadow a same-named class defined in a parent | * Presence or absence of parentheses in overrides must match exactly | @@ -144,38 +147,98 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett | * import p.{given, *} | * Eta-expansion `x.m` of methods without trailing `_` | - |The following constructs emit a migration warning under -Xsource:3. With - |-Xsource:3-cross the semantics change to match Scala 3 and no warning is issued. - | * Unicode escapes in raw interpolations and triple-quoted strings - | * Leading infix operators continue the previous line - | * Interpolator must be selectable from `scala.StringContext` - | * Case class copy and apply have the same access modifier as the constructor - | * The inferred type of an override is taken from the member it overrides + |The following constructs emit a migration warning under -Xsource:3. To adopt + |Scala 3 semantics, see `-Xsource-features:help`. + |${sourceFeatures.values.toList.collect { case c: sourceFeatures.Choice if c.expandsTo.isEmpty => c.help }.map(h => s" * $h").mkString("\n")} |""" @nowarn("cat=deprecation") - val source = ScalaVersionSetting ("-Xsource", "version", "Enable warnings and features for a future version.", initial = ScalaVersion("2.13"), helpText = Some(XsourceHelp)).withPostSetHook { s => - if (s.value >= ScalaVersion("3")) { - isScala3.value = true - if (s.value > ScalaVersion("3")) - isScala3Cross.value = true - } - else if (s.value >= ScalaVersion("2.14")) - s.withDeprecationMessage("instead of -Xsource:2.14, use -Xsource:3 or -Xsource:3-cross").value = ScalaVersion("3") - else if (s.value < ScalaVersion("2.13")) - errorFn.apply(s"-Xsource must be at least the current major version (${ScalaVersion("2.13").versionString})") + val source = ScalaVersionSetting ("-Xsource", "version", "Enable warnings and features for a future version.", initial = ScalaVersion("2.13"), helpText = Some(XsourceHelp)).withPostSetHook { s => + if (s.value.unparse == "3.0.0-cross") + XsourceFeatures.tryToSet(List("_")) + if (s.value < ScalaVersion("3")) + if (s.value >= ScalaVersion("2.14")) + s.withDeprecationMessage("instead of -Xsource:2.14, use -Xsource:3 and optionally -Xsource-features").value = ScalaVersion("3") + else if (s.value < ScalaVersion("2.13")) + errorFn.apply(s"-Xsource must be at least the current major version (${ScalaVersion("2.13").versionString})") } + + private val scala3Version = ScalaVersion("3") @deprecated("Use currentRun.isScala3 instead", since="2.13.9") - val isScala3 = BooleanSetting ("isScala3", "Is -Xsource Scala 3?").internalOnly() - @deprecated("Use currentRun.isScala3Cross instead", since="2.13.13") - val isScala3Cross = BooleanSetting ("isScala3Cross", "Is -Xsource > Scala 3?").internalOnly() - // The previous "-Xsource" option is intended to be used mainly though ^ helper + def isScala3 = source.value >= scala3Version + + // buffet of features available under -Xsource:3 + object sourceFeatures extends MultiChoiceEnumeration { + // Changes affecting binary encoding + val caseApplyCopyAccess = Choice("case-apply-copy-access", "Constructor modifiers are used for apply / copy methods of case classes. [bin]") + val caseCompanionFunction = Choice("case-companion-function", "Synthetic case companion objects no longer extend FunctionN. [bin]") + val caseCopyByName = Choice("case-copy-by-name", "Synthesize case copy method with by-name parameters. [bin]") + val inferOverride = Choice("infer-override", "Inferred type of member uses type of overridden member. [bin]") + val noInferStructural = Choice("no-infer-structural", "Definitions with an inferred type never have a structural type. [bin]") + + // Other semantic changes + val any2StringAdd = Choice("any2stringadd", "Implicit `any2stringadd` is never inferred.") + val unicodeEscapesRaw = Choice("unicode-escapes-raw", "Don't process unicode escapes in triple quoted strings and raw interpolations.") + val stringContextScope = Choice("string-context-scope", "String interpolations always desugar to scala.StringContext.") + val leadingInfix = Choice("leading-infix", "Leading infix operators continue the previous line.") + val packagePrefixImplicits = Choice("package-prefix-implicits", "The package prefix p is no longer part of the implicit search scope for type p.A.") + val implicitResolution = Choice("implicit-resolution", "Use Scala-3-style downwards comparisons for implicit search and overloading resolution (see github.com/scala/scala/pull/6037).") + val doubleDefinitions = Choice("double-definitions", "Correctly disallow double definitions differing in empty parens.") + val etaExpandAlways = Choice("eta-expand-always", "Eta-expand even if the expected type is not a function type.") + + val v13_13_choices = List(caseApplyCopyAccess, caseCompanionFunction, inferOverride, any2StringAdd, unicodeEscapesRaw, stringContextScope, leadingInfix, packagePrefixImplicits) + + val v13_13 = Choice( + "v2.13.13", + v13_13_choices.mkString("", ",", "."), + expandsTo = v13_13_choices) + + val v13_14_choices = implicitResolution :: v13_13_choices + val v13_14 = Choice( + "v2.13.14", + "v2.13.13 plus implicit-resolution", + expandsTo = v13_14_choices) + + val v13_15_choices = doubleDefinitions :: v13_14_choices + val v13_15 = Choice( + "v2.13.15", + "v2.13.14 plus double-definitions", + expandsTo = v13_15_choices) + + val v13_17_choices = etaExpandAlways :: noInferStructural :: v13_15_choices + val v13_17 = Choice( + "v2.13.17", + "v2.13.15 plus no-infer-structural, eta-expand-always", + expandsTo = v13_17_choices) + } + val XsourceFeatures = MultiChoiceSetting( + name = "-Xsource-features", + helpArg = "feature", + descr = "Enable Scala 3 features under -Xsource:3: `-Xsource-features:help` for details.", + domain = sourceFeatures, + helpText = Some( + sm"""Enable Scala 3 features under -Xsource:3. + | + |Instead of `-Xsource-features:_`, it is recommended to enable individual features. + |Features can also be removed from a feature group by prefixing with `-`; + |for example, `-Xsource-features:v2.13.14,-case-companion-function`. + |Listing features explicitly ensures new semantic changes in future Scala versions are + |not silently adopted; new features can be enabled after auditing migration warnings. + | + |`-Xsource:3-cross` is a shorthand for `-Xsource:3 -Xsource-features:_`. + | + |Features marked with [bin] affect the binary encoding. Enabling them in a project + |with existing releases for Scala 2.13 can break binary compatibility. + | + |Available features: + |""") + ) val XnoPatmatAnalysis = BooleanSetting ("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.") val XmixinForceForwarders = ChoiceSetting( name = "-Xmixin-force-forwarders", helpArg = "mode", - descr = "Generate forwarder methods in classes inhering concrete methods from traits.", + descr = "Generate forwarder methods in classes inheriting concrete methods from traits.", choices = List("true", "junit", "false"), default = "true", choicesHelp = List( @@ -303,15 +366,16 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett // Allows a specialised jar to be written. For instance one that provides stable hashing of content, or customisation of the file storage val YjarFactory = StringSetting ("-YjarFactory", "classname", "factory for jar files", classOf[DefaultJarFactory].getName) - val YaddBackendThreads = IntSetting ("-Ybackend-parallelism", "maximum worker threads for backend", 1, Some((1,16)), (x: String) => None ) - val YmaxQueue = IntSetting ("-Ybackend-worker-queue", "backend threads worker queue size", 0, Some((0,1000)), (x: String) => None ) + val YaddBackendThreads = IntSetting ("-Ybackend-parallelism", "maximum worker threads for backend", 1, Some((1,16)), (_: String) => None ) + val YmaxQueue = IntSetting ("-Ybackend-worker-queue", "backend threads worker queue size", 0, Some((0,1000)), (_: String) => None ) val YjarCompressionLevel = IntSetting("-Yjar-compression-level", "compression level to use when writing jar files", - Deflater.DEFAULT_COMPRESSION, Some((Deflater.DEFAULT_COMPRESSION,Deflater.BEST_COMPRESSION)), (x: String) => None) + Deflater.DEFAULT_COMPRESSION, Some((Deflater.DEFAULT_COMPRESSION,Deflater.BEST_COMPRESSION)), (_: String) => None) val YpickleJava = BooleanSetting("-Ypickle-java", "Pickler phase should compute pickles for .java defined symbols for use by build tools").internalOnly() val YpickleWrite = StringSetting("-Ypickle-write", "directory|jar", "destination for generated .sig files containing type signatures.", "", None).internalOnly() val YpickleWriteApiOnly = BooleanSetting("-Ypickle-write-api-only", "Exclude private members (other than those material to subclass compilation, such as private trait vals) from generated .sig files containing type signatures.").internalOnly() val YtrackDependencies = BooleanSetting("-Ytrack-dependencies", "Record references to in unit.depends. Deprecated feature that supports SBT 0.13 with incOptions.withNameHashing(false) only.", default = true) - val Yscala3ImplicitResolution = BooleanSetting("-Yscala3-implicit-resolution", "Use Scala-3-style downwards comparisons for implicit search and overloading resolution (see https://github.com/scala/bug/issues/12437).", default = false) + val Yscala3ImplicitResolution = BooleanSetting("-Yscala3-implicit-resolution", "Use Scala-3-style downwards comparisons for implicit search and overloading resolution (see github.com/scala/scala/pull/6037).") + .withDeprecationMessage("Use -Xsource:3 -Xsource-features:implicit-resolution instead") sealed abstract class CachePolicy(val name: String, val help: String) object CachePolicy { @@ -515,6 +579,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett */ val Vhelp = BooleanSetting("-V", "Print a synopsis of verbose options.") val browse = PhasesSetting("-Vbrowse", "Browse the abstract syntax tree after") withAbbreviation "-Ybrowse" + val cyclic = BooleanSetting("-Vcyclic", "Debug cyclic reference error.") val debug = BooleanSetting("-Vdebug", "Increase the quantity of debugging output.") withAbbreviation "-Ydebug" withPostSetHook (s => if (s.value) StatisticsStatics.enableDebugAndDeoptimize()) val YdebugTasty = BooleanSetting("-Vdebug-tasty", "Increase the quantity of debugging output when unpickling tasty.") withAbbreviation "-Ydebug-tasty" val VdebugTypeError = BooleanSetting("-Vdebug-type-error", "Print the stack trace when any error is caught.") withAbbreviation "-Ydebug-type-error" @@ -556,12 +621,14 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett .withAbbreviation("-Yshow-symkinds") val Yshowsymowners = BooleanSetting ("-Vshow-symowners", "Print owner identifiers next to symbol names.") .withAbbreviation("-Yshow-symowners") - val Ystatistics = PhasesSetting("-Vstatistics", "Print compiler statistics for specific phases", "parser,typer,patmat,erasure,cleanup,jvm") - .withPostSetHook(s => YstatisticsEnabled.value = s.value.nonEmpty) + val Ystatistics = PhasesSetting("-Vstatistics", "Print compiler statistics for specific phases (implies `-Ycollect-statistics`)", "parser,typer,patmat,erasure,cleanup,jvm") + .withPostSetHook(s => if (s.value.nonEmpty) YstatisticsEnabled.value = true) .withAbbreviation("-Ystatistics") val YstatisticsEnabled = BooleanSetting("-Ystatistics-enabled", "Internal setting, indicating that statistics are enabled for some phase.").internalOnly().withPostSetHook(s => if (s.value) StatisticsStatics.enableColdStatsAndDeoptimize()) val YhotStatisticsEnabled = BooleanSetting("-Vhot-statistics", s"Enable `${Ystatistics.name}` to also print hot statistics.") .withAbbreviation("-Yhot-statistics").withPostSetHook(s => if (s.value && YstatisticsEnabled.value) StatisticsStatics.enableHotStatsAndDeoptimize()) + val YcollectStatistics = BooleanSetting("-Ycollect-statistics", "Collect cold statistics (quietly, unless `-Vstatistics` is set)") + .withPostSetHook(s => if (s.value) YstatisticsEnabled.value = true) val Yshowsyms = BooleanSetting("-Vsymbols", "Print the AST symbol hierarchy after each phase.") withAbbreviation "-Yshow-syms" val Ytyperdebug = BooleanSetting("-Vtyper", "Trace type assignments.") withAbbreviation "-Ytyper-debug" val Vimplicits = BooleanSetting("-Vimplicits", "Print dependent missing implicits.").withAbbreviation("-Xlog-implicits") @@ -619,16 +686,13 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett } def conflictWarning: Option[String] = { - // See cd878232b5 for an example how to warn about conflicting settings - - /* - def checkSomeConflict: Option[String] = ... + @nowarn("cat=deprecation") + def sourceFeatures: Option[String] = + Option.when(XsourceFeatures.value.nonEmpty && !isScala3)(s"${XsourceFeatures.name} requires -Xsource:3") - List(/* checkSomeConflict, ... */).flatten match { + List(sourceFeatures).flatten match { case Nil => None case warnings => Some("Conflicting compiler settings were detected. Some settings will be ignored.\n" + warnings.mkString("\n")) } - */ - None } } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala index 839b0eb9b5f6..a773dadab0a9 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,9 +15,10 @@ package scala package tools.nsc.settings -/** - * Represents a single Scala version in a manner that - * supports easy comparison and sorting. +/** Represents a single Scala version in a manner that + * supports easy comparison and sorting. + * + * A version can be `Specific`, `Maximal`, or `Minimal`. */ sealed abstract class ScalaVersion extends Ordered[ScalaVersion] { def unparse: String @@ -26,33 +27,35 @@ sealed abstract class ScalaVersion extends Ordered[ScalaVersion] { /** A scala version that sorts higher than all actual versions. */ sealed abstract class MaximalScalaVersion extends ScalaVersion { - def compare(that: ScalaVersion): Int = that match { + final def compare(that: ScalaVersion): Int = that match { case _: MaximalScalaVersion => 0 case _ => 1 } } +/** A scala version that sorts lower than all actual versions. */ +sealed abstract class MinimalScalaVersion extends ScalaVersion { + final def compare(that: ScalaVersion): Int = that match { + case _: MinimalScalaVersion => 0 + case _ => -1 + } +} + /** If "no version" is specified, assume a maximal version, "the latest". */ case object NoScalaVersion extends MaximalScalaVersion { def unparse = "none" } -/** Same as `NoScalaVersion` but with a different toString */ -case object Scala3Cross extends MaximalScalaVersion { - def unparse = "3-cross" -} - -/** - * A specific Scala version, not one of the magic min/max versions. An SpecificScalaVersion - * may or may not be a released version - i.e. this same class is used to represent - * final, release candidate, milestone, and development builds. The build argument is used - * to segregate builds +/** A specific Scala version, not one of the magic min/max versions. + * + * A SpecificScalaVersion may or may not be a released version. + * The `build` parameter specifies final, release candidate, milestone, and development builds. */ case class SpecificScalaVersion(major: Int, minor: Int, rev: Int, build: ScalaBuild) extends ScalaVersion { def unparse = s"${major}.${minor}.${rev}${build.unparse}" override def versionString = s"${major}.${minor}.${rev}" - def compare(that: ScalaVersion): Int = that match { + final def compare(that: ScalaVersion): Int = that match { case SpecificScalaVersion(thatMajor, thatMinor, thatRev, thatBuild) => // this could be done more cleanly by importing scala.math.Ordering.Implicits, but we have to do these // comparisons a lot so I'm using brute force direct style code @@ -62,26 +65,19 @@ case class SpecificScalaVersion(major: Int, minor: Int, rev: Int, build: ScalaBu else if (minor > thatMinor) 1 else if (rev < thatRev) -1 else if (rev > thatRev) 1 - else build compare thatBuild - case AnyScalaVersion => 1 + else build.compare(thatBuild) + case _: MinimalScalaVersion => 1 case _: MaximalScalaVersion => -1 } } -/** - * A Scala version that sorts lower than all actual versions +/** A Scala version that sorts lower than all actual versions. */ -case object AnyScalaVersion extends ScalaVersion { +case object AnyScalaVersion extends MinimalScalaVersion { def unparse = "any" - - def compare(that: ScalaVersion): Int = that match { - case AnyScalaVersion => 0 - case _ => -1 - } } -/** - * Factory methods for producing ScalaVersions +/** Factory methods for producing ScalaVersions. */ object ScalaVersion { private val dot = """\.""" @@ -109,12 +105,11 @@ object ScalaVersion { } versionString match { - case "none" | "" => NoScalaVersion - case "3-cross" => Scala3Cross - case "any" => AnyScalaVersion + case "none" | "" => NoScalaVersion + case "any" => AnyScalaVersion case vpat(majorS, minorS, revS, buildS) => SpecificScalaVersion(toInt(majorS), toInt(minorS), toInt(revS), toBuild(buildS)) - case _ => error(); AnyScalaVersion + case _ => error(); AnyScalaVersion } } @@ -132,72 +127,61 @@ object ScalaVersion { } } -/** - * Represents the data after the dash in major.minor.rev-build +/** Represents the data after the dash in major.minor.rev-build. + * + * In order, Development, Final, RC, Milestone. The order is "newest to oldest". */ -abstract class ScalaBuild extends Ordered[ScalaBuild] { - /** - * Return a version of this build information that can be parsed back into the - * same ScalaBuild - */ +sealed abstract class ScalaBuild extends Ordered[ScalaBuild] { + /** Return a version of this build information that can be parsed back into the same ScalaBuild. */ def unparse: String + + final def compare(that: ScalaBuild) = buildOrdering.compare(this, that) +} +private object buildOrdering extends Ordering[ScalaBuild] { + override def compare(x: ScalaBuild, y: ScalaBuild): Int = + x match { + case Development(id) => + y match { + // sorting by id is pragmatic but not meaningful, such as "cross" < "migration" + case Development(thatId) => id.compare(thatId) + case _ => 1 // otherwise, newer than official builds, which is incorrect on the "build timeline" + } + case Milestone(n) => + y match { + case Milestone(thatN) => n - thatN // compare two milestones based on their milestone numbers + case _ => -1 // a milestone is older than anything other than another milestone + } + case RC(n) => + y match { + case RC(thatN) => n - thatN // compare two rcs based on their RC numbers + case Milestone(_) => 1 // an rc is older than anything other than a milestone or another rc + case _ => -1 + } + case Final => + y match { + case Final => 0 // a final is newer than anything other than a development build or another final + case Development(_) => -1 + case _ => 1 + } + } } -/** - * A development, test, integration, snapshot or other "unofficial" build +/** A development, test, integration, snapshot or other "unofficial" build. */ case class Development(id: String) extends ScalaBuild { def unparse = s"-${id}" - - def compare(that: ScalaBuild) = that match { - // sorting two development builds based on id is reasonably valid for two versions created with the same schema - // otherwise it's not correct, but since it's impossible to put a total ordering on development build versions - // this is a pragmatic compromise - case Development(thatId) => id compare thatId - // assume a development build is newer than anything else, that's not really true, but good luck - // mapping development build versions to other build types - case _ => 1 - } } -/** - * A final final +/** A final final. */ case object Final extends ScalaBuild { def unparse = "" - - def compare(that: ScalaBuild) = that match { - case Final => 0 - // a final is newer than anything other than a development build or another final - case Development(_) => -1 - case _ => 1 - } } - -/** - * A candidate for final release +/** A candidate for final release. */ case class RC(n: Int) extends ScalaBuild { def unparse = s"-RC${n}" - - def compare(that: ScalaBuild) = that match { - // compare two rcs based on their RC numbers - case RC(thatN) => n - thatN - // an rc is older than anything other than a milestone or another rc - case Milestone(_) => 1 - case _ => -1 - } } - -/** - * An intermediate release +/** An intermediate release. */ case class Milestone(n: Int) extends ScalaBuild { def unparse = s"-M${n}" - - def compare(that: ScalaBuild) = that match { - // compare two milestones based on their milestone numbers - case Milestone(thatN) => n - thatN - // a milestone is older than anything other than another milestone - case _ => -1 - - } } diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala index 044a6ca3dbd6..19f4bd987210 100644 --- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -32,14 +32,12 @@ trait StandardScalaSettings { _: MutableSettings => val javaextdirs = PathSetting ("-javaextdirs", "Override java extdirs classpath.", Defaults.javaExtDirs) withAbbreviation "--java-extension-directories" val sourcepath = PathSetting ("-sourcepath", "Specify location(s) of source files.", "") withAbbreviation "--source-path" // Defaults.scalaSourcePath val rootdir = PathSetting ("-rootdir", "The absolute path of the project root directory, usually the git/scm checkout. Used by -Wconf.", "") withAbbreviation "--root-directory" + val systemPath = PathSetting ("-system", "Override location of Java system modules", "") withAbbreviation "--system" /** Other settings. */ val dependencyfile = StringSetting ("-dependencyfile", "file", "Set dependency tracking file.", ".scala_dependencies") withAbbreviation "--dependency-file" - val deprecation = BooleanSetting ("-deprecation", "Emit warning and location for usages of deprecated APIs. See also -Wconf.") withAbbreviation "--deprecation" withPostSetHook { s => - if (s.value) Wconf.tryToSet(List(s"cat=deprecation:w")) - else Wconf.tryToSet(List(s"cat=deprecation:s")) - } + val deprecation = BooleanSetting ("-deprecation", "Emit warning and location for usages of deprecated APIs. See also -Wconf.").withAbbreviation("--deprecation") val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding) withAbbreviation "--encoding" val explaintypes = BooleanSetting ("-explaintypes", "Explain type errors in more detail.") withAbbreviation "--explain-types" val feature = BooleanSetting ("-feature", "Emit warning and location for usages of features that should be imported explicitly. See also -Wconf.") withAbbreviation "--feature" withPostSetHook { s => @@ -48,7 +46,9 @@ trait StandardScalaSettings { _: MutableSettings => } val g = ChoiceSetting ("-g", "level", "Set level of generated debugging info.", List("none", "source", "line", "vars", "notailcalls"), "vars") val help = BooleanSetting ("-help", "Print a synopsis of standard options") withAbbreviation "--help" withAbbreviation("-h") - val nowarn = BooleanSetting ("-nowarn", "Generate no warnings.") withAbbreviation "--no-warnings" withPostSetHook { s => if (s.value) maxwarns.value = 0 } + val nowarn = BooleanSetting("-nowarn", "Silence warnings. (-Wconf:any:s)") + .withAbbreviation("--no-warnings") + .withPostSetHook(s => if (s.value) maxwarns.value = 0) val optimise: BooleanSetting // depends on post hook which mutates other settings val print = BooleanSetting ("-print", "Print program with Scala-specific features removed.") withAbbreviation "--print" val quickfix = MultiStringSetting( @@ -75,11 +75,13 @@ trait StandardScalaSettings { _: MutableSettings => val current = setting.value.toInt if (!isJavaAtLeast("9") && current > 8) errorFn.apply("-release is only supported on JVM 9 and higher") if (target.valueSetByUser.map(_.toInt > current).getOrElse(false)) errorFn("-release cannot be less than -target") + if (systemPath.isSetByUser) errorFn("-release cannot be used with -system") //target.value = setting.value // this would trigger deprecation } .withAbbreviation("--release") .withAbbreviation("-java-output-version") def releaseValue: Option[String] = release.valueSetByUser + def systemPathValue: Option[String] = systemPath.valueSetByUser val target = ChoiceSetting("-target", "target", "Target platform for object files.", AllTargetVersions, "8") .withPreSetHook(normalizeTarget) @@ -90,7 +92,6 @@ trait StandardScalaSettings { _: MutableSettings => // .withAbbreviation("--Xtarget") // .withAbbreviation("-Xtarget") .withAbbreviation("-Xunchecked-java-output-version") - .withDeprecationMessage("Use -release instead to compile against the correct platform API.") def targetValue: String = target.valueSetByUser.orElse(releaseValue).getOrElse(target.value) val unchecked = BooleanSetting ("-unchecked", "Enable additional warnings where generated code depends on assumptions. See also -Wconf.") withAbbreviation "--unchecked" withPostSetHook { s => if (s.value) Wconf.tryToSet(List(s"cat=unchecked:w")) @@ -121,7 +122,7 @@ object StandardScalaSettings { val MaxTargetVersion = ScalaVersion(javaSpecVersion) match { case SpecificScalaVersion(1, minor, _, _) => minor case SpecificScalaVersion(major, _, _, _) => major - case _ => 22 + case _ => 25 } private val AllTargetVersions = (MinTargetVersion to MaxTargetVersion).map(_.toString).to(List) diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index f54c139abe27..57b1a687ce7d 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -27,7 +27,7 @@ trait Warnings { // Warning semantics. val fatalWarnings = BooleanSetting("-Werror", "Fail the compilation if there are any warnings.") withAbbreviation "-Xfatal-warnings" - private val WconfDefault = List("cat=deprecation:ws", "cat=feature:ws", "cat=optimizer:ws") + val WconfDefault = List("cat=deprecation:ws", "cat=feature:ws", "cat=optimizer:ws") // Note: user-defined settings are added on the right, but the value is reversed before // it's parsed, so that later defined settings take precedence. val Wconf = MultiStringSetting( @@ -40,8 +40,8 @@ trait Warnings { |Syntax: -Wconf::,:,... |multiple are combined with &, i.e., &...& | - |Note: Run with `-Wconf:any:warning-verbose` to print warnings with their category, site, - |and (for deprecations) origin and since-version. + |Use the `@nowarn("verbose")` / `@nowarn("v")` annotation or `-Wconf:any:warning-verbose` + |to print applicable message filters with every warning. | | | - Any message: any @@ -82,8 +82,13 @@ trait Warnings { |The default configuration is: | -Wconf:${WconfDefault.mkString(",")} | - |User-defined configurations are added to the left. The leftmost rule matching - |a warning message defines the action. + |Under -Xsource:3-cross, the category of scala3-migration warnings are errors by default: + | -Wconf:cat=scala3-migration:e + |Under -Xsource:3-migration, they are warnings: + | -Wconf:cat=scala3-migration:w + | + |User-defined configurations override previous settings, such that the last matching + |configuration defines the action for a given diagnostic message. | |Examples: | - change every warning into an error: -Wconf:any:error @@ -103,13 +108,14 @@ trait Warnings { name = "-Wmacros", helpArg = "mode", descr = "Enable lint warnings on macro expansions.", - choices = List("none", "before", "after", "both"), - default = "before", + choices = List("none", "before", "after", "both", "default"), + default = "default", choicesHelp = List( "Do not inspect expansions or their original trees when generating unused symbol warnings.", "Only inspect unexpanded user-written code for unused symbols.", "Only inspect expanded trees when generating unused symbol warnings.", - "Inspect both user-written code and expanded trees when generating unused symbol warnings." + "Inspect both user-written code and expanded trees when generating unused symbol warnings.", + "Only inspect unexpanded user-written code for unused symbols but include usages in expansions.", ) ) withAbbreviation "-Ywarn-macros" val warnDeadCode = BooleanSetting("-Wdead-code", "Warn when dead code is identified.") withAbbreviation "-Ywarn-dead-code" @@ -120,6 +126,11 @@ trait Warnings { val warnValueDiscard = BooleanSetting("-Wvalue-discard", "Warn when non-Unit expression results are unused.") withAbbreviation "-Ywarn-value-discard" val warnNumericWiden = BooleanSetting("-Wnumeric-widen", "Warn when numerics are widened.") withAbbreviation "-Ywarn-numeric-widen" val warnOctalLiteral = BooleanSetting("-Woctal-literal", "Warn on obsolete octal syntax.") withAbbreviation "-Ywarn-octal-literal" + val warnUnnamedBoolean = BooleanSetting("-Wunnamed-boolean-literal", "Warn about unnamed boolean literals if there is more than one or defaults are used, unless parameter has @deprecatedName.") + val warnUnnamedStrict = BooleanSetting("-Wunnamed-boolean-literal-strict", "Warn about all unnamed boolean literals, unless parameter has @deprecatedName or the method has a single leading boolean parameter.").enabling(warnUnnamedBoolean :: Nil) + val warnToString = BooleanSetting("-Wtostring-interpolated", "Warn when a standard interpolator uses toString.") + val warnMultiargInfix = BooleanSetting("-Wmultiarg-infix", "Infix operator was defined or used with multiarg operand.") + def multiargInfix = warnMultiargInfix.value object PerformanceWarnings extends MultiChoiceEnumeration { val Captured = Choice("captured", "Modification of var in closure causes boxing.") @@ -187,6 +198,7 @@ trait Warnings { val AdaptedArgs = LintWarning("adapted-args", "An argument list was modified to match the receiver.") val NullaryUnit = LintWarning("nullary-unit", "`def f: Unit` looks like an accessor; add parens to look side-effecting.") val Inaccessible = LintWarning("inaccessible", "Warn about inaccessible types in method signatures.") + val InferStructural = LintWarning("infer-structural", "Warn on definitions with an inferred structural type.") val InferAny = LintWarning("infer-any", "A type argument was inferred as Any.") val MissingInterpolator = LintWarning("missing-interpolator", "A string literal appears to be missing an interpolator id.") val DocDetached = LintWarning("doc-detached", "When running scaladoc, warn if a doc comment is discarded.") @@ -210,15 +222,14 @@ trait Warnings { val ByNameImplicit = LintWarning("byname-implicit", "Block adapted by implicit with by-name parameter.") val RecurseWithDefault = LintWarning("recurse-with-default", "Recursive call used default argument.") val UnitSpecialization = LintWarning("unit-special", "Warn for specialization of Unit in parameter position.") - val MultiargInfix = LintWarning("multiarg-infix", "Infix operator was defined or used with multiarg operand.") val ImplicitRecursion = LintWarning("implicit-recursion", "Implicit resolves to an enclosing definition.") - val UniversalMethods = LintWarning("universal-methods", "Require arg to is/asInstanceOf. No Unit receiver.") + val UniversalMethods = LintWarning("universal-methods", "Dubious usage of member of `Any` or `AnyRef`.") val NumericMethods = LintWarning("numeric-methods", "Dubious usages, such as `42.isNaN`.") val ArgDiscard = LintWarning("arg-discard", "-Wvalue-discard for adapted arguments.") val IntDivToFloat = LintWarning("int-div-to-float", "Warn when an integer division is converted (widened) to floating point: `(someInt / 2): Double`.") - val NamedBooleans = LintWarning("named-booleans", "Boolean literals should be named args unless param is @deprecatedName.") val PatternShadow = LintWarning("pattern-shadow", "Pattern variable id is also a term in scope.") val CloneableObject = LintWarning("cloneable", "Modules (objects) should not be Cloneable.") + val DubiousOverload = LintWarning("overload", "Overload differs only in an implicit parameter.") def allLintWarnings = values.toSeq.asInstanceOf[Seq[LintWarning]] } @@ -227,6 +238,7 @@ trait Warnings { def warnAdaptedArgs = lint contains AdaptedArgs def warnNullaryUnit = lint contains NullaryUnit def warnInaccessible = lint contains Inaccessible + def warnInferStructural = lint contains InferStructural def warnInferAny = lint contains InferAny def warnMissingInterpolator = lint contains MissingInterpolator def warnDocDetached = lint contains DocDetached @@ -249,15 +261,14 @@ trait Warnings { def warnByNameImplicit = lint contains ByNameImplicit def warnRecurseWithDefault = lint contains RecurseWithDefault def unitSpecialization = lint contains UnitSpecialization - def multiargInfix = lint contains MultiargInfix def lintImplicitRecursion = lint.contains(ImplicitRecursion) || (warnSelfImplicit.value: @nowarn("cat=deprecation")) def lintUniversalMethods = lint.contains(UniversalMethods) def lintNumericMethods = lint.contains(NumericMethods) def lintArgDiscard = lint.contains(ArgDiscard) def lintIntDivToFloat = lint.contains(IntDivToFloat) - def lintNamedBooleans = lint.contains(NamedBooleans) def warnPatternShadow = lint.contains(PatternShadow) def warnCloneableObject = lint.contains(CloneableObject) + def warnDubiousOverload = lint.contains(DubiousOverload) // The Xlint warning group. val lint = MultiChoiceSetting( diff --git a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala index 7eabc41be4f7..289640c04eb0 100644 --- a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index ac8345979ed9..c193040c2400 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,11 +16,12 @@ package symtab import classfile.{ClassfileParser, ReusableDataReader} import java.io.IOException +import scala.annotation._ import scala.reflect.internal.MissingRequirementError -import scala.reflect.io.{AbstractFile, NoAbstractFile} -import scala.tools.nsc.util.{ClassPath, ClassRepresentation} import scala.reflect.internal.util.ReusableInstance +import scala.reflect.io.{AbstractFile, NoAbstractFile} import scala.tools.nsc.Reporting.WarningCategory +import scala.tools.nsc.util.{ClassPath, ClassRepresentation} /** This class ... * @@ -50,7 +51,7 @@ abstract class SymbolLoaders { // forwards to runReporting.warning, but we don't have global in scope here def warning(pos: Position, msg: String, category: WarningCategory, site: String): Unit - protected def enterIfNew(owner: Symbol, member: Symbol, completer: SymbolLoader): Symbol = { + protected def enterIfNew(owner: Symbol, member: Symbol, @unused completer: SymbolLoader): Symbol = { assert(owner.info.decls.lookup(member.name) == NoSymbol, owner.fullName + "." + member.name) owner.info.decls enter member member diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index d562c715e493..2220065ea955 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala index 7a0af81ee22a..50b901372762 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala index faf69d5769e3..0080d97908d4 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 1de66e94f38c..1fcc7d69e05d 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -18,7 +18,7 @@ package classfile import java.io.IOException import java.lang.Integer.toHexString -import scala.annotation.switch +import scala.annotation._ import scala.collection.{immutable, mutable}, mutable.{ArrayBuffer, ListBuffer} import scala.reflect.internal.JavaAccFlags import scala.reflect.internal.pickling.ByteCodecs @@ -173,7 +173,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { AnyRefClass val bytes = in.buf.take(file.sizeOption.get) - TastyUnpickler.unpickle(TastyUniverse)(bytes, clazz, staticModule, file.path.stripSuffix(".class") + ".tasty") + TastyUnpickler.unpickle(TastyUniverse)(bytes, clazz, staticModule, file.path) } else { parseHeader() this.pool = new ConstantPool @@ -528,7 +528,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { val parentIndex = u2() val parentName = if (parentIndex == 0) null else pool.getClassName(parentIndex) val ifaceCount = u2() - val ifaces = for (i <- List.range(0, ifaceCount)) yield pool.getSuperClassName(index = u2()) + val ifaces = List.fill(ifaceCount.toInt)(pool.getSuperClassName(index = u2())) val completer = new ClassTypeCompleter(clazz.name, jflags, parentName, ifaces) enterOwnInnerClasses() @@ -922,9 +922,9 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { * Parse the "Exceptions" attribute which denotes the exceptions * thrown by a method. */ - def parseExceptions(len: Int, completer: JavaTypeCompleter): Unit = { + def parseExceptions(@unused len: Int, completer: JavaTypeCompleter): Unit = { val nClasses = u2() - for (n <- 0 until nClasses) { + for (_ <- 0 until nClasses) { // FIXME: this performs an equivalent of getExceptionTypes instead of getGenericExceptionTypes (scala/bug#7065) val cls = pool.getClassName(u2()) completer.exceptions ::= cls @@ -1195,7 +1195,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { case LongSigTpe => checkScalaSigAnnotArg() bytes = parseScalaLongSigBytes() - case t => + case _ => skipAnnotArgs() } i += 1 @@ -1292,7 +1292,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { var paramNames: ParamNames = _ var exceptions: List[NameOrString] = Nil } - private final class ClassTypeCompleter(name: Name, jflags: JavaAccFlags, parent: NameOrString, ifaces: List[NameOrString]) extends JavaTypeCompleter { + private final class ClassTypeCompleter(@unused name: Name, @unused jflags: JavaAccFlags, parent: NameOrString, ifaces: List[NameOrString]) extends JavaTypeCompleter { var permittedSubclasses: List[symbolTable.Symbol] = Nil override def complete(sym: symbolTable.Symbol): Unit = { val info = if (sig != null) sigToType(sym, sig) else { @@ -1316,7 +1316,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { override def complete(sym: symbolTable.Symbol): Unit = { def descriptorInfo = sigToType(sym, descriptor) val hasOuterParam = (name == nme.CONSTRUCTOR) && (descriptorInfo match { - case MethodType(params, restpe) => + case MethodType(params, _) => // if this is a non-static inner class, remove the explicit outer parameter innerClasses getEntry currentClass match { case Some(entry) if !entry.jflags.isStatic => @@ -1339,10 +1339,10 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) { sigToType(sym, sig) } else if (name == nme.CONSTRUCTOR) { descriptorInfo match { - case MethodType(params, restpe) => + case MethodType(params, _) => val paramsNoOuter = if (hasOuterParam) params.tail else params val newParams = paramsNoOuter match { - case (init :+ tail) if jflags.isSynthetic => + case init :+ _ if jflags.isSynthetic => // scala/bug#7455 strip trailing dummy argument ("access constructor tag") from synthetic constructors which // are added when an inner class needs to access a private constructor. init diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/DataReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/DataReader.scala index 9caf87a2c694..58691e7fcdbe 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/DataReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/DataReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 1a9f0af98e82..79556be4ba15 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -150,7 +150,7 @@ abstract class Pickler extends SubComponent { override protected def shouldSkipThisPhaseForJava: Boolean = !settings.YpickleJava.value } - type Index = mutable.AnyRefMap[AnyRef, Int] // a map from objects (symbols, types, names, ...) to indices into Entries + type Index = mutable.HashMap[AnyRef, Int] // a map from objects (symbols, types, names, ...) to indices into Entries type Entries = Array[AnyRef] final val InitEntriesSize = 256 @@ -158,7 +158,7 @@ abstract class Pickler extends SubComponent { private[this] var _entries: Entries = _ final def initPickle(root: Symbol, noPrivates: Boolean)(f: Pickle => Unit): Pickle = { - if (_index eq null) { _index = new Index(InitEntriesSize) } + if (_index eq null) { _index = new Index(InitEntriesSize, mutable.HashMap.defaultLoadFactor) } if (_entries eq null) { _entries = new Entries(InitEntriesSize) } val pickle = new Pickle(root, _index, _entries, noPrivates) try f(pickle) finally { pickle.close(); _index.clear(); fill(_entries, null) } @@ -369,7 +369,7 @@ abstract class Pickler extends SubComponent { // annotations in Modifiers are removed by the typechecker override def traverseModifiers(mods: Modifiers): Unit = if (putEntry(mods)) putEntry(mods.privateWithin) override def traverseName(name: Name): Unit = putEntry(name) - override def traverseConstant(const: Constant): Unit = putEntry(const) + override def traverseConstant(const: Constant): Unit = putConstant(const) override def traverse(tree: Tree): Unit = putTree(tree) def put(tree: Tree): Unit = { @@ -418,7 +418,9 @@ abstract class Pickler extends SubComponent { private def putAnnotationBody(annot: AnnotationInfo): Unit = { def putAnnotArg(arg: Tree): Unit = { arg match { - case Literal(c) => putConstant(c) + // Keep Literal with an AnnotatedType. Used in AnnotationInfo.argIsDefault. Allow `null` to prevent NPEs: + // Literal(Constant(v)) is used eg in compiler plugins, it produces a tree with `tpe == null`. + case Literal(c) if arg.tpe == null || arg.tpe.isInstanceOf[ConstantType] => putConstant(c) case _ => putTree(arg) } } @@ -475,7 +477,9 @@ abstract class Pickler extends SubComponent { private def writeAnnotation(annot: AnnotationInfo): Unit = { def writeAnnotArg(arg: Tree): Unit = { arg match { - case Literal(c) => writeRef(c) + // Keep Literal with an AnnotatedType. Used in AnnotationInfo.argIsDefault. Allow `null` to prevent NPEs: + // Literal(Constant(v)) is used eg in compiler plugins, it produces a tree with `tpe == null`. + case Literal(c) if arg.tpe == null || arg.tpe.isInstanceOf[ConstantType] => writeRef(c) case _ => writeRef(arg) } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ReusableDataReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ReusableDataReader.scala index f781d7cd8a50..46adc4c37d97 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ReusableDataReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ReusableDataReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/package.scala b/src/compiler/scala/tools/nsc/symtab/classfile/package.scala index ffe00c3c13bf..4e6f22601ea0 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/package.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/symtab/package.scala b/src/compiler/scala/tools/nsc/symtab/package.scala index 7a1dedec3fa3..6fd5a1673c07 100644 --- a/src/compiler/scala/tools/nsc/symtab/package.scala +++ b/src/compiler/scala/tools/nsc/symtab/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/ForceKinds.scala b/src/compiler/scala/tools/nsc/tasty/ForceKinds.scala index 137bbfe854bc..1e0991d55cff 100644 --- a/src/compiler/scala/tools/nsc/tasty/ForceKinds.scala +++ b/src/compiler/scala/tools/nsc/tasty/ForceKinds.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/TastyModes.scala b/src/compiler/scala/tools/nsc/tasty/TastyModes.scala index 6352b0fc6ef6..5faab5f982d5 100644 --- a/src/compiler/scala/tools/nsc/tasty/TastyModes.scala +++ b/src/compiler/scala/tools/nsc/tasty/TastyModes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/TastyUniverse.scala b/src/compiler/scala/tools/nsc/tasty/TastyUniverse.scala index 5fd81bcdf81e..4c9de6986024 100644 --- a/src/compiler/scala/tools/nsc/tasty/TastyUniverse.scala +++ b/src/compiler/scala/tools/nsc/tasty/TastyUniverse.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala b/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala index fb3924870570..ac0a0b1104c2 100644 --- a/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala +++ b/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -71,7 +71,7 @@ object TastyUnpickler { /** When Scala 3 is in an RC phase for a new minor version, we put here the TASTy of that Minor, * otherwise it should be empty. */ - final val toolOverrides: List[TastyVersion] = Nil + final val toolOverrides: List[TastyVersion] = List() private def asScala3Compiler(version: TastyVersion): String = if (version.major == 28) { diff --git a/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala b/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala index 7a8a1f3189cf..e43da99adff0 100644 --- a/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala +++ b/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,7 +16,7 @@ import scala.tools.tasty.{TastyRefs, TastyReader, TastyName, TastyFormat, TastyF import TastyRefs._, TastyFlags._, TastyFormat._ import ForceKinds._ -import scala.annotation.switch +import scala.annotation.{switch, unused} import scala.collection.mutable import scala.reflect.io.AbstractFile import scala.reflect.internal.Variance @@ -162,7 +162,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( tag match { case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | TEMPLATE => val end = readEnd() - for (i <- 0 until numRefs(tag)) readNat() + for (_ <- 0 until numRefs(tag)) readNat() if (tag === TEMPLATE) { // Read all member definitions now, whereas non-members are children of // template's owner tree. @@ -179,7 +179,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( val end = readEnd() val nrefs = numRefs(tag) if (nrefs < 0) { - for (i <- nrefs until 0) scanTree(buf, AllDefs) + for (_ <- nrefs until 0) scanTree(buf, AllDefs) goto(end) } else { @@ -409,6 +409,10 @@ class TreeUnpickler[Tasty <: TastyUniverse]( case METHODtype => readMethodic(MethodTermLambda, FlagSets.parseMethod, id) case TYPELAMBDAtype => readMethodic(HKTypeLambda, FlagSets.addDeferred, _.toTypeName) case PARAMtype => defn.ParamRef(readTypeRef(), readNat()) // reference to a parameter within a LambdaType + case FLEXIBLEtype => + // dotty would wrap the inner type in FlexibleType (with lower bound >: tpe | Null), + // but we can leave as-is - as Scala 2 does not have explicit nulls. + readType() } assert(currentAddr === end, s"$start $currentAddr $end ${astTagToString(tag)}") result @@ -510,7 +514,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( flags } - def isAbstractType(ttag: Int)(implicit ctx: Context): Boolean = nextUnsharedTag match { + def isAbstractType(@unused ttag: Int)(implicit ctx: Context): Boolean = nextUnsharedTag match { case LAMBDAtpt => val rdr = fork rdr.reader.readByte() // tag @@ -694,6 +698,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( case EXPORTED => addFlag(Exported) case OPEN => addFlag(Open) case INVISIBLE => addFlag(Invisible) + case TRACKED => addFlag(Tracked) case PRIVATEqualified => readByte() privateWithin = readWithin(ctx) @@ -739,7 +744,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( def indexStats(end: Addr)(implicit ctx: Context): Unit = { while (currentAddr.index < end.index) { nextByte match { - case tag @ (VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM) => + case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM => symbolAtCurrent() skipTree() case IMPORT | EXPORT => @@ -882,7 +887,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( def TypeDef(repr: TastyRepr, localCtx: Context)(implicit ctx: Context): Unit = { val allowedShared = Enum | Opaque | Infix | Given val allowedTypeFlags = allowedShared | Exported - val allowedClassFlags = allowedShared | Open | Transparent + val allowedClassFlags = allowedShared | Open | Transparent | Tracked if (sym.isClass) { checkUnsupportedFlags(repr.unsupportedFlags &~ allowedClassFlags) sym.owner.ensureCompleted(CompleteOwner) @@ -905,7 +910,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( } def TermParam(repr: TastyRepr, localCtx: Context)(implicit ctx: Context): Unit = { - checkUnsupportedFlags(repr.unsupportedFlags &~ (ParamAlias | Exported | Given)) + checkUnsupportedFlags(repr.unsupportedFlags &~ (ParamAlias | Exported | Given | Tracked)) val tpt = readTpt()(localCtx) ctx.setInfo(sym, if (nothingButMods(end) && sym.not(ParamSetter)) tpt.tpe @@ -1051,7 +1056,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( def isTopLevel: Boolean = nextByte === IMPORT || nextByte === PACKAGE - def readIndexedStatAsSym(exprOwner: Symbol)(implicit ctx: Context): NoCycle = nextByte match { + def readIndexedStatAsSym(@unused exprOwner: Symbol)(implicit ctx: Context): NoCycle = nextByte match { case TYPEDEF | VALDEF | DEFDEF => readIndexedMember() case IMPORT => @@ -1220,19 +1225,23 @@ class TreeUnpickler[Tasty <: TastyUniverse]( exprReader.readTerm() } else unsupportedTermTreeError("block expression") - case ASSIGN => unsupportedTermTreeError("assignment expression") - case LAMBDA => unsupportedTermTreeError("anonymous function literal") - case MATCH => unsupportedTermTreeError("match expression") - case RETURN => unsupportedTermTreeError("return statement") - case WHILE => unsupportedTermTreeError("loop statement") - case TRY => unsupportedTermTreeError("try expression") - case BIND => unsupportedTermTreeError("bind pattern") - case ALTERNATIVE => unsupportedTermTreeError("pattern alternative") - case UNAPPLY => unsupportedTermTreeError("unapply pattern") - case INLINED => unsupportedTermTreeError("inlined expression") - case SELECTouter => metaprogrammingIsUnsupported // only within inline - case HOLE => abortMacroHole - case _ => readPathTerm() + case ASSIGN => unsupportedTermTreeError("assignment expression") + case LAMBDA => unsupportedTermTreeError("anonymous function literal") + case MATCH => unsupportedTermTreeError("match expression") + case RETURN => unsupportedTermTreeError("return statement") + case WHILE => unsupportedTermTreeError("loop statement") + case TRY => unsupportedTermTreeError("try expression") + case BIND => unsupportedTermTreeError("bind pattern") + case ALTERNATIVE => unsupportedTermTreeError("pattern alternative") + case UNAPPLY => unsupportedTermTreeError("unapply pattern") + case INLINED => unsupportedTermTreeError("inlined expression") + case SELECTouter => metaprogrammingIsUnsupported // only within inline + case QUOTE => abortQuote + case SPLICE => abortSplice + case QUOTEPATTERN => abortQuotePattern + case SPLICEPATTERN => abortSplicePattern + case HOLE => abortMacroHole + case _ => readPathTerm() } assert(currentAddr === end, s"$start $currentAddr $end ${astTagToString(tag)}") result @@ -1265,6 +1274,10 @@ class TreeUnpickler[Tasty <: TastyUniverse]( * A HOLE should never appear in TASTy for a top level class, only in quotes. */ private def abortMacroHole[T]: T = abortWith(msg = "Scala 3 macro hole in pickled TASTy") + private def abortQuote[T]: T = abortWith(msg = "Scala 3 quoted expression in pickled TASTy") + private def abortSplice[T]: T = abortWith(msg = "Scala 3 quoted splice in pickled TASTy") + private def abortQuotePattern[T]: T = abortWith(msg = "Scala 3 quoted pattern in pickled TASTy") + private def abortSplicePattern[T]: T = abortWith(msg = "Scala 3 quoted pattern splice in pickled TASTy") private def signaturePolymorphicIsUnsupported[T](implicit ctx: Context): T = unsupportedTermTreeError("signature polymorphic application") @@ -1300,7 +1313,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( private def traceReadWith[T](treader: TreeReader, mode: TastyMode, owner: Symbol) = TraceInfo[T]( query = "read within owner", qual = s"${showSym(owner)} with modes `${mode.debug}` at ${treader.reader.currentAddr}", - res = t => s"exiting sub reader" + res = _ => s"exiting sub reader" ) /** A lazy datastructure that records how definitions are nested in TASTY data. diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/AnnotationOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/AnnotationOps.scala index 5e48e9d82e8a..6162028ba6ac 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/AnnotationOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/AnnotationOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -55,7 +55,7 @@ trait AnnotationOps { self: TastyUniverse => } tree match { case u.New(tpt) => - // this is to handle incorrectly formatted annotations in dotty - https://github.com/lampepfl/dotty/issues/10113 + // this is to handle incorrectly formatted annotations in dotty - https://github.com/scala/scala3/issues/10113 u.AnnotationInfo(tpt.tpe, Nil, Nil) case _ => go(Nil, Nil, tree) diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala index afad1a1f95fa..9d9220ab6bdd 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,12 +12,10 @@ package scala.tools.nsc.tasty.bridge -import scala.annotation.tailrec - +import scala.annotation._ import scala.collection.mutable -import scala.reflect.io.AbstractFile import scala.reflect.internal.MissingRequirementError - +import scala.reflect.io.AbstractFile import scala.tools.tasty.{TastyName, TastyFlags}, TastyFlags._, TastyName.ObjectName import scala.tools.nsc.tasty.{TastyUniverse, TastyModes, SafeEq}, TastyModes._ import scala.tools.nsc.tasty.{cyan, yellow, magenta, blue, green} @@ -194,7 +192,7 @@ trait ContextOps { self: TastyUniverse => protected implicit final def implyThisCtx: thisCtx.type = thisCtx /** JAVAattr is necessary to support pipelining in Zinc, we have to set Java erasure semantics if found. - * To support this we also need to support TASTy-only classpaths, see https://github.com/lampepfl/dotty/pull/17594 + * To support this we also need to support TASTy-only classpaths, see https://github.com/scala/scala3/pull/17594 * For a test case, see test/tasty/run-pipelined */ def isJava: Boolean = mode.is(ReadJava) @@ -521,7 +519,7 @@ trait ContextOps { self: TastyUniverse => final def processParents(cls: Symbol, parentTypes: List[Type]): parentTypes.type = { if (parentTypes.head.typeSymbolDirect === u.definitions.AnyValClass) { // TODO [tasty]: please reconsider if there is some shared optimised logic that can be triggered instead. - withPhaseNoLater("extmethods") { ctx0 => + withPhaseNoLater("extmethods") { _ => // duplicated from scala.tools.nsc.transform.ExtensionMethods cls.primaryConstructor.makeNotPrivate(noSymbol) for (decl <- cls.info.decls if decl.isMethod) { @@ -781,7 +779,7 @@ trait ContextOps { self: TastyUniverse => enterIfUnseen0(decls, d) } - def reportParameterizedTrait(cls: Symbol, decls: u.Scope): Unit = { + def reportParameterizedTrait(cls: Symbol, @unused decls: u.Scope): Unit = { val traitParams = traitParamAccessors(cls).getOrElse(Iterable.empty) if (traitParams.nonEmpty) { log { diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala index 1e703eba4721..ebc7718a2162 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -26,7 +26,7 @@ trait FlagOps { self: TastyUniverse => val TastyOnlyFlags: TastyFlagSet = ( Erased | Inline | InlineProxy | Opaque | Extension | Given | Exported | Transparent - | Enum | Infix | Open | ParamAlias | Invisible + | Enum | Infix | Open | ParamAlias | Invisible | Tracked ) type FlagParser = TastyFlagSet => Context => TastyFlagSet @@ -71,10 +71,10 @@ trait FlagOps { self: TastyUniverse => def is(mask: TastyFlagSet)(implicit ctx: Context): Boolean = sym.hasAllFlags(unsafeEncodeTastyFlagSet(mask, ctx.isJava)) def is(mask: TastyFlagSet, butNot: TastyFlagSet)(implicit ctx: Context): Boolean = - if (!butNot) - sym.is(mask) + if (butNot.hasFlags) + is(mask) && not(butNot) else - sym.is(mask) && sym.not(butNot) + is(mask) def not(mask: TastyFlagSet)(implicit ctx: Context): Boolean = sym.hasNoFlags(unsafeEncodeTastyFlagSet(mask, ctx.isJava)) } @@ -139,6 +139,7 @@ trait FlagOps { self: TastyUniverse => if (flags.is(ParamAlias)) sb += "" if (flags.is(Infix)) sb += "infix" if (flags.is(Invisible)) sb += "" + if (flags.is(Tracked)) sb += "" sb.mkString(" | ") } } diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/NameOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/NameOps.scala index 13ee13cc854b..b05cdfed9855 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/NameOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/NameOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala index 866454d34583..8ff67983b336 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.nsc.tasty.bridge -import scala.annotation.tailrec +import scala.annotation._ import scala.tools.nsc.tasty.{SafeEq, TastyUniverse, ForceKinds, TastyModes}, TastyModes._, ForceKinds._ import scala.tools.tasty.{TastyName, Signature, TastyFlags}, TastyName.SignedName, Signature.MethodSignature, TastyFlags._ import scala.tools.tasty.ErasedTypeRef @@ -74,7 +74,7 @@ trait SymbolOps { self: TastyUniverse => def isTraitParamAccessor: Boolean = sym.owner.isTrait && repr.tflags.is(FieldAccessor|ParamSetter) def isParamGetter: Boolean = - sym.isMethod && sym.repr.tflags.is(FlagSets.ParamGetter) + sym.isMethod && repr.tflags.is(FlagSets.ParamGetter) /** A computed property that should only be called on a symbol which is known to have been initialised by the * Tasty Unpickler and is not yet completed. @@ -84,7 +84,7 @@ trait SymbolOps { self: TastyUniverse => def repr: TastyRepr = { try sym.rawInfo.asInstanceOf[TastyRepr] catch { - case err: ClassCastException => + case _: ClassCastException => val raw = u.showRaw(sym.rawInfo) val tastyRepr = u.typeOf[TastyRepr] throw new AssertionError(s"$sym is already completed. Expected $tastyRepr, is $raw.") @@ -123,9 +123,9 @@ trait SymbolOps { self: TastyUniverse => def symIsExperimental(sym: Symbol) = sym.hasAnnotation(defn.ExperimentalAnnotationClass) /** if isConstructor, make sure it has one non-implicit parameter list */ - def normalizeIfConstructor(owner: Symbol, termParamss: List[List[Symbol]], paramClauses: List[List[NoCycle]], isConstructor: Boolean): List[List[Symbol]] = + def normalizeIfConstructor(@unused owner: Symbol, termParamss: List[List[Symbol]], paramClauses: List[List[NoCycle]], isConstructor: Boolean): List[List[Symbol]] = if (!isConstructor) termParamss - else { + else paramClauses match { case (vparam :: _) :: _ if vparam.tflags.is(Implicit, butNot=Given) => Nil :: termParamss case _ => @@ -135,7 +135,6 @@ trait SymbolOps { self: TastyUniverse => termParamss } } - } private[bridge] def lookupSymbol(space: Type, tname: TastyName)(implicit ctx: Context): Symbol = { deepComplete(space) @@ -168,7 +167,7 @@ trait SymbolOps { self: TastyUniverse => } if (isSymbol(member) && hasType(member)) member else if (ctx.isJava && space.termSymbol.isModule && !space.termSymbol.hasPackageFlag) { - // TODO [tasty]: remove this workaround for https://github.com/lampepfl/dotty/issues/19619 + // TODO [tasty]: remove this workaround for https://github.com/scala/scala3/issues/19619 // Use heuristic that we are accidentally looking in the static scope for some class/object, // when really we should be looking in the instance scope. In this case, we should be always looking for // the class and not the object, so we convert to type name and look in the companion. diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/TastyCore.scala b/src/compiler/scala/tools/nsc/tasty/bridge/TastyCore.scala index 01ca7a60fffe..a3021c417849 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/TastyCore.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/TastyCore.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala index 5ef1d094c0dd..957fa37be8d6 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala index faef3e5312b9..b10929e769af 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -339,15 +339,15 @@ trait TypeOps { self: TastyUniverse => case _ => tp } prefix match { - case pre: u.TypeRef => processInner(u.typeRef(prefix, sym, Nil)) // e.g. prefix is `Foo[Int]` - case _ => processInner(sym.tpeHK) // ignore prefix otherwise + case _: u.TypeRef => processInner(u.typeRef(prefix, sym, Nil)) // e.g. prefix is `Foo[Int]` + case _ => processInner(sym.tpeHK) // ignore prefix otherwise } } else if (sym.isType) { prefix match { - case tp: u.ThisType if !sym.isTypeParameter => u.typeRef(prefix, sym, Nil) - case _:u.SingleType | _:u.RefinedType => u.typeRef(prefix, sym, Nil) - case _ => u.appliedType(sym, Nil) + case _: u.ThisType if !sym.isTypeParameter => u.typeRef(prefix, sym, Nil) + case _:u.SingleType | _:u.RefinedType => u.typeRef(prefix, sym, Nil) + case _ => u.appliedType(sym, Nil) } } else { // is a term @@ -457,7 +457,7 @@ trait TypeOps { self: TastyUniverse => * Do the same for by name types => From[T] and => To[T] */ def translateParameterized(self: Type)(from: u.ClassSymbol, to: u.ClassSymbol, wildcardArg: Boolean): Type = self match { - case self @ u.NullaryMethodType(tp) => + case u.NullaryMethodType(tp) => u.NullaryMethodType(translateParameterized(tp)(from, to, wildcardArg = false)) case _ => if (self.typeSymbol.isSubClass(from)) { @@ -538,7 +538,7 @@ trait TypeOps { self: TastyUniverse => } /** A synthetic type `scala.&` which accepts two type arguments, representing an intersection type - * @see https://github.com/lampepfl/dotty/issues/7688 + * @see https://github.com/scala/scala3/issues/7688 */ case object AndTpe extends Type diff --git a/src/compiler/scala/tools/nsc/tasty/package.scala b/src/compiler/scala/tools/nsc/tasty/package.scala index a490d74d6ede..df5f040af058 100644 --- a/src/compiler/scala/tools/nsc/tasty/package.scala +++ b/src/compiler/scala/tools/nsc/tasty/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala index 17f2027dbb37..e4089db46958 100644 --- a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala +++ b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -10,8 +10,6 @@ * additional information regarding copyright ownership. */ -// Copyright 2005-2017 LAMP/EPFL and Lightbend, Inc - package scala.tools.nsc package transform @@ -328,7 +326,7 @@ trait AccessorSynthesis extends Transform with ast.TreeDSL { // TODO is this case ever hit? constructors does not generate Assigns with EmptyTree for the rhs AFAICT // !!! Ident(self) is never referenced, is it supposed to be confirming // that self is anything in particular? - case Apply(lhs@Select(Ident(self), _), EmptyTree.asList) if lhs.symbol.isSetter => Nil + case Apply(lhs@Select(Ident(_), _), EmptyTree.asList) if lhs.symbol.isSetter => Nil case stat => List(stat) } diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 260053b69cb6..b80330d8bc0a 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -220,8 +220,8 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL { case _ => false } def typesMatchUpdate = paramTypes match { - case List(tp1, tp2) => (tp1 <:< IntTpe) && isMaybeUnit - case _ => false + case List(tp1, _) => (tp1 <:< IntTpe) && isMaybeUnit + case _ => false } (methSym.name == nme.length && params.isEmpty) || @@ -518,9 +518,9 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL { classTagEvidence.attachments.get[analyzer.MacroExpansionAttachment] match { case Some(att) if att.expandee.symbol.name == nme.materializeClassTag && tree.isInstanceOf[ApplyToImplicitArgs] => super.transform(arg) - case _ => + case _ => typedWithPos(tree.pos) { - gen.evalOnce(classTagEvidence, currentOwner, unit) { ev => + gen.evalOnce(classTagEvidence, currentOwner, unit) { _ => val arr = typedWithPos(tree.pos)(gen.mkMethodCall(classTagEvidence, definitions.ClassTagClass.info.decl(nme.newArray), Nil, Literal(Constant(elems.size)) :: Nil)) gen.evalOnce(arr, currentOwner, unit) { arr => val stats = ListBuffer[Tree]() @@ -553,7 +553,7 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL { ).transform(this) // (a, b, c) ~> new ::(a, new ::(b, new ::(c, Nil))) but only for reference types - case StripCast(Apply(appMeth @ Select(appQual, _), List(Apply(wrapArrayMeth, List(StripCast(rest @ ArrayValue(elemtpt, _))))))) + case StripCast(Apply(appMeth @ Select(_, _), List(Apply(wrapArrayMeth, List(StripCast(rest @ ArrayValue(elemtpt, _))))))) if wrapArrayMeth.symbol == currentRun.runDefinitions.wrapVarargsRefArrayMethod && currentRun.runDefinitions.isSeqApply(appMeth) // includes List && rest.elems.lengthIs < transformListApplyLimit @@ -646,7 +646,7 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL { * And, finally, be advised - Scala's Symbol literal (scala.Symbol) and the Symbol class of the compiler * have little in common. */ - case Apply(Select(qual, _), (arg @ Literal(Constant(symname: String))) :: Nil) + case Apply(Select(qual, _), (arg @ Literal(Constant(_: String))) :: Nil) if fun.symbol == Symbol_apply && !currentClass.isTrait && treeInfo.isQualifierSafeToElide(qual) => treeCopy.ApplyDynamic(tree, atPos(fun.pos)(Ident(SymbolLiteral_dummy).setType(SymbolLiteral_dummy.info)), LIT(SymbolLiteral_bootstrap) :: arg :: Nil).transform(this) diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index ce3ddf8aaf21..cde7623ec881 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,8 @@ package scala.tools.nsc package transform -import scala.collection.mutable +import scala.annotation._ +import scala.collection.mutable, mutable.ListBuffer import scala.reflect.internal.util.ListOfNil import scala.tools.nsc.Reporting.WarningCategory import symtab.Flags._ @@ -28,8 +29,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme /** the following two members override abstract members in Transform */ val phaseName: String = "constructors" - protected def newTransformer(unit: CompilationUnit): AstTransformer = - new ConstructorTransformer(unit) + protected def newTransformer(unit: CompilationUnit): AstTransformer = new ConstructorTransformer(unit) private val guardedCtorStats: mutable.Map[Symbol, List[Tree]] = perRunCaches.newMap[Symbol, List[Tree]]() private val ctorParams: mutable.Map[Symbol, List[Symbol]] = perRunCaches.newMap[Symbol, List[Symbol]]() @@ -81,10 +81,10 @@ abstract class Constructors extends Statics with Transform with TypingTransforme override def transform(tree: Tree): Tree = { tree match { - case cd @ ClassDef(mods0, name0, tparams0, impl0) if !isPrimitiveValueClass(cd.symbol) && cd.symbol.primaryConstructor != NoSymbol => - if(cd.symbol eq AnyValClass) { + case cd @ ClassDef(mods0, name0, tparams0, impl0) + if !isPrimitiveValueClass(cd.symbol) && cd.symbol.primaryConstructor != NoSymbol => + if (cd.symbol eq AnyValClass) cd - } else { checkUninitializedReads(cd) val tplTransformer = new TemplateTransformer(unit, impl0) @@ -154,11 +154,11 @@ abstract class Constructors extends Statics with Transform with TypingTransforme * Finally, the whole affair of eliding is avoided for DelayedInit subclasses, * given that for them usually nothing gets elided anyway. * That's a consequence from re-locating the post-super-calls statements from their original location - * (the primary constructor) into a dedicated synthetic method that an anon-closure may invoke, as required by DelayedInit. - * + * (the primary constructor) into a dedicated synthetic method that an anon-closure may invoke, + * as required by DelayedInit. */ private trait OmittablesHelper { - def computeOmittableAccessors(clazz: Symbol, defs: List[Tree], auxConstructors: List[Tree], constructor: List[Tree]): Set[Symbol] = { + def computeOmittableAccessors(clazz: Symbol, defs: List[Tree], auxConstructors: List[Tree], @unused constructor: List[Tree]): Set[Symbol] = { val decls = clazz.info.decls.toSet val isEffectivelyFinal = clazz.isEffectivelyFinal @@ -250,7 +250,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme * * @return the DefDef for (c) above * - * */ + */ private trait DelayedInitHelper extends ConstructorTransformerBase { private def delayedEndpointDef(stats: List[Tree]): DefDef = { val methodName = currentUnit.freshTermName("delayedEndpoint$" + clazz.fullNameAsName('$').toString + "$") @@ -306,7 +306,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme } /** For a DelayedInit subclass, wrap remainingConstrStats into a DelayedInit closure. */ - def delayedInitDefsAndConstrStats(defs: List[Tree], remainingConstrStats: List[Tree]): (List[Tree], List[Tree]) = { + def delayedInitDefsAndConstrStats(@unused defs: List[Tree], remainingConstrStats: List[Tree]): (List[Tree], List[Tree]) = { val delayedHook = delayedEndpointDef(remainingConstrStats) val delayedHookSym = delayedHook.symbol.asInstanceOf[MethodSymbol] @@ -336,7 +336,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme * `specializedStats` are replaced by the specialized assignment. */ private def mergeConstructors(genericClazz: Symbol, originalStats: List[Tree], specializedStats: List[Tree]): List[Tree] = { - val specBuf = new mutable.ListBuffer[Tree] + val specBuf = ListBuffer.empty[Tree] specBuf ++= specializedStats def specializedAssignFor(sym: Symbol): Option[Tree] = @@ -355,7 +355,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme val arrayUpdateMethod = currentRun.runDefinitions.arrayUpdateMethod val adapter = new AstTransformer { override def transform(t: Tree): Tree = t match { - case Apply(fun @ Select(receiver, method), List(xs, idx, v)) if fun.symbol == arrayUpdateMethod => + case Apply(fun @ Select(_, _), List(xs, idx, v)) if fun.symbol == arrayUpdateMethod => localTyper.typed(Apply(gen.mkAttributedSelect(xs, arrayUpdateMethod), List(idx, v))) case _ => super.transform(t) } @@ -458,18 +458,20 @@ abstract class Constructors extends Statics with Transform with TypingTransforme { protected def typedPos(pos: Position)(tree: Tree): Tree = localTyper.typedPos(pos)(tree) - val clazz = impl.symbol.owner // the transformed class - - val isDelayedInitSubclass = clazz isSubClass DelayedInitClass - - private val stats = impl.body // the transformed template body + override val clazz = impl.symbol.owner // the transformed class + private val stats = impl.body // the transformed template body + private val isDelayedInitSubclass = clazz isSubClass DelayedInitClass // find and dissect primary constructor - private val (primaryConstr, _primaryConstrParams, primaryConstrBody) = stats collectFirst { - case dd@DefDef(_, _, _, vps :: Nil, _, rhs: Block) if dd.symbol.isPrimaryConstructor => (dd, vps map (_.symbol), rhs) - } getOrElse { - abort("no constructor in template: impl = " + impl) - } + private val (primaryConstr, _primaryConstrParams, primaryConstrBody) = + stats.collectFirst { + case dd @ DefDef(_, _, _, vps :: Nil, _, rhs: Block) + if dd.symbol.isPrimaryConstructor => + (dd, vps.map(_.symbol), rhs) + } + .getOrElse { + abort("no constructor in template: impl = " + impl) + } def primaryConstrParams = _primaryConstrParams def usesSpecializedField = intoConstructor.usesSpecializedField @@ -477,7 +479,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme // The constructor parameter corresponding to an accessor def parameter(acc: Symbol): Symbol = { //works around the edge case where unexpandedName over-unexpands shenanigans like literal $$ or `$#` - def unexpanded = parameterNamed(acc.unexpandedName.getterName) + val unexpanded = parameterNamed(acc.unexpandedName.getterName) def expanded = parameterNamed(acc.getterName) unexpanded.orElse(expanded).swap.map(abort).merge } @@ -493,15 +495,14 @@ abstract class Constructors extends Statics with Transform with TypingTransforme // A transformer for expressions that go into the constructor object intoConstructor extends AstTransformer { - /* - * `usesSpecializedField` makes a difference in deciding whether constructor-statements - * should be guarded in a `guardSpecializedFieldInit` class, ie in a class that's the generic super-class of - * one or more specialized sub-classes. - * - * Given that `usesSpecializedField` isn't read for any other purpose than the one described above, - * we skip setting `usesSpecializedField` in case the current class isn't `guardSpecializedFieldInit` to start with. - * That way, trips to a map in `specializeTypes` are saved. - */ + /* `usesSpecializedField` makes a difference in deciding whether constructor-statements + * should be guarded in a `guardSpecializedFieldInit` class, ie in a class that's the generic super-class of + * one or more specialized sub-classes. + * + * Given that `usesSpecializedField` isn't read for any other purpose than the one described above, + * we skip setting `usesSpecializedField` in case the current class isn't `guardSpecializedFieldInit` + * to start with. That way, trips to a map in `specializeTypes` are saved. + */ var usesSpecializedField: Boolean = false private def isParamRef(sym: Symbol) = sym.isParamAccessor && sym.owner == clazz @@ -514,8 +515,9 @@ abstract class Constructors extends Statics with Transform with TypingTransforme !sym.isVariable ) - /* - * whether `sym` denotes a param-accessor (ie in a class a PARAMACCESSOR field, or in a trait a method with same flag) + /* whether `sym` denotes a param-accessor + * (ie in a class a PARAMACCESSOR field, or in a trait a method with same flag) + * * that fulfills all of: * (a) has stationary value, ie the same value provided via the corresponding ctor-arg; and * (b) isn't subject to specialization. We might be processing statements for: @@ -530,7 +532,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme // references to parameter accessor methods of own class become references to parameters // outer accessors become references to $outer parameter // println(s"to param ref in $clazz for ${tree.symbol} ${tree.symbol.debugFlagString} / ${tree.symbol.outerSource} / ${canBeSupplanted(tree.symbol)}") - if (clazz.isTrait && !(tree.symbol hasAllFlags (ACCESSOR | PARAMACCESSOR))) + if (clazz.isTrait && !tree.symbol.hasAllFlags(ACCESSOR | PARAMACCESSOR)) super.transform(tree) else if (canBeSupplanted(tree.symbol)) gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos @@ -593,7 +595,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme * - `classInitStats`: statements that go into the class initializer */ class Triage { - private val defBuf, auxConstructorBuf, constrPrefixBuf, constrStatBuf, classInitStatBuf = new mutable.ListBuffer[Tree] + private val defBuf, auxConstructorBuf, constrPrefixBuf, constrStatBuf, classInitStatBuf = ListBuffer.empty[Tree] triage() @@ -605,7 +607,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme private def triage() = { // Constant typed vals are not memoized. - def memoizeValue(sym: Symbol) = !sym.info.resultType.isInstanceOf[FoldableConstantType] + def memoizeValue(sym: Symbol) = enteringErasure(!sym.info.resultType.isInstanceOf[FoldableConstantType]) // The early initialized field definitions of the class (these are the class members) val presupers = treeInfo.preSuperFields(stats) @@ -616,8 +618,15 @@ abstract class Constructors extends Statics with Transform with TypingTransforme stat match { case ValDef(mods, name, _, _) if mods.hasFlag(PRESUPER) => // TODO trait presupers // stat is the constructor-local definition of the field value - val fields = presupers filter (_.getterName == name) - assert(fields.length == 1, s"expected exactly one field by name $name in $presupers of $clazz's early initializers") + val fields = presupers.filter { v => + val nm = + if (v.symbol.isPrivateLocal && v.symbol.hasFlag(EXPANDEDNAME)) + v.symbol.unexpandedName.dropLocal + else + v.getterName + nm == name + } + assert(fields.length == 1, s"expected exactly one field by name $name in $presupers of $clazz's early initializers but saw $fields") val to = fields.head.symbol if (memoizeValue(to)) constrStatBuf += mkAssign(to, Ident(stat.symbol)) @@ -668,7 +677,8 @@ abstract class Constructors extends Statics with Transform with TypingTransforme // - the constructor, before the super call (early initialized or a parameter accessor), // - the constructor, after the super call (regular val). case vd: ValDef => - if (vd.rhs eq EmptyTree) { defBuf += vd } + if (vd.rhs eq EmptyTree) + defBuf += vd else { val emitField = memoizeValue(statSym) @@ -680,14 +690,22 @@ abstract class Constructors extends Statics with Transform with TypingTransforme case dd: DefDef => // either move the RHS to ctor (for getter of stored field) or just drop it (for corresponding setter) - def shouldMoveRHS = - clazz.isTrait && statSym.isAccessor && !statSym.isLazy && !statSym.isSpecialized && (statSym.isSetter || memoizeValue(statSym)) - - if ((dd.rhs eq EmptyTree) || !shouldMoveRHS) { defBuf += dd } - else { - if (statSym.isGetter) moveEffectToCtor(dd.mods, dd.rhs, statSym.asTerm.referenced orElse statSym.setterIn(clazz)) - defBuf += deriveDefDef(stat)(_ => EmptyTree) - } + def shouldMoveRHS = ( + (dd.rhs ne EmptyTree) + && clazz.isTrait + && statSym.isAccessor + && !statSym.isLazy + && !statSym.isSpecialized + && (statSym.isSetter || memoizeValue(statSym)) + ) + val toMove = + if (shouldMoveRHS) { + if (statSym.isGetter) + moveEffectToCtor(dd.mods, dd.rhs, statSym.asTerm.referenced.orElse(statSym.setterIn(clazz))) + deriveDefDef(stat)(_ => EmptyTree) + } + else dd + defBuf += toMove // all other statements go into the constructor case _ => @@ -716,19 +734,22 @@ abstract class Constructors extends Statics with Transform with TypingTransforme else clazz.constrParamAccessors // Initialize all parameters fields that must be kept. - val paramInits = paramAccessors filterNot omittableSym map { acc => + val paramInits = paramAccessors.filterNot(omittableSym).map { acc => // Check for conflicting field mixed in for a val/var defined in a parent trait (neg/t1960.scala). // Since the fields phase has already mixed in fields, we can just look for // an existing decl with the local variant of our paramaccessor's name. // - // TODO: mangle the constructor parameter name (it can only be used internally), though we probably first need more robust name mangling + // TODO: mangle the constructor parameter name (it can only be used internally), + // though we probably first need more robust name mangling // sometimes acc is a field with a local name (when it's a val/var constructor param) --> exclude the `acc` itself when looking for conflicting decl // sometimes it's not (just a constructor param) --> any conflicting decl is a problem val conflict = clazz.info.decl(acc.name.localName).filter(sym => sym ne acc) if (conflict ne NoSymbol) { val orig = exitingTyper(clazz.info.nonPrivateMember(acc.name).filter(_ hasFlag ACCESSOR)) - reporter.error(acc.pos, s"parameter '${acc.name}' requires field but conflicts with ${(orig orElse conflict).fullLocationString}") + reporter.error(acc.pos, s"parameter '${acc.name}' requires field but conflicts with ${ + orig.orElse(conflict).fullLocationString + }") } val accSetter = @@ -776,7 +797,10 @@ abstract class Constructors extends Statics with Transform with TypingTransforme ) } - if ((exitingPickler(clazz.isAnonymousClass) || clazz.originalOwner.isTerm) && omittableAccessor.exists(_.isOuterField) && !constructorStats.exists(_.exists { case i: Ident if i.symbol.isOuterParam => true; case _ => false})) + if ((exitingPickler(clazz.isAnonymousClass) || clazz.originalOwner.isTerm) + && omittableAccessor.exists(_.isOuterField) + && !constructorStats.exists(_.exists { case i: Ident if i.symbol.isOuterParam => true case _ => false }) + ) primaryConstructor.symbol.updateAttachment(OuterArgCanBeElided) val constructors = primaryConstructor :: auxConstructors @@ -788,7 +812,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme // Eliminate all field/accessor definitions that can be dropped from template // We never eliminate delayed hooks or the constructors, so, only filter `defs`. - val prunedStats = (defs filterNot omittableStat) ::: delayedHookDefs ::: constructors + val prunedStats = defs.filterNot(omittableStat) ::: delayedHookDefs ::: constructors val statsWithInitChecks = if (settings.checkInit.value) { diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 30cb0abbf60e..59daa51171ae 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,6 +15,7 @@ package transform import symtab._ import Flags._ +import scala.annotation._ import scala.collection.mutable /** @@ -42,10 +43,9 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre final case class LambdaMetaFactoryCapable(lambdaTarget: Symbol, arity: Int, functionalInterface: Symbol, sam: Symbol, bridges: List[Symbol], isSerializable: Boolean) - /** - * Get the symbol of the target lifted lambda body method from a function. I.e. if - * the function is {args => anonfun(args)} then this method returns anonfun's symbol - */ + /** Get the symbol of the target lifted lambda body method from a function. I.e. if + * the function is {args => anonfun(args)} then this method returns anonfun's symbol + */ private def targetMethod(fun: Function): Symbol = fun match { case Function(_, Apply(target, _)) => target.symbol case _ => @@ -148,7 +148,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre } // determine which lambda target to use with java's LMF -- create a new one if scala-specific boxing is required - def createBoxingBridgeMethodIfNeeded(fun: Function, target: Symbol, functionalInterface: Symbol, sam: Symbol): Symbol = { + def createBoxingBridgeMethodIfNeeded(fun: Function, target: Symbol, @unused functionalInterface: Symbol, sam: Symbol): Symbol = { val oldClass = fun.symbol.enclClass val pos = fun.pos @@ -176,9 +176,11 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val resTpOk = ( samResultType =:= UnitTpe || functionResultType =:= samResultType - || (isReferenceType(samResultType) && isReferenceType(functionResultType))) // yes, this is what the spec says -- no further correspondence required - if (resTpOk && (samParamTypes corresponds functionParamTypes){ (samParamTp, funParamTp) => - funParamTp =:= samParamTp || (isReferenceType(funParamTp) && isReferenceType(samParamTp) && funParamTp <:< samParamTp) }) target + || (isReferenceType(samResultType) && isReferenceType(functionResultType))) // per spec, no further correspondence required + def paramTpsOk = samParamTypes.corresponds(functionParamTypes)((samParamTp, funParamTp) => + funParamTp =:= samParamTp || + (isReferenceType(funParamTp) && isReferenceType(samParamTp) && funParamTp <:< samParamTp)) + if (resTpOk && paramTpsOk) target else { // We have to construct a new lambda target that bridges to the one created by uncurry. // The bridge must satisfy the above invariants, while also minimizing adaptation on our end. @@ -193,7 +195,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre // which means the function's parameter -- even if it expects a value class -- will need to be // boxed on the generic call to the sam method. - val bridgeParamTypes = map2(samParamTypes, functionParamTypes){ (samParamTp, funParamTp) => + val bridgeParamTypes = map2(samParamTypes, functionParamTypes) { (samParamTp, funParamTp) => if (isReferenceType(samParamTp) && funParamTp <:< samParamTp) funParamTp else postErasure.elimErasedValueType(samParamTp) } @@ -242,9 +244,12 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre gen.mkMethodCall(Select(gen.mkAttributedThis(oldClass), target), capturedArgRefs ::: functionArgRefs) } + val forwarderResultType = + if (samResultType.isInstanceOf[ErasedValueType] && functionResultType.isInstanceOf[ErasedValueType]) bridgeResultType + else functionResultType val bridge = postErasure.newTransformer(unit).transform(DefDef(methSym, List(bridgeParams.map(ValDef(_))), - adaptToType(forwarderCall setType functionResultType, bridgeResultType))).asInstanceOf[DefDef] + adaptToType(forwarderCall.setType(forwarderResultType), bridgeResultType))).asInstanceOf[DefDef] boxingBridgeMethods += bridge bridge.symbol diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 49ca77d72b3d..77d568b2e6c2 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,7 @@ package scala.tools.nsc package transform -import scala.annotation.tailrec +import scala.annotation._ import scala.reflect.internal.ClassfileConstants._ import scala.collection.{immutable, mutable} import symtab._ @@ -33,7 +33,7 @@ abstract class Erasure extends InfoTransform val phaseName: String = "erasure" - val requiredDirectInterfaces = perRunCaches.newAnyRefMap[Symbol, mutable.Set[Symbol]]() + val requiredDirectInterfaces = perRunCaches.newMap[Symbol, mutable.Set[Symbol]]() def newTransformer(unit: CompilationUnit): AstTransformer = new ErasureTransformer(unit) @@ -42,7 +42,7 @@ abstract class Erasure extends InfoTransform // -------- erasure on types -------------------------------------------------------- - // convert a numeric with a toXXX method + // convert a numeric with a toNNN method def numericConversion(tree: Tree, numericSym: Symbol): Tree = { val mname = newTermName("to" + numericSym.name) val conversion = tree.tpe member mname @@ -90,12 +90,17 @@ abstract class Erasure extends InfoTransform } } @tailrec - private[this] def untilApply(ts: List[Type]): Unit = - if (! ts.isEmpty && ! result) { apply(ts.head) ; untilApply(ts.tail) } + private def untilApply(ts: List[Type]): Unit = + ts match { + case t :: ts if !result => + apply(t) + untilApply(ts) + case _ => + } } override protected def verifyJavaErasure = settings.Xverify.value || settings.isDebug - private def needsJavaSig(sym: Symbol, tp: Type, throwsArgs: List[Type]) = !settings.Ynogenericsig.value && { + def needsJavaSig(sym: Symbol, tp: Type, throwsArgs: List[Type]) = !settings.Ynogenericsig.value && { def needs(tp: Type) = NeedsSigCollector(sym.isClassConstructor).collect(tp) needs(tp) || throwsArgs.exists(needs) } @@ -117,9 +122,9 @@ abstract class Erasure extends InfoTransform * is the same as the erased type that's generated. Normalization means * unboxing some primitive types and further simplifications as they are done in jsig. */ - val prepareSigMap = new TypeMap { + val prepareSigMap: TypeMap = new TypeMap { def squashBoxed(tp: Type): Type = tp.dealiasWiden match { - case t @ RefinedType(parents, decls) => + case RefinedType(parents, decls) => val parents1 = parents mapConserve squashBoxed if (parents1 eq parents) tp else RefinedType(parents1, decls) @@ -227,7 +232,7 @@ abstract class Erasure extends InfoTransform // a signature should always start with a class def ensureClassAsFirstParent(tps: List[Type]) = tps match { case Nil => ObjectTpe :: Nil - case head :: tail if isInterfaceOrTrait(head.typeSymbol) => ObjectTpe :: tps + case head :: _ if isInterfaceOrTrait(head.typeSymbol) => ObjectTpe :: tps case _ => tps } @@ -293,7 +298,7 @@ abstract class Erasure extends InfoTransform } else builder.append('*') } else tp match { - case PolyType(_, res) => + case PolyType(_, _) => builder.append('*') // scala/bug#7932 case _ => boxedSig(tp) @@ -415,7 +420,7 @@ abstract class Erasure extends InfoTransform } Some(builder.toString) } - catch { case ex: UnknownSig => None } + catch { case _: UnknownSig => None } } else None } @@ -478,7 +483,7 @@ abstract class Erasure extends InfoTransform override def newTyper(context: Context) = new Eraser(context) - class EnterBridges(unit: CompilationUnit, root: Symbol) { + class EnterBridges(@unused unit: CompilationUnit, root: Symbol) { val site = root.thisType val bridgesScope = newScope val bridgeTarget = mutable.HashMap[Symbol, Symbol]() @@ -595,7 +600,7 @@ abstract class Erasure extends InfoTransform def bridgeMayClash = other.paramss.exists(_.exists(_.tpe match { case TypeRef(_, r, _) => r.isTypeParameter case _ => false })) def bridgeIsAOK = checkBridgeOverrides(member, other, bridge) match { case Nil => true - case es if member.owner.isAnonymousClass => resolveAnonymousBridgeClash(member, bridge); true + case _ if member.owner.isAnonymousClass => resolveAnonymousBridgeClash(member, bridge); true case es => for ((pos, msg) <- es) reporter.error(pos, msg); false } !sigContainsValueClass && !bridgeMayClash || bridgeIsAOK @@ -715,7 +720,7 @@ abstract class Erasure extends InfoTransform } } else treeCopy.Apply(tree, treeCopy.TypeApply(ta, treeCopy.Select(sel, qual1, name), List(targ)), List()) - case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) + case Apply(TypeApply(Select(_, _), List(targ)), List()) if tree.symbol == Any_isInstanceOf => targ.tpe match { case ErasedValueType(clazz, _) => targ.setType(clazz.tpe) @@ -795,9 +800,10 @@ abstract class Erasure extends InfoTransform /** A replacement for the standard typer's `typed1` method. */ override def typed1(tree: Tree, mode: Mode, pt: Type): Tree = { - val tree1 = try { + val tree1 = try tree match { - case DefDef(_,_,_,_,_,_) if tree.symbol.isClassConstructor && tree.symbol.isPrimaryConstructor && tree.symbol.owner != ArrayClass => + case tree: DefDef + if tree.symbol.isClassConstructor && tree.symbol.isPrimaryConstructor && tree.symbol.owner != ArrayClass => super.typed1(deriveDefDef(tree)(addMixinConstructorCalls(_, tree.symbol.owner)), mode, pt) // (3) case Template(parents, self, body) => val parents1 = tree.symbol.owner.info.parents map (t => TypeTree(t) setPos tree.pos) @@ -820,16 +826,14 @@ abstract class Erasure extends InfoTransform case _ => super.typed1(adaptMember(tree), mode, pt) } - } catch { + catch { case er: TypeError => Console.println("exception when typing " + tree+"/"+tree.getClass) Console.println(er.msg + " in file " + context.owner.sourceFile) er.printStackTrace abort("unrecoverable error") case ex: Exception => - //if (settings.debug.value) - try Console.println("exception when typing " + tree) - finally throw ex + try Console.println(s"exception when typing $tree") catch identity: @nowarn throw ex } @@ -846,7 +850,6 @@ abstract class Erasure extends InfoTransform case Some(SAMFunction(samTp, _, _)) => fun setType specialScalaErasure(samTp) case _ => fun } - case If(cond, thenp, elsep) => treeCopy.If(tree1, cond, adaptBranch(thenp), adaptBranch(elsep)) case Match(selector, cases) => @@ -858,7 +861,7 @@ abstract class Erasure extends InfoTransform val first = tree1.symbol.alternatives.head val firstTpe = first.tpe val sym1 = tree1.symbol.filter { - alt => alt == first || !(firstTpe looselyMatches alt.tpe) + alt => alt == first || !firstTpe.looselyMatches(alt.tpe) } if (tree.symbol ne sym1) { tree1 setSymbol sym1 setType sym1.tpe @@ -884,13 +887,15 @@ abstract class Erasure extends InfoTransform else if (low.owner == base) "name clash between defined and inherited member" else "name clash between inherited members" ) - val when = if (exitingRefchecks(lowType matches highType)) "" else " after erasure: " + exitingPostErasure(highType) + val when = + if (exitingRefchecks(lowType matches highType)) "" + else s" after erasure: ${exitingPostErasure(highType)}" reporter.error(pos, - s"""|$what: - |${exitingRefchecks(highString)} and - |${exitingRefchecks(lowString)} - |have same type$when""".trim.stripMargin + sm"""|$what: + |${exitingRefchecks(highString)} and + |${exitingRefchecks(lowString)} + |have same type$when""" ) } low setInfo ErrorType @@ -1003,7 +1008,7 @@ abstract class Erasure extends InfoTransform * - Remove all instance creations new C(arg) where C is an inlined class. * - Reset all other type attributes to null, thus enforcing a retyping. */ - private val preTransformer = new TypingTransformer(unit) { + private val preTransformer: TypingTransformer = new TypingTransformer(unit) { // Work around some incomplete path unification :( there are similar casts in SpecializeTypes def context: Context = localTyper.context.asInstanceOf[Context] @@ -1195,7 +1200,7 @@ abstract class Erasure extends InfoTransform global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen)))) } else if (primitiveGetClassMethods.contains(fn.symbol)) { // if we got here then we're trying to send a primitive getClass method to either - // a) an Any, in which cage Object_getClass works because Any erases to object. Or + // a) an Any, in which case Object_getClass works because Any erases to object. Or // // b) a non-primitive, e.g. because the qualifier's type is a refinement type where one parent // of the refinement is a primitive and another is AnyRef. In that case @@ -1226,10 +1231,11 @@ abstract class Erasure extends InfoTransform case tree: Apply => preEraseApply(tree) - case TypeApply(fun, args) if (fun.symbol.owner != AnyClass && - fun.symbol != Object_asInstanceOf && - fun.symbol != Object_isInstanceOf && - fun.symbol != Object_synchronized) => + case TypeApply(fun, args) + if fun.symbol.owner != AnyClass + && fun.symbol != Object_asInstanceOf + && fun.symbol != Object_isInstanceOf + && fun.symbol != Object_synchronized => // leave all other type tests/type casts, remove all other type applications preErase(fun) @@ -1287,9 +1293,11 @@ abstract class Erasure extends InfoTransform if (qualSym != owner) tree.updateAttachment(new QualTypeSymAttachment(qualSym)) - } else if (!isJvmAccessible(owner, context)) { + } else if (!isJvmAccessible(owner, context) || + // scala/bug#13007: isJvmAccessible is true for a protected java method, even if accessed through erased self type + sym.isJavaDefined && sym.isProtected && !qual.tpe.typeSymbol.isSubClass(sym.owner)) { val qualSym = qual.tpe.typeSymbol - if (qualSym != owner && isJvmAccessible(qualSym, context) && definesMemberAfterErasure(qualSym, sym)) + if (qualSym != owner && isJvmAccessible(qualSym, context) && (definesMemberAfterErasure(qualSym, sym) || sym.overridingSymbol(qualSym).exists)) tree.updateAttachment(new QualTypeSymAttachment(qualSym)) else reporter.error(tree.pos, s"Unable to emit reference to ${sym.fullLocationString}, $owner is not accessible in ${context.enclClass.owner}") @@ -1370,7 +1378,7 @@ abstract class Erasure extends InfoTransform try super.transform(tree1).clearType() finally tpt setType specialErasure(tree1.symbol)(tree1.symbol.tpe).resultType - case ApplyDynamic(qual, Literal(Constant(bootstrapMethodRef: Symbol)) :: _) => + case ApplyDynamic(_, Literal(Constant(_: Symbol)) :: _) => tree case _: Apply if tree1 ne tree => /* some Apply trees get replaced (in `preEraseApply`) with one of diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 3971302b1c98..700bcf275d60 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -392,7 +392,7 @@ abstract class ExplicitOuter extends InfoTransform if (sym.isProtected && !sym.isJavaDefined) sym setFlag notPROTECTED } tree match { - case Template(parents, self, decls) => + case Template(_, _, _) => val newDefs = new ListBuffer[Tree] atOwner(tree, currentOwner) { if (!currentClass.isInterface) { @@ -468,7 +468,7 @@ abstract class ExplicitOuter extends InfoTransform // for the pattern matcher // base..eq(o) --> base.$outer().eq(o) if there's an accessor, else the whole tree becomes TRUE // TODO remove the synthetic `` method from outerFor?? - case Apply(eqsel@Select(eqapp@Apply(sel@Select(base, nme.OUTER_SYNTH), Nil), eq), args) => + case Apply(eqsel@Select(Apply(sel@Select(base, nme.OUTER_SYNTH), Nil), eq), args) => val outerFor = sel.symbol.owner val acc = outerAccessor(outerFor) diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 57c470e42c60..1b976e6cc164 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala index 88709c99ec2f..59821f87ee03 100644 --- a/src/compiler/scala/tools/nsc/transform/Fields.scala +++ b/src/compiler/scala/tools/nsc/transform/Fields.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,7 @@ package scala.tools.nsc package transform -import scala.annotation.tailrec +import scala.annotation._ import scala.reflect.internal.util.ListOfNil import symtab.Flags._ @@ -119,7 +119,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor } // TODO: add MIXEDIN (see e.g., `accessed` on `Symbol`) - private def setMixedinAccessorFlags(orig: Symbol, cloneInSubclass: Symbol): Unit = + private def setMixedinAccessorFlags(@unused orig: Symbol, cloneInSubclass: Symbol): Unit = cloneInSubclass setFlag OVERRIDE | NEEDS_TREES resetFlag DEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS private def setFieldFlags(accessor: Symbol, fieldInSubclass: TermSymbol): Unit = { @@ -375,7 +375,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor } else tp - case tp@ClassInfoType(parents, oldDecls, clazz) if !classNeedsInfoTransform(clazz) => tp + case tp@ClassInfoType(_, _, clazz) if !classNeedsInfoTransform(clazz) => tp // mix in fields & accessors for all mixed in traits case tp@ClassInfoType(parents, oldDecls, clazz) => diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index f3b1eeb83275..01cf08418f98 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala index c2d3a3849c81..f38a645ce56a 100644 --- a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala +++ b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index d95db7df73cc..cf5266fd953e 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 92a5b15b12cf..447e125eb9a4 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -404,7 +404,7 @@ abstract class Mixin extends Transform with ast.TreeDSL with AccessorSynthesis { // first complete the superclass with mixed in members addMixedinMembers(clazz.superClass, unit) - for (mc <- clazz.mixinClasses ; if mc.isTrait) { + for (mc <- clazz.mixinClasses if mc.isTrait) { // @SEAN: adding trait tracking so we don't have to recompile transitive closures unit.registerDependency(mc) publicizeTraitMethods(mc) @@ -427,7 +427,7 @@ abstract class Mixin extends Transform with ast.TreeDSL with AccessorSynthesis { private val rootContext = erasure.NoContext.make(EmptyTree, rootMirror.RootClass, newScope) - private val nullables = mutable.AnyRefMap[Symbol, Map[Symbol, List[Symbol]]]() + private val nullables = mutable.HashMap[Symbol, Map[Symbol, List[Symbol]]]() /** The first transform; called in a pre-order traversal at phase mixin * (that is, every node is processed before its children). @@ -616,7 +616,7 @@ abstract class Mixin extends Transform with ast.TreeDSL with AccessorSynthesis { val sym = tree.symbol tree match { - case templ @ Template(parents, self, body) => + case Template(parents, self, body) => // change parents of templates to conform to parents in the symbol info val parents1 = currentOwner.info.parents map (t => TypeTree(t) setPos tree.pos) diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala index fc9592732517..c2a495e2d0e4 100644 --- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala +++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala index 423d8a61944c..f24f52477b68 100644 --- a/src/compiler/scala/tools/nsc/transform/PostErasure.scala +++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala index 22b271ea7972..761a427b3f7b 100644 --- a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala +++ b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,6 +13,8 @@ package scala.tools.nsc package transform +import scala.annotation._ + /** A sample transform. */ abstract class SampleTransform extends Transform { @@ -27,7 +29,7 @@ abstract class SampleTransform extends Transform { protected def newTransformer(unit: CompilationUnit): AstTransformer = new SampleTransformer(unit) - class SampleTransformer(unit: CompilationUnit) extends AstTransformer { + class SampleTransformer(@unused unit: CompilationUnit) extends AstTransformer { override def transform(tree: Tree): Tree = { val tree1 = super.transform(tree); // transformers always maintain `currentOwner`. diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 172bde0caa29..ce3ea681f147 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,8 +14,8 @@ package scala package tools.nsc package transform -import scala.annotation.{nowarn, tailrec} -import scala.collection.mutable, mutable.{AnyRefMap, Buffer, ListBuffer} +import scala.annotation._ +import scala.collection.mutable, mutable.{Buffer, HashMap, ListBuffer} import scala.tools.nsc.symtab.Flags import scala.tools.nsc.Reporting.WarningCategory import scala.util.chaining._ @@ -80,7 +80,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private implicit val typeOrdering: Ordering[Type] = Ordering[String] on ("" + _.typeSymbol.name) /** For a given class and concrete type arguments, give its specialized class */ - val specializedClass = perRunCaches.newAnyRefMap[Symbol, AnyRefMap[TypeEnv, Symbol]]() + val specializedClass = perRunCaches.newAnyRefMap[Symbol, HashMap[TypeEnv, Symbol]]() // read-only map, where missing value defaults to empty immutable.Map def specializationOf(sym: Symbol) = specializedClass.getOrElse(sym, Map.empty[TypeEnv, Symbol]) @@ -120,13 +120,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } - @annotation.tailrec private def findSymbol[T](candidates: List[T], f: T => Symbol): Symbol = { - if (candidates.isEmpty) NoSymbol - else f(candidates.head) match { - case NoSymbol => findSymbol(candidates.tail, f) - case sym => sym - } - } private def hasNewParents(tree: Tree) = { val parents = tree.symbol.info.parents val prev = enteringPrevPhase(tree.symbol.info.parents) @@ -153,7 +146,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { def fromSpecialization(sym: Symbol, args: List[Type]): TypeEnv = { ifDebug(assert(sym.info.typeParams.sizeCompare(args) == 0, "" + sym + " args: " + args)) - emptyEnv ++ collectMap2(sym.info.typeParams, args)((k, v) => k.isSpecialized) + emptyEnv ++ collectMap2(sym.info.typeParams, args)((k, _) => k.isSpecialized) } /** Does typeenv `t1` include `t2`? All type variables in `t1` @@ -263,7 +256,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } /** Symbol is a specialized accessor for the `target` field. */ - case class SpecializedAccessor(target: Symbol) extends SpecializedInfo { } + case class SpecializedAccessor(target: Symbol) extends SpecializedInfo /** Symbol is a specialized method whose body should be the target's method body. */ case class Implementation(target: Symbol) extends SpecializedInfo @@ -577,7 +570,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { */ private def mapAnyRefsInSpecSym(env: TypeEnv, origsym: Symbol, specsym: Symbol): TypeEnv = env transform { case (sym, AnyRefTpe) if sym.owner == origsym => typeParamSubAnyRef(sym, specsym) - case (k, v) => v + case (_, v) => v } /** Maps AnyRef bindings from a raw environment (holding AnyRefs) into type parameters from @@ -585,7 +578,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { */ private def mapAnyRefsInOrigCls(env: TypeEnv, origcls: Symbol): TypeEnv = env transform { case (sym, AnyRefTpe) if sym.owner == origcls => sym.tpe - case (k, v) => v + case (_, v) => v } /** Specialize 'clazz', in the environment `outerEnv`. The outer @@ -602,12 +595,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * was both already used for a map and mucho long. So "sClass" is the * specialized subclass of "clazz" throughout this file. */ - val clazzName = specializedName(clazz, env0).toTypeName // scala/bug#5545: Eliminate classes with the same name loaded from the bytecode already present - all we need to do is // to force .info on them, as their lazy type will be evaluated and the symbols will be eliminated. Unfortunately // evaluating the info after creating the specialized class will mess the specialized class signature, so we'd - // better unlink the the class-file backed symbol before creating the new class symbol + // better unlink the class-file backed symbol before creating the new class symbol val bytecodeClazz = clazz.owner.info.decl(clazzName) // debuglog("Specializing " + clazz + ", but found " + bytecodeClazz + " already there") def unlink(sym: Symbol): Unit = if (sym != NoSymbol) { @@ -638,7 +630,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val env = mapAnyRefsInSpecSym(env0, clazz, sClass) typeEnv(sClass) = env - specializedClass.getOrElseUpdate(clazz, AnyRefMap.empty).update(env0, sClass) + specializedClass.getOrElseUpdate(clazz, HashMap.empty).update(env0, sClass) val decls1 = newScope // declarations of the newly specialized class 'sClass' var oldClassTParams: List[Symbol] = Nil // original unspecialized type parameters @@ -844,7 +836,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { info(origGetter) = Forward(specGetter) enterMember(specGetter) enterMember(origGetter) - debuglog("specialize accessor in %s: %s -> %s".format(sClass.name.decode, origGetter.name.decode, specGetter.name.decode)) + debuglog(s"specialize accessor in ${sClass.name.decode}: ${origGetter.name.decode} -> ${specGetter.name.decode}") clazz.caseFieldAccessors.find(_.name.startsWith(m.name)) foreach { cfa => val cfaGetter = overrideIn(sClass, cfa) @@ -1115,7 +1107,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val alias = overriding.alias debuglog(s"checking special overload for super accessor: ${overriding.fullName}, alias for ${alias.fullName}") needsSpecialOverride(alias) match { - case nope @ (NoSymbol, _) => None + case (NoSymbol, _) => None case (overridden, env) => val om = specializedOverload(clazz, overriding, env, overridden) om.setName(nme.superName(om.name)) @@ -1194,7 +1186,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { unifyError(tp1, tp2) else env - case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) => + case (TypeRef(_, _, args1), TypeRef(_, _, args2)) => if (args1.nonEmpty || args2.nonEmpty) debuglog(s"Unify types $tp1 and $tp2") @@ -1537,10 +1529,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } /** Map a specializable method to its rhs, when not deferred. */ - val body = AnyRefMap.empty[Symbol, Tree] + val body = HashMap.empty[Symbol, Tree] /** Map a specializable method to its value parameter symbols. */ - val parameters = AnyRefMap.empty[Symbol, List[Symbol]] + val parameters = HashMap.empty[Symbol, List[Symbol]] /** Collect method bodies that are concrete specialized methods. */ @@ -1592,7 +1584,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val memberType = qual.tpe memberType member val residualTreeType = tree match { - case TypeApply(fun, targs) if fun.symbol == symbol => + case TypeApply(fun, _) if fun.symbol == symbol => // scala/bug#6308 Handle methods with only some type parameters specialized. // drop the specialized type parameters from the PolyType, and // substitute in the type environment. @@ -1651,7 +1643,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * specMe[Int, String](1, "2") => specMe\$mIc\$sp[String](1, "2") * }}} */ - def computeResidualTypeVars(baseTree: Tree, specMember: Symbol, specTree: Tree, baseTargs: List[Tree], env: TypeEnv): Tree = { + def computeResidualTypeVars(@unused baseTree: Tree, specMember: Symbol, specTree: Tree, baseTargs: List[Tree], env: TypeEnv): Tree = { val residualTargs = symbol.info.typeParams zip baseTargs collect { case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ } @@ -1715,7 +1707,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // def foo[@specialized T](t: T): T = t // foo(3) // TypeApply(Ident(foo), List(Int)) => foo$mIc$sp(3) // } - case TypeApply(sel @ Ident(name), targs) if name != nme.CONSTRUCTOR => + case TypeApply(Ident(name), targs) if name != nme.CONSTRUCTOR => val env = unify(symbol.tpe, tree.tpe, emptyEnv, strict = false, tparams = false) if (env.isEmpty) super.transform(tree) else { @@ -1848,7 +1840,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } // end transformDefDef expandInnerNormalizedMembers(transformDefDef(ddef)) - case ddef @ DefDef(_, _, _, _, _, _) => + case DefDef(_, _, _, _, _, _) => val tree1 = expandInnerNormalizedMembers(tree) super.transform(tree1) @@ -1900,7 +1892,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // flag. nobody has to see this anyway :) sym.setFlag(SPECIALIZED) // create empty bodies for specializations - localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, { vparamss: List[List[Symbol]] => EmptyTree })), ddef)) + localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, (_: List[List[Symbol]]) => EmptyTree)), ddef)) } else tree case _ => @@ -1995,18 +1987,16 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { ) ) // param accessors for private members (the others are inherited from the generic class) - if (m.isPrimaryConstructor) { - for (param <- vparams ; if sClass.info.nonPrivateMember(param.name) == NoSymbol) { + if (m.isPrimaryConstructor) + for (param <- vparams if sClass.info.nonPrivateMember(param.name) == NoSymbol) { val acc = param.cloneSymbol(sClass, param.flags | PARAMACCESSOR | PrivateLocal) sClass.info.decls.enter(acc) mbrs += ValDef(acc, EmptyTree).setType(NoType).setPos(m.pos) } - } - // ctor mbrs += DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef.apply), EmptyTree) } else { - mbrs += DefDef(m, { paramss: List[List[Symbol]] => EmptyTree }) + mbrs += DefDef(m, (_: List[List[Symbol]]) => EmptyTree) } } else if (m.isValue) { mbrs += ValDef(m).setType(NoType) diff --git a/src/compiler/scala/tools/nsc/transform/Statics.scala b/src/compiler/scala/tools/nsc/transform/Statics.scala index ac2ea4132aa3..345ad4a4c9bb 100644 --- a/src/compiler/scala/tools/nsc/transform/Statics.scala +++ b/src/compiler/scala/tools/nsc/transform/Statics.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index b1e67c77f19c..29aa7a91db3e 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,7 +16,7 @@ package transform import symtab.Flags import Flags.SYNTHETIC -import scala.annotation.tailrec +import scala.annotation._ /** Perform tail recursive call elimination. * @@ -84,7 +84,7 @@ abstract class TailCalls extends Transform { * parameter lists exist. *

*/ - class TailCallElimination(unit: CompilationUnit) extends AstTransformer { + class TailCallElimination(@unused unit: CompilationUnit) extends AstTransformer { private def defaultReason = "it contains a recursive call not in tail position" private val failPositions = perRunCaches.newMap[TailContext, Position]() withDefault (_.methodPos) private val failReasons = perRunCaches.newMap[TailContext, String]() withDefaultValue defaultReason @@ -275,7 +275,7 @@ abstract class TailCalls extends Transform { import runDefinitions.{Boolean_or, Boolean_and} tree match { - case dd: DefDef if tree.symbol.isLazy && tree.symbol.hasAnnotation(TailrecClass) => + case _: DefDef if tree.symbol.isLazy && tree.symbol.hasAnnotation(TailrecClass) => reporter.error(tree.pos, "lazy vals are not tailcall transformed") tree.transform(this) @@ -287,7 +287,7 @@ abstract class TailCalls extends Transform { debuglog(s"Considering $name for tailcalls, with labels in tailpos: ${newCtx.tailLabels}") val newRHS = transform(rhs0, newCtx) - deriveDefDef(tree) { rhs => + deriveDefDef(tree) { _ => if (newCtx.isTransformed) { /* We have rewritten the tree, but there may be nested recursive calls remaining. * If @tailrec is given we need to fail those now. @@ -330,7 +330,7 @@ abstract class TailCalls extends Transform { ) // a translated casedef - case LabelDef(_, _, body) if hasSynthCaseSymbol(tree) => + case LabelDef(_, _, _) if hasSynthCaseSymbol(tree) => deriveLabelDef(tree)(transform) case Block(stats, expr) => @@ -471,7 +471,7 @@ abstract class TailCalls extends Transform { traverseNoTail(selector) traverseTrees(cases) - case dd @ DefDef(_, _, _, _, _, _) => // we are run per-method + case DefDef(_, _, _, _, _, _) => // we are run per-method case Block(stats, expr) => traverseTreesNoTail(stats) diff --git a/src/compiler/scala/tools/nsc/transform/Transform.scala b/src/compiler/scala/tools/nsc/transform/Transform.scala index f3ecf7eacf0b..14c1a9e8d0db 100644 --- a/src/compiler/scala/tools/nsc/transform/Transform.scala +++ b/src/compiler/scala/tools/nsc/transform/Transform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala b/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala index 1ed9f30b78fa..4342f9d22bf5 100644 --- a/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala +++ b/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -51,6 +51,13 @@ trait TypeAdaptingTransformer { self: TreeDSL => case LabelDef(_, _, _) => val ldef = deriveLabelDef(tree)(box) ldef setType ldef.rhs.tpe + case Apply(fun @ Ident(_), _) if fun.symbol.isLabel => + // don't box around label jumps, scala/bug#13043 + // need to set the tree type to avoid looping in `adaptToType` + tree.setType(tree.tpe match { + case ErasedValueType(clazz, _) => clazz.tpe + case _ => ObjectTpe + }) case _ => val tree1 = tree.tpe match { case ErasedValueType(clazz, _) => New(clazz, cast(tree, underlyingOfValueClass(clazz))) @@ -58,11 +65,10 @@ trait TypeAdaptingTransformer { self: TreeDSL => case UnitClass => if (treeInfo isExprSafeToInline tree) REF(BoxedUnit_UNIT) else BLOCK(tree, REF(BoxedUnit_UNIT)) - case NothingClass => tree // a non-terminating expression doesn't need boxing case x => assert(x != ArrayClass, "array") tree match { - case Apply(boxFun, List(arg)) if isSafelyRemovableUnbox(tree, arg) => + case Apply(_, List(arg)) if isSafelyRemovableUnbox(tree, arg) => arg case _ => (REF(currentRun.runDefinitions.boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectTpe @@ -87,8 +93,8 @@ trait TypeAdaptingTransformer { self: TreeDSL => if (treeInfo isExprSafeToInline side) value else BLOCK(side, value) val tree1 = pt match { - case ErasedValueType(clazz, BoxedUnitTpe) => cast(preservingSideEffects(tree, REF(BoxedUnit_UNIT)), pt) - case ErasedValueType(clazz, underlying) => cast(unboxValueClass(tree, clazz, underlying), pt) + case ErasedValueType(_, BoxedUnitTpe) => cast(preservingSideEffects(tree, REF(BoxedUnit_UNIT)), pt) + case ErasedValueType(clazz, underlying) => cast(unboxValueClass(tree, clazz, underlying), pt) case _ => pt.typeSymbol match { case UnitClass => diff --git a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala index d2185a7fe678..55d70009aaf6 100644 --- a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala +++ b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 2f1838b0becb..9ea2dbc75603 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -194,7 +194,7 @@ abstract class UnCurry extends InfoTransform import treeInfo.{catchesThrowable, isSyntheticCase} for { - Try(t, catches, _) <- body + Try(_, catches, _) <- body cdef <- catches if catchesThrowable(cdef) && !isSyntheticCase(cdef) } { @@ -398,7 +398,7 @@ abstract class UnCurry extends InfoTransform * all lambda impl methods as static. */ private def translateSynchronized(tree: Tree) = tree match { - case dd @ DefDef(_, _, _, _, _, Apply(fn, body :: Nil)) if isSelfSynchronized(dd) => + case dd @ DefDef(_, _, _, _, _, Apply(_, body :: Nil)) if isSelfSynchronized(dd) => log("Translating " + dd.symbol.defString + " into synchronized method") dd.symbol setFlag SYNCHRONIZED deriveDefDef(dd)(_ => body) @@ -576,15 +576,6 @@ abstract class UnCurry extends InfoTransform tree } - @tailrec def isThrowable(pat: Tree): Boolean = pat match { - case Typed(Ident(nme.WILDCARD), tpt) => - tpt.tpe =:= ThrowableTpe - case Bind(_, pat) => - isThrowable(pat) - case _ => - false - } - tree match { /* Some uncurry post transformations add members to templates. * @@ -847,7 +838,7 @@ abstract class UnCurry extends InfoTransform val theTyper = typer.atOwner(dd, currentClass) val forwTree = theTyper.typedPos(dd.pos) { - val seqArgs = map3(newPs, oldPs, isRepeated)((param, oldParam, isRep) => { + val seqArgs = map3(newPs, oldPs, isRepeated)((param, _, isRep) => { if (!isRep) Ident(param) else { val parTp = elementType(ArrayClass, param.tpe) diff --git a/src/compiler/scala/tools/nsc/transform/async/AnfTransform.scala b/src/compiler/scala/tools/nsc/transform/async/AnfTransform.scala index 603981947175..eaf866b6a162 100644 --- a/src/compiler/scala/tools/nsc/transform/async/AnfTransform.scala +++ b/src/compiler/scala/tools/nsc/transform/async/AnfTransform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -177,7 +177,7 @@ private[async] trait AnfTransform extends TransformUtils { treeCopy.Match(tree, scrutExpr, casesWithAssign) } - case ld@LabelDef(name, params, rhs) => + case LabelDef(name, params, rhs) => treeCopy.LabelDef(tree, name, params, transformNewControlFlowBlock(rhs)) case t@Typed(expr, tpt) => transform(expr).setType(t.tpe) @@ -318,11 +318,11 @@ private[async] trait AnfTransform extends TransformUtils { val statsExpr0: ArrayBuffer[Tree] = new ArrayBuffer[Tree](statsExpr.length) statsExpr.reverseIterator.foreach { - case ld@LabelDef(_, param :: Nil, _) => + case ld@LabelDef(_, _ :: Nil, _) => val (ld1, after) = modifyLabelDef(ld) statsExpr0 += after statsExpr0 += ld1 - case a@ValDef(mods, name, tpt, ld@LabelDef(_, param :: Nil, _)) => + case a@ValDef(mods, name, tpt, ld@LabelDef(_, _ :: Nil, _)) => val (ld1, after) = modifyLabelDef(ld) statsExpr0 += treeCopy.ValDef(a, mods, name, tpt, after) statsExpr0 += ld1 diff --git a/src/compiler/scala/tools/nsc/transform/async/AsyncAnalysis.scala b/src/compiler/scala/tools/nsc/transform/async/AsyncAnalysis.scala index 201e474628a4..5eed85764497 100644 --- a/src/compiler/scala/tools/nsc/transform/async/AsyncAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/async/AsyncAnalysis.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/async/AsyncNames.scala b/src/compiler/scala/tools/nsc/transform/async/AsyncNames.scala index bc8b1ca175e1..957b60ca2b4b 100644 --- a/src/compiler/scala/tools/nsc/transform/async/AsyncNames.scala +++ b/src/compiler/scala/tools/nsc/transform/async/AsyncNames.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/async/AsyncPhase.scala b/src/compiler/scala/tools/nsc/transform/async/AsyncPhase.scala index 670b59494d2b..306346910ac6 100644 --- a/src/compiler/scala/tools/nsc/transform/async/AsyncPhase.scala +++ b/src/compiler/scala/tools/nsc/transform/async/AsyncPhase.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,7 +14,7 @@ package scala.tools.nsc.transform.async import scala.collection.mutable import scala.tools.nsc.transform.{Transform, TypingTransformers} -import scala.reflect.internal.util.{SourceFile, NoSourceFile} +import scala.reflect.internal.util.{NoSourceFile, ReplBatchSourceFile, SourceFile} abstract class AsyncPhase extends Transform with TypingTransformers with AnfTransform with Lifter with LiveVariables { self => @@ -46,9 +46,10 @@ abstract class AsyncPhase extends Transform with TypingTransformers with AnfTran reporter.warning(pos, s"${settings.async.name} must be enabled for async transformation.") sourceFilesToTransform += pos.source val postAnfTransform = config.getOrElse("postAnfTransform", (x: Block) => x).asInstanceOf[Block => Block] - val stateDiagram = config.getOrElse("stateDiagram", (sym: Symbol, tree: Tree) => None).asInstanceOf[(Symbol, Tree) => Option[String => Unit]] + val stateDiagram = config.getOrElse("stateDiagram", (_: Symbol, _: Tree) => None).asInstanceOf[(Symbol, Tree) => Option[String => Unit]] val allowExceptionsToPropagate = config.contains("allowExceptionsToPropagate") method.updateAttachment(new AsyncAttachment(awaitMethod, postAnfTransform, stateDiagram, allowExceptionsToPropagate)) + method.updateAttachment(ForceMatchDesugar) // Wrap in `{ expr: Any }` to force value class boxing before calling `completeSuccess`, see test/async/run/value-class.scala deriveDefDef(method) { rhs => Block(Apply(gen.mkAttributedRef(definitions.Predef_locally), rhs :: Nil).updateAttachment(TypedExpectingUnitAttachment), Literal(Constant(()))) @@ -74,12 +75,16 @@ abstract class AsyncPhase extends Transform with TypingTransformers with AnfTran // TOOD: figure out how to make the root-level async built-in macro sufficiently configurable: // replace the ExecutionContext implicit arg with an AsyncContext implicit that also specifies the type of the Future/Awaitable/Node/...? final class AsyncTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { - private lazy val liftableMap = new mutable.AnyRefMap[Symbol, (Symbol, List[Tree])]() + private lazy val liftableMap = new mutable.HashMap[Symbol, (Symbol, List[Tree])]() override def transformUnit(unit: CompilationUnit): Unit = { if (settings.async.value) { // NoSourceFile can happen for, e.g., toolbox compilation; overestimate by always transforming them. See test/async/jvm/toolbox.scala - val shouldTransform = unit.source == NoSourceFile || sourceFilesToTransform.contains(unit.source) + val shouldTransform = unit.source == NoSourceFile || sourceFilesToTransform(unit.source) || (unit.source match { + // scala/bug#13050, see also `PerRunReporting.repSrc` + case r: ReplBatchSourceFile => sourceFilesToTransform(r.parserSource) + case _ => false + }) if (shouldTransform) super.transformUnit(unit) if (awaits.exists(_.isInitialized)) { unit.body.foreach { @@ -122,7 +127,7 @@ abstract class AsyncPhase extends Transform with TypingTransformers with AnfTran case dd: DefDef if dd.hasAttachment[AsyncAttachment] => val asyncAttachment = dd.getAndRemoveAttachment[AsyncAttachment].get val asyncBody = (dd.rhs: @unchecked) match { - case blk@Block(Apply(qual, body :: Nil) :: Nil, Literal(Constant(()))) => body + case Block(Apply(_, body :: Nil) :: Nil, Literal(Constant(()))) => body } atOwner(dd, dd.symbol) { diff --git a/src/compiler/scala/tools/nsc/transform/async/AsyncTransformStates.scala b/src/compiler/scala/tools/nsc/transform/async/AsyncTransformStates.scala index a1da31110c77..202a1ef6990e 100644 --- a/src/compiler/scala/tools/nsc/transform/async/AsyncTransformStates.scala +++ b/src/compiler/scala/tools/nsc/transform/async/AsyncTransformStates.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/async/ExprBuilder.scala b/src/compiler/scala/tools/nsc/transform/async/ExprBuilder.scala index b21667673e7b..8436020f6c50 100644 --- a/src/compiler/scala/tools/nsc/transform/async/ExprBuilder.scala +++ b/src/compiler/scala/tools/nsc/transform/async/ExprBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -312,7 +312,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis { buildStateAndOpenNextState(afterLabelState, style = StateTransitionStyle.None) } } else if (containsAwait(rhs)) { - // A while loop containing an await. We assuming that the the backward branch is reachable across the async + // A while loop containing an await. We assuming that the backward branch is reachable across the async // code path and create a state for the `while` label. // // In theory we could avoid creating this state in code like: @@ -396,8 +396,8 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis { val blockBuilder = new AsyncBlockBuilder(stats, expr, startState, endState, startToEndUpdateStyle = StateTransitionStyle.Update) new AsyncBlock { - private val switchIds = mutable.AnyRefMap[Integer, Integer]() - private val emptyReplacements = mutable.AnyRefMap[Integer, Integer]() + private val switchIds = mutable.HashMap[Integer, Integer]() + private val emptyReplacements = mutable.HashMap[Integer, Integer]() private def switchIdOf(state: Integer) = switchIds(emptyReplacements.getOrElse(state, state)) // render with http://graphviz.it/#/new @@ -522,10 +522,10 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis { live } else all - private val compactStateTransform = new AstTransformer { + private val compactStateTransform: AstTransformer = new AstTransformer { val transformState = currentTransformState override def transform(tree: Tree): Tree = tree match { - case as @ Apply(qual: Select, (lit @ Literal(Constant(i: Integer))) :: Nil) if qual.symbol == transformState.stateSetter && compactStates => + case Apply(qual: Select, (lit @ Literal(Constant(i: Integer))) :: Nil) if qual.symbol == transformState.stateSetter && compactStates => val replacement = switchIdOf(i) treeCopy.Apply(tree, qual, treeCopy.Literal(lit, Constant(replacement)):: Nil) case _: Match | _: CaseDef | _: Block | _: If | _: LabelDef => @@ -632,7 +632,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis { } } - /** Update the state variable and jump to the the while loop that encloses the state machine. */ + /** Update the state variable and jump to the while loop that encloses the state machine. */ case object UpdateAndContinue extends StateTransitionStyle { def trees(nextState: Int, stateSet: StateSet): List[Tree] = { stateSet += nextState diff --git a/src/compiler/scala/tools/nsc/transform/async/Lifter.scala b/src/compiler/scala/tools/nsc/transform/async/Lifter.scala index e1a2519af5d8..b7ae5ec924d6 100644 --- a/src/compiler/scala/tools/nsc/transform/async/Lifter.scala +++ b/src/compiler/scala/tools/nsc/transform/async/Lifter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -95,7 +95,7 @@ trait Lifter extends ExprBuilder { // The definitions trees val symToTree: mutable.LinkedHashMap[Symbol, Tree] = defs.map { - case (k, v) => (k.symbol, k) + case (k, _) => (k.symbol, k) } // The direct references of each definition tree @@ -182,7 +182,7 @@ trait Lifter extends ExprBuilder { case NoSymbol => sym.setName(currentTransformState.name.freshen(sym.name.toTypeName)) sym.setName(sym.name.toTypeName) - case classSymbol => // will be renamed by above. + case classSymbol@_ => // will be renamed by above. } treeCopy.ClassDef(cd, Modifiers(sym.flags), sym.name, tparams, impl) } diff --git a/src/compiler/scala/tools/nsc/transform/async/LiveVariables.scala b/src/compiler/scala/tools/nsc/transform/async/LiveVariables.scala index 01ef248e060d..82a5bef32ba0 100644 --- a/src/compiler/scala/tools/nsc/transform/async/LiveVariables.scala +++ b/src/compiler/scala/tools/nsc/transform/async/LiveVariables.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,6 +12,7 @@ package scala.tools.nsc.transform.async +import scala.annotation._ import scala.collection.immutable.ArraySeq import scala.collection.mutable import scala.reflect.internal.Flags._ @@ -28,7 +29,7 @@ trait LiveVariables extends ExprBuilder { * @param liftables the lifted fields * @return a map which indicates fields which are used for the final time in each state. */ - def fieldsToNullOut(asyncStates: List[AsyncState], finalState: AsyncState, + def fieldsToNullOut(asyncStates: List[AsyncState], @unused finalState: AsyncState, liftables: List[Tree]): mutable.LinkedHashMap[Int, (mutable.LinkedHashSet[Symbol], mutable.LinkedHashSet[Symbol])] = { val liftedSyms = mutable.LinkedHashSet[Symbol]() diff --git a/src/compiler/scala/tools/nsc/transform/async/StateAssigner.scala b/src/compiler/scala/tools/nsc/transform/async/StateAssigner.scala index f5971c5a3671..39feb481b84d 100644 --- a/src/compiler/scala/tools/nsc/transform/async/StateAssigner.scala +++ b/src/compiler/scala/tools/nsc/transform/async/StateAssigner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/async/StateSet.scala b/src/compiler/scala/tools/nsc/transform/async/StateSet.scala index 74a67bfb8b3a..cef46b1addba 100644 --- a/src/compiler/scala/tools/nsc/transform/async/StateSet.scala +++ b/src/compiler/scala/tools/nsc/transform/async/StateSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/async/TransformUtils.scala b/src/compiler/scala/tools/nsc/transform/async/TransformUtils.scala index be14f1d0e017..05204a8440fe 100644 --- a/src/compiler/scala/tools/nsc/transform/async/TransformUtils.scala +++ b/src/compiler/scala/tools/nsc/transform/async/TransformUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index f5efc46600f2..a39ea17d7d1a 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index 14beab1416be..6180ff4bb5f2 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.nsc.transform.patmat -import scala.annotation.tailrec +import scala.annotation._ import scala.collection.mutable import scala.tools.nsc.Reporting.WarningCategory @@ -461,7 +461,7 @@ trait MatchAnalysis extends MatchApproximation { // the case is reachable if there is a model for -P /\ C, // thus, the case is unreachable if there is no model for -(-P /\ C), // or, equivalently, P \/ -C, or C => P - def unreachableCase(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): Option[Int] = { + def unreachableCase(prevBinder: Symbol, cases: List[List[TreeMaker]], @unused pt: Type): Option[Int] = { debug.patmat("reachability analysis") val start = if (settings.areStatisticsEnabled) statistics.startTimer(statistics.patmatAnaReach) else null @@ -519,7 +519,7 @@ trait MatchAnalysis extends MatchApproximation { // exhaustivity - def exhaustive(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[String] = if (!settings.warnStrictUnsealedPatMat && uncheckableType(prevBinder.info)) Nil else { + def exhaustive(prevBinder: Symbol, cases: List[List[TreeMaker]], @unused pt: Type): List[String] = if (!settings.warnStrictUnsealedPatMat && uncheckableType(prevBinder.info)) Nil else { debug.patmat("exhaustiveness analysis") // customize TreeMakersToProps (which turns a tree of tree makers into a more abstract DAG of tests) // - approximate the pattern `List()` (unapplySeq on List with empty length) as `Nil`, @@ -788,7 +788,7 @@ trait MatchAnalysis extends MatchApproximation { object VariableAssignment { private def findVar(path: List[Symbol]) = path match { case List(root) if root == scrutVar.path.symbol => Some(scrutVar) - case _ => varAssignment.find{case (v, a) => chop(v.path) == path}.map(_._1) + case _ => varAssignment.find{case (v, _) => chop(v.path) == path}.map(_._1) } private val uniques = new mutable.HashMap[Var, VariableAssignment] diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala index 6d87a6bb1e74..b7c38b023188 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCps.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCps.scala index 0b5c089dbfc7..61f14d404088 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCps.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala index 6c320fd01e1d..358da87057c9 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.nsc.transform.patmat -import scala.annotation.tailrec +import scala.annotation._ import scala.collection.mutable import scala.tools.nsc.symtab.Flags.{MUTABLE, STABLE} import scala.tools.nsc.Reporting.WarningCategory @@ -35,7 +35,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { * the variable is floated up so that its scope includes all of the program that shares it * we generalize sharing to implication, where b reuses a if a => b and priors(a) => priors(b) (the priors of a sub expression form the path through the decision tree) */ - def doCSE(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, selectorPos: Position): List[List[TreeMaker]] = { + def doCSE(prevBinder: Symbol, cases: List[List[TreeMaker]], @unused pt: Type, selectorPos: Position): List[List[TreeMaker]] = { debug.patmat("before CSE:") showTreeMakers(cases) @@ -130,9 +130,8 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { // if the shared prefix contains interesting conditions (!= True) // and the last of such interesting shared conditions reuses another treemaker's test // replace the whole sharedPrefix by a ReusingCondTreeMaker - for (lastShared <- sharedPrefix.reverse.dropWhile(_.prop == True).headOption; - lastReused <- reusesTest(lastShared)) - yield ReusingCondTreeMaker(sharedPrefix, reusesTest, reusedOrOrig) :: suffix.map(_.treeMaker) + for (lastShared <- sharedPrefix.reverse.dropWhile(_.prop == True).headOption; _ <- reusesTest(lastShared)) + yield ReusingCondTreeMaker(sharedPrefix, reusesTest, reusedOrOrig) :: suffix.map(_.treeMaker) } collapsedTreeMakers getOrElse tests.map(_.treeMaker) // sharedPrefix need not be empty (but it only contains True-tests, which are dropped above) @@ -209,6 +208,8 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { trait SwitchEmission extends TreeMakers with MatchMonadInterface { import treeInfo.isGuardedCase + def inForceDesugar: Boolean + abstract class SwitchMaker { abstract class SwitchableTreeMakerExtractor { def unapply(x: TreeMaker): Option[Tree] } val SwitchableTreeMaker: SwitchableTreeMakerExtractor @@ -304,7 +305,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { // the patterns in same are equal (according to caseEquals) // we can thus safely pick the first one arbitrarily, provided we correct binding val origPatWithoutBind = commonPattern match { - case Bind(b, orig) => orig + case Bind(_, orig) => orig case o => o } // need to replace `defaultSym` as well -- it's used in `defaultBody` (see `jumpToDefault` above) @@ -312,7 +313,8 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { (Bind(binder, origPatWithoutBind), unifiedBody) } - atPos(commonPattern.pos)(CaseDef(pat, EmptyTree, guardedBodySubst)) + val samePos = wrappingPos(same.flatMap(k => List(k.pat, k.body))) + atPos(samePos)(CaseDef(pat, EmptyTree, guardedBodySubst)) } // requires cases.exists(isGuardedCase) (otherwise the rewrite is pointless) @@ -479,9 +481,12 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { else { def wrapInDefaultLabelDef(cd: CaseDef): CaseDef = if (needDefaultLabel) deriveCaseDef(cd){ b => - // TODO: can b.tpe ever be null? can't really use pt, see e.g. pos/t2683 or cps/match1.scala - defaultLabel setInfo MethodType(Nil, if (b.tpe != null) b.tpe.deconst else pt) - LabelDef(defaultLabel, Nil, b) + // If `b` is synthesized in SwitchMaker (by `collapseGuardedCases` or by `defaultCase`) + // it is not yet typed. In order to assign the correct type to the label, type the case body. + // See scala/scala#10926, pos/t13060.scala. + val b1 = if (b.tpe == null) typer.typed(b, pt) else b + defaultLabel setInfo MethodType(Nil, b1.tpe.deconst) + LabelDef(defaultLabel, Nil, b1) } else cd val last = collapsed.last @@ -497,7 +502,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { class RegularSwitchMaker(scrutSym: Symbol, matchFailGenOverride: Option[Tree => Tree], val unchecked: Boolean) extends SwitchMaker { import CODE._ val switchableTpe = Set(ByteTpe, ShortTpe, IntTpe, CharTpe, StringTpe) val alternativesSupported = true - val canJump = true + val canJump = !inForceDesugar // Constant folding sets the type of a constant tree to `ConstantType(Constant(folded))` // The tree itself can be a literal, an ident, a selection, ... @@ -534,7 +539,9 @@ trait MatchOptimization extends MatchTreeMaking with MatchApproximation { } def defaultSym: Symbol = scrutSym - def defaultBody: Tree = { matchFailGenOverride map (gen => gen(REF(scrutSym))) getOrElse Throw(MatchErrorClass.tpe, REF(scrutSym)) } + def defaultBody: Tree = matchFailGenOverride + .map(gen => gen(REF(scrutSym))) + .getOrElse(Throw(MatchErrorClass.tpe, REF(scrutSym))) def defaultCase(scrutSym: Symbol = defaultSym, guard: Tree = EmptyTree, body: Tree = defaultBody): CaseDef = { atPos(body.pos) { (DEFAULT IF guard) ==> body }} diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index 34d8a13d1821..3f508e006b14 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,6 +13,8 @@ package scala.tools.nsc package transform.patmat +import scala.annotation._ + /** Translate typed Trees that represent pattern matches into the patternmatching IR, defined by TreeMakers. */ trait MatchTranslation { @@ -186,7 +188,7 @@ trait MatchTranslation { val Match(selector, cases) = match_ val (nonSyntheticCases, defaultOverride) = cases match { - case init :+ last if treeInfo isSyntheticDefaultCase last => (init, Some(((scrut: Tree) => last.body))) + case init :+ last if treeInfo isSyntheticDefaultCase last => (init, Some(((_: Tree) => last.body))) case _ => (cases, None) } @@ -198,7 +200,7 @@ trait MatchTranslation { if (phase.id >= currentRun.uncurryPhase.id) devWarning(s"running translateMatch past uncurry (at $phase) on $selector match $cases") - debug.patmat("translating "+ cases.mkString("{", "\n", "}")) + debug.patmat(cases.mkString("translating {", "\n", "}")) val start = if (settings.areStatisticsEnabled) statistics.startTimer(statistics.patmatNanos) else null @@ -252,20 +254,21 @@ trait MatchTranslation { val catches = if (swatches.nonEmpty) swatches else { val scrutSym = freshSym(caseDefs.head.pat.pos, ThrowableTpe) val cases = caseDefs.map(translateCase(scrutSym, pt)) + val casesPos = wrappingPos(caseDefs) val exSym = freshSym(pos, ThrowableTpe, "ex") val suppression = if (settings.XnoPatmatAnalysis.value) Suppression.FullSuppression else Suppression.NoSuppression.copy(suppressExhaustive = true) // try/catches needn't be exhaustive - List( - atPos(pos) { - CaseDef( - Bind(exSym, Ident(nme.WILDCARD)), // TODO: does this need fixing upping? - EmptyTree, - combineCases(REF(exSym), scrutSym, cases, pt, selectorPos, matchOwner, Some(scrut => Throw(REF(exSym))), suppression) - ) - }) + val combo = combineCases(REF(exSym), scrutSym, cases, pt, selectorPos, matchOwner, Some(_ => Throw(REF(exSym))), suppression) + List(atPos(casesPos) { + CaseDef( + Bind(exSym, Ident(nme.WILDCARD)), // TODO: does this need fixing upping? + EmptyTree, + combo + ) + }) } typer.typedCases(catches, ThrowableTpe, WildcardType) @@ -402,7 +405,7 @@ trait MatchTranslation { private def genDrop(binder: Symbol, n: Int): List[Tree] = codegen.drop(seqTree(binder, forceImmutable = false))(n) :: Nil // codegen.drop(seqTree(binder))(nbIndexingIndices)))).toList - protected def seqTree(binder: Symbol, forceImmutable: Boolean) = tupleSel(binder)(firstIndexingBinder + 1) + protected def seqTree(binder: Symbol, @unused forceImmutable: Boolean) = tupleSel(binder)(firstIndexingBinder + 1) protected def tupleSel(binder: Symbol)(i: Int): Tree = codegen.tupleSel(binder)(i) // the trees that select the subpatterns on the extractor's result, diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 5193255eab86..5416476c7c33 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.nsc.transform.patmat -import scala.annotation.tailrec +import scala.annotation._ import scala.collection.mutable import scala.tools.nsc.symtab.Flags.{SYNTHETIC, ARTIFACT} import scala.tools.nsc.Reporting.WarningCategory @@ -335,7 +335,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { trait TypeTestCondStrategy { type Result - def withOuterTest(orig: Result)(testedBinder: Symbol, expectedTp: Type): Result = orig + def withOuterTest(orig: Result)(@unused testedBinder: Symbol, @unused expectedTp: Type): Result = orig // TODO: can probably always widen def typeTest(testedBinder: Symbol, expectedTp: Type): Result def nonNullTest(testedBinder: Symbol): Result @@ -590,7 +590,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE)))(casegen)) ) - val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanTpe)(combinedAlts, Some(x => FALSE)) + val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanTpe)(combinedAlts, Some(_ => FALSE)) codegenAlt.ifThenElseZero(findAltMatcher, substitution(next)) } } @@ -640,14 +640,14 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { def requiresSwitch(scrut: Tree, cases: List[List[TreeMaker]]): Boolean = { if (settings.XnoPatmatAnalysis.value) false else scrut match { - case Typed(tree, tpt) => + case Typed(_, tpt) => val hasSwitchAnnotation = treeInfo.isSwitchAnnotation(tpt.tpe) // matches with two or fewer cases need not apply for switchiness (if-then-else will do) // `case 1 | 2` is considered as two cases. def exceedsTwoCasesOrAlts = { // avoids traversing the entire list if there are more than 3 elements def lengthMax3(cases: List[List[TreeMaker]]): Int = cases match { - case a :: b :: c :: _ => 3 + case _ :: _ :: _ :: _ => 3 case cases => cases.map { case AlternativesTreeMaker(_, alts, _) :: _ => lengthMax3(alts) case _ => 1 diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala index 0cf775d3b16e..439bbdeca938 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchWarnings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala index 0b6adebb8970..472231e7ca0d 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternExpansion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index a0b53cb0de90..cfc92ec8c4cc 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -65,12 +65,22 @@ trait PatternMatching extends Transform def newTransformer(unit: CompilationUnit): AstTransformer = new MatchTransformer(unit) class MatchTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { + private var inForceDesugar = false + override def transform(tree: Tree): Tree = tree match { - case CaseDef(UnApply(Apply(Select(qual, nme.unapply), Ident(nme.SELECTOR_DUMMY) :: Nil), (bind@Bind(b, Ident(nme.WILDCARD))) :: Nil), guard, body) + case dd: DefDef if dd.hasAttachment[ForceMatchDesugar.type] || dd.symbol.hasAttachment[ForceMatchDesugar.type] => + val wasInForceDesugar = inForceDesugar + try { + inForceDesugar = true + super.transform(dd) + } finally + inForceDesugar = wasInForceDesugar + + case CaseDef(UnApply(Apply(Select(qual, nme.unapply), Ident(nme.SELECTOR_DUMMY) :: Nil), (bind@Bind(name, Ident(nme.WILDCARD))) :: Nil), guard, body) if guard.isEmpty && qual.symbol == definitions.NonFatalModule => transform(treeCopy.CaseDef( tree, - bind, + treeCopy.Bind(bind, name, Typed(Ident(nme.WILDCARD), TypeTree(definitions.ThrowableTpe)).setType(definitions.ThrowableTpe)), localTyper.typed(atPos(tree.pos)(Apply(gen.mkAttributedRef(definitions.NonFatal_apply), List(Ident(bind.symbol))))), body)) @@ -103,16 +113,17 @@ trait PatternMatching extends Transform } def translator(selectorPos: Position): MatchTranslator with CodegenCore = { - new OptimizingMatchTranslator(localTyper, selectorPos) + new OptimizingMatchTranslator(localTyper, selectorPos, inForceDesugar) } } - class OptimizingMatchTranslator(val typer: analyzer.Typer, val selectorPos: Position) extends MatchTranslator - with MatchOptimizer - with MatchAnalyzer - with Solver + class OptimizingMatchTranslator(val typer: analyzer.Typer, val selectorPos: Position, val inForceDesugar: Boolean) + extends MatchTranslator + with MatchOptimizer + with MatchAnalyzer + with Solver } trait Debugging { diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala index cb0cb889601c..9dbd871030a0 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala index 862b3e6ed6b6..4863b010d7f5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -37,7 +37,7 @@ trait Adaptations { case _ => EmptyTree } def isInfix = t match { - case Apply(_, arg :: Nil) => t.hasAttachment[MultiargInfixAttachment.type] + case Apply(_, _ :: Nil) => t.hasAttachment[MultiargInfixAttachment.type] case _ => false } def callString = ( @@ -90,7 +90,7 @@ trait Adaptations { } @inline def warnAdaptation: true = { def discardedArgs = t match { - case Apply(_, stat @ Block(Apply(TypeApply(Select(adapter, _), _), adapted) :: Nil, expr) :: Nil) => + case Apply(_, Block(Apply(TypeApply(Select(adapter, _), _), adapted) :: Nil, expr) :: Nil) => isTupleSymbol(adapter.symbol.companion) && expr.tpe == UnitTpe && adapted == args case _ => false } diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 7c9439132c99..3ca7b7a1538d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,9 @@ package scala.tools.nsc package typechecker +import scala.collection.mutable import scala.collection.mutable.ArrayDeque +import scala.reflect.internal.util.JavaClearable /** Defines the sub-components for the namer, packageobjects, and typer phases. */ @@ -33,6 +35,7 @@ trait Analyzer extends AnyRef with StdAttachments with MacroAnnotationAttachments with AnalyzerPlugins + with ImportTracking { val global : Global import global._ @@ -54,7 +57,13 @@ trait Analyzer extends AnyRef object packageObjects extends { val global: Analyzer.this.global.type = Analyzer.this.global } with SubComponent { - val deferredOpen = perRunCaches.newSet[Symbol]() + val deferredOpen: mutable.Set[Symbol] = { + import scala.jdk.CollectionConverters._ + // This will throw a ConcurrentModificationException if we mutate during iteration + val javaSet = new java.util.LinkedHashSet[Symbol]() + perRunCaches.recordCache(JavaClearable.forCollection(javaSet)) + javaSet.asScala + } val phaseName = "packageobjects" val runsAfter = List[String]() val runsRightAfter= Some("namer") @@ -79,8 +88,18 @@ trait Analyzer extends AnyRef def apply(unit: CompilationUnit): Unit = { openPackageObjectsTraverser(unit.body) - deferredOpen.foreach(openPackageModule(_)) - deferredOpen.clear() + } + + override def run(): Unit = { + super.run() + + for (sym <- deferredOpen.toVector) { + if (deferredOpen.remove(sym)) { + // this can remove entries from `deferredOpen`, hence the copy to a vector + // and the check of `remove` return value + openPackageModule(sym) + } + } } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala index dc0bb21cf0c4..f9bf03de6fd2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala +++ b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,12 +13,15 @@ package scala.tools.nsc package typechecker +import scala.annotation._ + /** * @author Lukas Rytz */ trait AnalyzerPlugins { self: Analyzer with splain.SplainData => import global._ + @nowarn trait AnalyzerPlugin { /** * Selectively activate this analyzer plugin, e.g. according to the compiler phase. @@ -55,7 +58,7 @@ trait AnalyzerPlugins { self: Analyzer with splain.SplainData => * Let analyzer plugins change the types assigned to definitions. For definitions that have * an annotated type, the assigned type is obtained by typing that type tree. Otherwise, the * type is inferred by typing the definition's righthand side, or from the overridden - * member under `-Xsource:3-cross`. + * member under `-Xsource-features`. * * In order to know if the type was inferred, you can query the `wasEmpty` field in the `tpt` * TypeTree of the definition (for DefDef and ValDef). @@ -197,6 +200,7 @@ trait AnalyzerPlugins { self: Analyzer with splain.SplainData => * or something else if the plugin knows better that the implementation provided in scala-compiler.jar. * If multiple plugins return a non-empty result, it's going to be a compilation error. */ + @nowarn trait MacroPlugin { /** * Selectively activate this analyzer plugin, e.g. according to the compiler phase. @@ -435,7 +439,7 @@ trait AnalyzerPlugins { self: Analyzer with splain.SplainData => if (plugin.isActive()) { op.custom(plugin) match { case None => - case s @ Some(custom) => + case s @ Some(_) => if (result.isDefined) { typer.context.error(op.position, s"both $resultPlugin and $plugin want to ${op.description}") op.default diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala index 56e788d13897..7696f381ade2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -144,7 +144,7 @@ trait Checkable { def Psym = P.typeSymbol def PErased = P match { - case GenericArray(n, core) => existentialAbstraction(core.typeSymbol :: Nil, P) + case GenericArray(_, core) => existentialAbstraction(core.typeSymbol :: Nil, P) case _ => existentialAbstraction(Psym.typeParams, Psym.tpe_*) } def XR = if (Xsym == AnyClass) PErased else propagateKnownTypes(X, Psym) @@ -276,7 +276,7 @@ trait Checkable { } // Important to dealias at any entry point (this is the only one at this writing but cf isNeverSubClass.) def isNeverSubType(tp1: Type, tp2: Type): Boolean = /*logResult(s"isNeverSubType($tp1, $tp2)")*/((tp1.dealias, tp2.dealias) match { - case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) => + case (TypeRef(_, sym1, _), TypeRef(_, sym2, args2)) => isNeverSubClass(sym1, sym2) || { (sym1 isSubClass sym2) && { val tp1seen = tp1 baseType sym2 diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala index 97296d89a2bd..d97ef571b721 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index bee46af0d3cf..8e50e47307ec 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,17 +13,17 @@ package scala.tools.nsc package typechecker -import scala.reflect.internal.util.StringOps.{countAsString, countElementsAsString} import java.lang.System.{lineSeparator => EOL} import scala.PartialFunction.cond -import scala.annotation.tailrec +import scala.annotation._ +import scala.reflect.internal.util.{CodeAction, NoSourceFile} +import scala.reflect.internal.util.StringOps.{countAsString, countElementsAsString} +import scala.reflect.io.NoAbstractFile import scala.reflect.runtime.ReflectionUtils import scala.reflect.macros.runtime.AbortMacroException -import scala.util.control.{ControlThrowable, NonFatal} import scala.tools.nsc.Reporting.WarningCategory import scala.tools.nsc.util.stackTraceString -import scala.reflect.io.NoAbstractFile -import scala.reflect.internal.util.{CodeAction, NoSourceFile} +import scala.util.control.{ControlThrowable, NonFatal} trait ContextErrors extends splain.SplainErrors { self: Analyzer => @@ -314,13 +314,13 @@ trait ContextErrors extends splain.SplainErrors { case Some(holder) => val prettyParent = formatTraitWithParams(parent, holder.params) s"$prettyParent is an illegal Scala 3 parameterized trait; so can not take constructor arguments" - case none => s"$parent is a trait; does not take constructor arguments" + case _ => s"$parent is a trait; does not take constructor arguments" } issueNormalTypeError(arg, msg) } - def ConstrArgsInParentOfTraitError(arg: Tree, parent: Symbol) = + def ConstrArgsInParentOfTraitError(arg: Tree, @unused parent: Symbol) = issueNormalTypeError(arg, "parents of traits may not have parameters") def MissingTypeArgumentsParentTpeError(supertpt: Tree) = @@ -330,9 +330,10 @@ trait ContextErrors extends splain.SplainErrors { def AmbiguousIdentError(tree: Tree, name: Name, msg: String) = NormalTypeError(tree, "reference to " + name + " is ambiguous;\n" + msg) - def SymbolNotFoundError(tree: Tree, name: Name, owner: Symbol, startingIdentCx: Context, inPattern: Boolean) = { - def help = if (inPattern && name.isTermName) s"\nIdentifiers ${if (name.charAt(0).isUpper) "that begin with uppercase" else "enclosed in backticks"} are not pattern variables but match the value in scope." else "" - NormalTypeError(tree, s"not found: ${decodeWithKind(name, owner)}$help") + def SymbolNotFoundError(tree: Tree, name: Name, owner: Symbol, inPattern: Boolean, hidden: Boolean) = { + val help = if (inPattern && name.isTermName) s"\nIdentifiers ${if (name.charAt(0).isUpper) "that begin with uppercase" else "enclosed in backticks"} are not pattern variables but match the value in scope." else "" + val path = if (hidden) s"\nA ${if (name.isTermName) "value" else "class"} on the class path is shadowed by a companion artifact currently compiled; companions must be compiled together." else "" + NormalTypeError(tree, s"not found: ${decodeWithKind(name, owner)}$help$path") } // typedAppliedTypeTree @@ -424,8 +425,8 @@ trait ContextErrors extends splain.SplainErrors { def AmbiguousParentClassError(tree: Tree) = issueNormalTypeError(tree, "ambiguous parent class qualifier") - //typedSelect - def NotAMemberError(sel: Tree, qual: Tree, name: Name, cx: Context) = { + //typedSelect or checkSelector + def NotAMemberError(sel: Tree /*Select|Import*/, qual: Tree, name: Name, cx: Context) = { import util.EditDistance, util.StringUtil.oxford def errMsg: String = { val editThreshold = 3 @@ -516,7 +517,14 @@ trait ContextErrors extends splain.SplainErrors { else s"$nameString is not a member of $targetStr$addendum" ) } - issueNormalTypeError(sel, errMsg) + sel match { + case tree: Import => // selector name is unique; use it to improve position + tree.selectors.find(_.hasName(name)) match { + case Some(badsel) => issueTypeError(PosAndMsgTypeError(tree.posOf(badsel), errMsg)) + case _ => issueNormalTypeError(sel, errMsg) + } + case _ => issueNormalTypeError(sel, errMsg) + } // the error has to be set for the copied tree, otherwise // the error remains persistent across multiple compilations // and causes problems @@ -677,7 +685,7 @@ trait ContextErrors extends splain.SplainErrors { // doTypeApply //tryNamesDefaults - def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = + def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, @unused fun: Tree) = NormalTypeError(tree, "macro applications do not support named and/or default arguments") def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree, formals: List[Type], args: List[Tree], argPos: Array[Int]) = { @@ -807,15 +815,41 @@ trait ContextErrors extends splain.SplainErrors { //adapt def MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) = { val f = meth.name.decoded - val paf = s"$f(${ meth.asMethod.paramLists map (_ map (_ => "_") mkString ",") mkString ")(" })" + val paf = s"$f(${ meth.asMethod.paramLists.map(_.map(_ => "_").mkString(",")).mkString(")(") })" + val feature = if (!currentRun.isScala3) "" else + sm"""| + |Use -Xsource-features:eta-expand-always to convert even if the expected type is not a function type.""" val advice = if (meth.isConstructor || meth.info.params.lengthIs > definitions.MaxFunctionArity) "" - else s""" - |Unapplied methods are only converted to functions when a function type is expected. - |You can make this conversion explicit by writing `$f _` or `$paf` instead of `$f`.""".stripMargin + else + sm"""| + |Unapplied methods are only converted to functions when a function type is expected.$feature + |You can make this conversion explicit by writing `$f _` or `$paf` instead of `$f`.""" + val help = { + def memberTypesOf(qualTpe: Type, name: Name): List[Type] = { + val m = qualTpe.member(name) + if (m.isOverloaded) + m.alternatives.map(qualTpe.memberType(_)) + else + List(qualTpe.memberType(meth)) + } + val (qualTpe, memberTypes) = tree match { + case Select(qualifier, name) => (qualifier.tpe, memberTypesOf(qualifier.tpe, name)) + case treeInfo.Applied(Select(qualifier, name), _, _) => (qualifier.tpe, memberTypesOf(qualifier.tpe, name)) + case _ => (NoType, Nil) + } + memberTypes match { + case tp :: Nil => s" of type $tp" + case Nil => s" of type ${meth.info}" + case ov => + sm"""| + |with overloaded members in ${qualTpe.dealiasWiden} + | ${ov.map(show(_)).sorted.mkString("\n ")}""" + } + } val message = if (meth.isMacro) MacroTooFewArgumentListsMessage - else s"""missing argument list for ${meth.fullLocationString}$advice""" + else s"""missing argument list for ${meth.fullLocationString}${help}${advice}""" issueNormalTypeError(tree, message) setError(tree) } @@ -1140,18 +1174,20 @@ trait ContextErrors extends splain.SplainErrors { val ambiguousBuffered = !context.ambiguousErrors if (validTargets || ambiguousBuffered) context.issueAmbiguousError( - if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) { - val methodName = nme.defaultGetterToMethod(sym1.name) + if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) AmbiguousTypeError(sym1.enclClass.pos, - s"in ${sym1.enclClass}, multiple overloaded alternatives of $methodName define default arguments") - - } else { + s"in ${sym1.enclClass}, multiple overloaded alternatives of ${ + nme.defaultGetterToMethod(sym1.name) + } define default arguments" + ) + else AmbiguousTypeError(pos, - "ambiguous reference to overloaded definition,\n" + - s"both ${sym1.fullLocationString} of type ${pre.memberType(sym1)}\n" + - s"and ${sym2.fullLocationString} of type ${pre.memberType(sym2)}\n" + - s"match $rest") - }) + sm"""|ambiguous reference to overloaded definition, + |both ${sym1.fullLocationString} of type ${pre.memberType(sym1)} + |and ${sym2.fullLocationString} of type ${pre.memberType(sym2)} + |match $rest""" + ) + ) } def AccessError(tree: Tree, sym: Symbol, ctx: Context, explanation: String): AbsTypeError = @@ -1209,6 +1245,11 @@ trait ContextErrors extends splain.SplainErrors { case (tpe, _) => tpe } + def NoMatchingAlternative(tree: Tree, alts: List[Symbol], argTpes: List[Type], pt: Type) = { + val msg = " does not match arguments " + issueNormalTypeError(tree, applyErrorMsg(tree, msg, argTpes, pt)) + } + def NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type, lastTry: Boolean) = { val alts = alternatives(tree) val widenedArgtpes = widenArgs(argtpes, alts.head.params, alts.tail.head.params) @@ -1276,7 +1317,7 @@ trait ContextErrors extends splain.SplainErrors { } def NotWithinBounds(tree: Tree, prefix: String, targs: List[Type], - tparams: List[Symbol], kindErrors: List[String]) = + tparams: List[Symbol], @unused kindErrors: List[String]) = issueNormalTypeError(tree, NotWithinBoundsErrorMessage(prefix, targs, tparams, settings.explaintypes.value)) @@ -1340,7 +1381,7 @@ trait ContextErrors extends splain.SplainErrors { def TypeSigError(tree: Tree, ex: TypeError) = { ex match { - case CyclicReference(_, _) if tree.symbol.isTermMacro => + case CyclicReference(_, _, _) if tree.symbol.isTermMacro => // say, we have a macro def `foo` and its macro impl `impl` // if impl: 1) omits return type, 2) has anything implicit in its body, 3) sees foo // @@ -1353,8 +1394,8 @@ trait ContextErrors extends splain.SplainErrors { // hence we (together with reportTypeError in TypeDiagnostics) make sure that this CyclicReference // evades all the handlers on its way and successfully reaches `isCyclicOrErroneous` in Implicits throw ex - case CyclicReference(sym, info: TypeCompleter) => - issueNormalTypeError(tree, typer.cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage) + case CyclicReference(sym, info: TypeCompleter, trace) => + issueNormalTypeError(tree, typer.cyclicReferenceMessage(sym, info.tree, trace, tree.pos).getOrElse(ex.getMessage)) case _ => contextNamerErrorGen.issue(TypeErrorWithUnderlyingTree(tree, ex)) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 85c7b056ac73..854498ee0a61 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -22,13 +22,12 @@ import scala.util.chaining._ /** * @author Martin Odersky */ -trait Contexts { self: Analyzer => +trait Contexts { self: Analyzer with ImportTracking => import global._ import definitions.{JavaLangPackage, ScalaPackage, PredefModule, ScalaXmlTopScope, ScalaXmlPackage} import ContextMode._ import scala.reflect.internal.Flags._ - protected def onTreeCheckerError(pos: Position, msg: String): Unit = () object NoContext @@ -57,59 +56,6 @@ trait Contexts { self: Analyzer => rootMirror.RootClass.info.decls ) - private lazy val allUsedSelectors = - mutable.Map.empty[ImportInfo, Set[ImportSelector]].withDefaultValue(Set.empty) - private lazy val allImportInfos = - mutable.Map.empty[CompilationUnit, List[(ImportInfo, Symbol)]].withDefaultValue(Nil) - - def warnUnusedImports(unit: CompilationUnit) = if (!unit.isJava) { - def msg(sym: Symbol) = sym.deprecationMessage.map(": " + _).getOrElse("") - def checkDeprecatedElementInPath(selector: ImportSelector, info: ImportInfo): String = { - def badName(name: Name) = - info.qual.tpe.member(name) match { - case m if m.isDeprecated => Some(s" of deprecated $m${msg(m)}") - case _ => None - } - val badSelected = - if (!selector.isMask && selector.isSpecific) badName(selector.name).orElse(badName(selector.name.toTypeName)) - else None - def badFrom = { - val sym = info.qual.symbol - if (sym.isDeprecated) Some(s" from deprecated $sym${msg(sym)}") else None - } - badSelected.orElse(badFrom).getOrElse("") - } - def warnUnusedSelections(infos0: List[(ImportInfo, Symbol)]): Unit = { - type Culled = (ImportSelector, ImportInfo, Symbol) - var unused = List.empty[Culled] - @tailrec def loop(infos: List[(ImportInfo, Symbol)]): Unit = - infos match { - case (info, owner) :: infos => - val used = allUsedSelectors.remove(info).getOrElse(Set.empty) - def checkSelectors(selectors: List[ImportSelector]): Unit = - selectors match { - case selector :: selectors => - checkSelectors(selectors) - if (!selector.isMask && !used(selector)) - unused ::= ((selector, info, owner)) - case _ => - } - checkSelectors(info.tree.selectors) - loop(infos) - case _ => - } - loop(infos0) - unused.foreach { - case (selector, info, owner) => - val pos = info.posOf(selector) - val origin = info.fullSelectorString(selector) - val addendum = checkDeprecatedElementInPath(selector, info) - runReporting.warning(pos, s"Unused import$addendum", WarningCategory.UnusedImports, owner, origin) - } - } - allImportInfos.remove(unit).foreach(warnUnusedSelections) - } - var lastAccessCheckDetails: String = "" val rootImportsCached = perRunCaches.newMap[CompilationUnit, List[Symbol]]() @@ -173,9 +119,14 @@ trait Contexts { self: Analyzer => else RootImports.completeList def rootContext(unit: CompilationUnit, tree: Tree = EmptyTree, throwing: Boolean = false, checking: Boolean = false): Context = { - val rootImportsContext = rootImports(unit).foldLeft(startContext)((c, sym) => - c.make(gen.mkWildcardImport(sym), unit = unit) - ) + val rootImportsContext = rootImports(unit).foldLeft(startContext) { (c, sym) => + val imp = + if ((sym eq PredefModule) && currentRun.sourceFeatures.any2StringAdd) + gen.mkImportFromSelector(sym, ImportSelector.mask(nme.any2stringadd) :: ImportSelector.wildList) + else + gen.mkWildcardImport(sym) + c.make(tree = imp, unit = unit) + } // there must be a scala.xml package when xml literals were parsed in this unit if (unit.hasXml && ScalaXmlPackage == NoSymbol) @@ -378,8 +329,8 @@ trait Contexts { self: Analyzer => def prune(trees: List[Tree], pending: List[(Symbol, Tree)], acc: List[(Symbol, Tree)]): List[(Symbol, Tree)] = pending match { case Nil => acc case ps => - val (in, out) = ps.partition { case (vsym, rhs) => trees.exists(_.exists(_.symbol == vsym)) } - if(in.isEmpty) acc + val (in, out) = ps.partition { case (vsym, _) => trees.exists(_.exists(_.symbol == vsym)) } + if (in.isEmpty) acc else prune(in.map(_._2) ++ trees, out, in ++ acc) } @@ -587,8 +538,8 @@ trait Contexts { self: Analyzer => tryOnce(isLastTry = false) reporter.hasErrors } catch { - case ex: CyclicReference => throw ex - case ex: TypeError => true // recoverable cyclic references? + case e: CyclicReference => throw e + case _: TypeError => true // recoverable cyclic references? } } } else true @@ -727,8 +678,8 @@ trait Contexts { self: Analyzer => def makeImportContext(tree: Import): Context = make(tree).tap { ctx => - if (settings.warnUnusedImport && openMacros.isEmpty && !ctx.isRootImport) - allImportInfos(ctx.unit) ::= ctx.importOrNull -> ctx.owner + if (settings.warnUnusedImport && openMacros.isEmpty && !ctx.isRootImport && !ctx.outer.owner.isInterpreterWrapper) + recordImportContext(ctx) } /** Use reporter (possibly buffered) for errors/warnings and enable implicit conversion **/ @@ -875,7 +826,7 @@ trait Contexts { self: Analyzer => val pstr = if ((parents eq null) || parents.isEmpty) "Nil" else parents mkString " " val bstr = if (body eq null) "" else "" + body.length + " stats" s"""Template($pstr, _, $bstr)""" - case x => s"${tree.shortClass}${treeIdString}:${treeTruncated}" + case _ => s"${tree.shortClass}${treeIdString}:${treeTruncated}" } override def toString = @@ -1072,11 +1023,6 @@ trait Contexts { self: Analyzer => private def isQualifyingImplicit(name: Name, sym: Symbol, pre: Type, imported: Boolean) = sym.isImplicit && isAccessible(sym, pre) && - !( - // [eed3si9n] ideally I'd like to do this: val fd = currentRun.isScala3 && sym.isDeprecated - // but implicit caching currently does not report sym.isDeprecated correctly. - currentRun.isScala3Cross && (sym == currentRun.runDefinitions.Predef_any2stringaddMethod) - ) && !(imported && { val e = scope.lookupEntry(name) (e ne null) && (e.owner == scope) && e.sym.exists @@ -1107,7 +1053,7 @@ trait Contexts { self: Analyzer => def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match { case List() => List() - case sel :: _ if sel.isWildcard => + case sel :: _ if sel.isWildcard || sel.isGiven => // Using pre.implicitMembers seems to exposes a problem with out-dated symbols in the IDE, // see the example in https://www.assembla.com/spaces/scala-ide/tickets/1002552#/activity/ticket // I haven't been able to boil that down the an automated test yet. @@ -1355,14 +1301,14 @@ trait Contexts { self: Analyzer => } } - private def isReplImportWrapperImport(tree: Tree): Boolean = { + // detect magic REPL imports (used to manage visibility) + private def isReplImportWrapperImport(tree: Tree): Boolean = tree match { case Import(expr, selector :: Nil) => // Just a syntactic check to avoid forcing typechecking of imports selector.name.string_==(nme.INTERPRETER_IMPORT_LEVEL_UP) && owner.enclosingTopLevelClass.isInterpreterWrapper case _ => false } - } } //class Context @@ -1611,7 +1557,7 @@ trait Contexts { self: Analyzer => else if (impSym.isError || impSym.name == nme.CONSTRUCTOR) true // Try to reconcile them before giving up - else if (foreignDefined && reconcileAmbiguousImportAndDef) + else if (reconcileAmbiguousImportAndDef) true // Otherwise they are irreconcilably ambiguous else @@ -1815,7 +1761,7 @@ trait Contexts { self: Analyzer => if (context.reportErrors) { context.issue(divergent.withPt(paramTp)) errorBuffer.filterInPlace { - case dte: DivergentImplicitTypeError => false + case _: DivergentImplicitTypeError => false case _ => true } } @@ -1909,8 +1855,7 @@ trait Contexts { self: Analyzer => class ImportInfo(val tree: Import, val depth: Int, val isRootImport: Boolean) { def pos = tree.pos - def posOf(sel: ImportSelector) = - if (sel.namePos >= 0) tree.pos withPoint sel.namePos else tree.pos + def posOf(sel: ImportSelector) = tree.posOf(sel) /** The prefix expression */ def qual: Tree = tree.symbol.info match { @@ -1931,31 +1876,33 @@ trait Contexts { self: Analyzer => var renamed = false var selectors = tree.selectors @inline def current = selectors.head - @inline def maybeNonLocalMember(nom: Name): Symbol = + def maybeNonLocalMember(nom: Name): Symbol = if (qual.tpe.isError) NoSymbol - else if (pos.source.isJava) { - val (_, sym) = NoContext.javaFindMember(qual.tpe, nom, _ => true) - // We don't need to propagate the new prefix back out to the result of `Context.lookupSymbol` - // because typechecking .java sources doesn't need it. - sym - } + // We don't need to propagate the new prefix back out to the result of `Context.lookupSymbol` + // because typechecking .java sources doesn't need it. + else if (pos.source.isJava) NoContext.javaFindMember(qual.tpe, nom, _ => true)._2 else { val tp = qual.tpe - val sym = tp.typeSymbol // opening package objects is delayed (scala/scala#9661), but that can lead to missing symbols for // package object types that are forced early through Definitions; see scala/bug#12740 / scala/scala#10333 - if (phase.id < currentRun.typerPhase.id && sym.hasPackageFlag && analyzer.packageObjects.deferredOpen.remove(sym)) - openPackageModule(sym) + if (phase.id < currentRun.typerPhase.id) { + val sym = tp.typeSymbol + if (sym.hasPackageFlag && analyzer.packageObjects.deferredOpen.remove(sym)) + openPackageModule(sym) + } tp.nonLocalMember(nom) } while ((selectors ne Nil) && result == NoSymbol) { if (current.introduces(name)) - result = maybeNonLocalMember(current.name asTypeOf name) - else if (!current.isWildcard && current.hasName(name)) + result = maybeNonLocalMember(current.name.asTypeOf(name)) + else if (!current.isWildcard && !current.isGiven && current.hasName(name)) renamed = true - else if (current.isWildcard && !renamed && !requireExplicit) - result = maybeNonLocalMember(name) - + else if (!renamed && !requireExplicit) + if (current.isWildcard) + result = maybeNonLocalMember(name) + else if (current.isGiven) + result = maybeNonLocalMember(name).filter(_.isImplicit) + .orElse(maybeNonLocalMember(name.toTypeName).filter(_.isImplicit)) if (result == NoSymbol) selectors = selectors.tail } @@ -1971,8 +1918,8 @@ trait Contexts { self: Analyzer => if (isRootImport) !definitions.isUnimportableUnlessRenamed(sym) else definitions.isImportable(sym) ) match { - case filtered: NoSymbol => TupleOfNullAndNoSymbol - case _ => (current, result) + case _: NoSymbol => TupleOfNullAndNoSymbol + case _ => (current, result) } } @@ -1992,7 +1939,7 @@ trait Contexts { self: Analyzer => else s"(expr=${tree.expr}, ${result.fullLocationString})" }") if (settings.warnUnusedImport && !isRootImport && result != NoSymbol && pos != NoPosition) - allUsedSelectors(this) += sel + recordImportUsage(this, sel) } def allImportedSymbols: Iterable[Symbol] = diff --git a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala index 3069d4818f9d..f4270492cfc1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala +++ b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 4021cd9e4ba4..efd2717a04eb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,8 +13,9 @@ package scala.tools.nsc package typechecker -import scala.tools.nsc.symtab.Flags +import scala.annotation._ import scala.collection.mutable +import scala.tools.nsc.symtab.Flags /** Duplicate trees and re-type check them, taking care to replace * and create fresh symbols for new local definitions. @@ -195,7 +196,7 @@ abstract class Duplicators extends Analyzer { /** Optionally cast this tree into some other type, if required. * Unless overridden, just returns the tree. */ - def castType(tree: Tree, pt: Type): Tree = tree + def castType(tree: Tree, @unused pt: Type): Tree = tree /** Special typer method for re-type checking trees. It expects a typed tree. * Returns a typed tree that has fresh symbols for all definitions in the original tree. @@ -293,7 +294,7 @@ abstract class Duplicators extends Analyzer { tree.symbol = updateSym(origtreesym) super.typed(tree.clearType(), mode, pt) - case Select(th @ This(_), sel) if (oldClassOwner ne null) && (th.symbol == oldClassOwner) => + case Select(th @ This(_), _) if (oldClassOwner ne null) && (th.symbol == oldClassOwner) => // We use the symbol name instead of the tree name because the symbol // may have been name mangled, rendering the tree name obsolete. // ...but you can't just do a Select on a name because if the symbol is @@ -313,7 +314,7 @@ abstract class Duplicators extends Analyzer { case ((alt, tpe)) :: Nil => log(s"Arrested overloaded type in Duplicators, narrowing to ${alt.defStringSeenAs(tpe)}\n Overload was: $memberString") Select(This(newClassOwner), alt) - case xs => + case _ => alts filter (alt => (alt.paramss corresponds tree.symbol.paramss)(_.size == _.size)) match { case alt :: Nil => log(s"Resorted to parameter list arity to disambiguate to $alt\n Overload was: $memberString") @@ -354,7 +355,7 @@ abstract class Duplicators extends Analyzer { val scrutTpe = scrut1.tpe.widen val cases1 = { if (scrutTpe.isFinalType) cases filter { - case CaseDef(Bind(_, pat @ Typed(_, tpt)), EmptyTree, body) => + case CaseDef(Bind(_, Typed(_, tpt)), EmptyTree, body) => // the typed pattern is not incompatible with the scrutinee type scrutTpe matchesPattern fixType(tpt.tpe) case CaseDef(Typed(_, tpt), EmptyTree, body) => diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala index 439aedac1c26..d50636f6c514 100644 --- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index aab2d0d69f4c..89b75bd3eb67 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -24,8 +24,9 @@ import scala.collection.mutable, mutable.{LinkedHashMap, ListBuffer} import scala.language.implicitConversions import scala.reflect.internal.util.{ReusableInstance, Statistics, TriState} import scala.reflect.internal.TypesStats -import scala.tools.nsc.Reporting.WarningCategory +import scala.tools.nsc.Reporting.WarningCategory.{Scala3Migration, WFlagSelfImplicit} import symtab.Flags._ +import PartialFunction.cond /** This trait provides methods to find various kinds of implicits. * @@ -126,19 +127,67 @@ trait Implicits extends splain.SplainData { if (settings.areStatisticsEnabled) statistics.stopCounter(findMemberImpl, findMemberStart) if (settings.areStatisticsEnabled) statistics.stopCounter(subtypeImpl, subtypeStart) - val rts = result.tree.symbol - if (result.isSuccess && rts != null) { + if (result.isSuccess) { + val rts = { + val infoSym = if (result.implicitInfo != null) result.implicitInfo.sym else NoSymbol + infoSym.orElse { + val rts0 = result.tree.symbol + if (rts0 != null) rts0 else NoSymbol + } + } if (settings.lintImplicitRecursion) { - val s = if (rts.isAccessor) rts.accessed else if (rts.isModule) rts.moduleClass else rts - if (s != NoSymbol && context.owner.hasTransOwner(s)) - context.warning(result.tree.pos, s"Implicit resolves to enclosing $rts", WarningCategory.WFlagSelfImplicit) + val target = + if (rts.isAccessor) rts.accessed + else if (rts.isModule) rts.moduleClass + else rts + def wrapped = { + val sym = tree match { + case NamedApplyBlock(i) => i.original.symbol + case t => t.symbol + } + if (sym == null) "expression" else if (sym.isMethod) s"result of $sym" else sym.toString + } + val rtsIsImplicitWrapper = isView && rts.isMethod && rts.isSynthetic && rts.isImplicit + def isSelfEnrichment(encl: Symbol): Boolean = + Option(tree.symbol).exists(s => s.isParamAccessor && s.owner == encl && !encl.isDerivedValueClass) + def targetsUniversalMember(target: => Type): Boolean = cond(pt) { + case TypeRef(pre, sym, _ :: RefinedType(WildcardType :: Nil, decls) :: Nil) => + sym == FunctionClass(1) && + decls.exists(d => d.isMethod && d.info == WildcardType && isUniversalMember(target.member(d.name))) + } + def targetsImplicitWrapper(encl: Symbol): Boolean = + encl.owner == rts.owner && encl.isClass && encl.isImplicit && encl.name == rts.name.toTypeName + if (target != NoSymbol) + context.owner.ownersIterator + .find(encl => encl == target || rtsIsImplicitWrapper && targetsImplicitWrapper(encl)) + .foreach { encl => + var doWarn = false + var help = "" + if (!encl.isClass) { + doWarn = true + if (encl.isMethod && targetsUniversalMember(encl.info.finalResultType)) + help = s"; the conversion adds a member of AnyRef to $wrapped" + } + else if (encl.isModuleClass) { + doWarn = true + } + else if (isSelfEnrichment(encl)) { + doWarn = true + help = s"; the enrichment wraps $wrapped" + } + else if (targetsUniversalMember(encl.info)) { + doWarn = true + help = s"; the conversion adds a member of AnyRef to $wrapped" + } + if (doWarn) + context.warning(result.tree.pos, s"Implicit resolves to enclosing $encl$help", WFlagSelfImplicit) + } } - if (result.inPackagePrefix && currentRun.isScala3) { val msg = - s"""Implicit $rts was found in a package prefix of the required type, which is not part of the implicit scope in Scala 3. + s"""Implicit $rts was found in a package prefix of the required type, which is not part of the implicit scope in Scala 3 (or with -Xsource-features:package-prefix-implicits). |For migration, add `import ${rts.fullNameString}`.""".stripMargin - context.warning(result.tree.pos, msg, WarningCategory.Scala3Migration) + context.warning(result.tree.pos, msg, Scala3Migration) } } implicitSearchContext.emitImplicitDictionary(result) @@ -176,7 +225,7 @@ trait Implicits extends splain.SplainData { val tvars = tpars map (TypeVar untouchable _) val tpSubsted = tp.subst(tpars, tvars) - val search = new ImplicitSearch(EmptyTree, functionType(List(tpSubsted), AnyTpe), true, context.makeImplicit(reportAmbiguousErrors = false), isByNamePt = false) + val search = new ImplicitSearch(EmptyTree, functionType(List(tpSubsted), AnyTpe), isView = true, context.makeImplicit(reportAmbiguousErrors = false), isByNamePt = false) search.allImplicitsPoly(tvars) } @@ -283,7 +332,7 @@ trait Implicits extends splain.SplainData { /** Does type `tp` contain an Error type as parameter or result? */ private final def containsError(tp: Type): Boolean = tp match { - case PolyType(tparams, restpe) => + case PolyType(_, restpe) => containsError(restpe) case NullaryMethodType(restpe) => containsError(restpe) @@ -616,7 +665,7 @@ trait Implicits extends splain.SplainData { @tailrec def loop(ois: List[OpenImplicit], isByName: Boolean): Option[OpenImplicit] = ois match { - case hd :: tl if (isByName || hd.isByName) && hd.pt <:< pt => Some(hd) + case hd :: _ if (isByName || hd.isByName) && hd.pt <:< pt => Some(hd) case hd :: tl => loop(tl, isByName || hd.isByName) case _ => None } @@ -731,7 +780,7 @@ trait Implicits extends splain.SplainData { if (mt.isImplicit) loop(restpe, pt) else pt match { - case tr @ TypeRef(pre, sym, args) => + case TypeRef(pre, sym, args) => if (sym.isAliasType) loop(tp, pt.dealias) else if (sym.isAbstractType) loop(tp, pt.lowerBound) else { @@ -1200,7 +1249,7 @@ trait Implicits extends splain.SplainData { firstPending == alt || ( try improves(firstPending, alt) catch { - case e: CyclicReference => + case _: CyclicReference => devWarning(s"Discarding $firstPending during implicit search due to cyclic reference.") true } @@ -1341,7 +1390,7 @@ trait Implicits extends splain.SplainData { if (sym.isPackageClass) (sym.packageObject.typeOfThis, true) else (singleType(pre, companionSymbolOf(sym, context)), false) val preInfos = { - if (currentRun.isScala3Cross && inPackagePrefix) Iterator.empty + if (currentRun.sourceFeatures.packagePrefixImplicits && inPackagePrefix) Iterator.empty else pre1.implicitMembers.iterator.map(mem => new ImplicitInfo(mem.name, pre1, mem, inPackagePrefix = inPackagePrefix)) } val mergedInfos = if (symInfos.isEmpty) preInfos else { @@ -1564,7 +1613,7 @@ trait Implicits extends splain.SplainData { // can't generate a reference to a value that's abstracted over by an existential if (containsExistential(tp1)) EmptyTree else manifestFactoryCall("singleType", tp, gen.mkAttributedQualifier(tp1)) - case ConstantType(value) => + case ConstantType(_) => manifestOfType(tp1.deconst, FullManifestClass) case TypeRef(pre, sym, args) => if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) { @@ -1604,7 +1653,7 @@ trait Implicits extends splain.SplainData { if (hasLength(parents, 1)) findManifest(parents.head) else if (full) manifestFactoryCall("intersectionType", tp, parents map findSubManifest: _*) else mot(erasure.intersectionDominator(parents), from, to) - case ExistentialType(tparams, result) => + case ExistentialType(_, _) => mot(tp1.skolemizeExistential, from, to) case _ => EmptyTree diff --git a/src/compiler/scala/tools/nsc/typechecker/ImportTracking.scala b/src/compiler/scala/tools/nsc/typechecker/ImportTracking.scala new file mode 100644 index 000000000000..cbad8fa6ce01 --- /dev/null +++ b/src/compiler/scala/tools/nsc/typechecker/ImportTracking.scala @@ -0,0 +1,192 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.tools.nsc +package typechecker + +import scala.annotation.nowarn +import scala.collection.mutable +import scala.reflect.internal.Chars.{isLineBreakChar, isWhitespace} +import scala.reflect.internal.util.CodeAction +import scala.tools.nsc.Reporting.WarningCategory + +/** Track import clauses and usages for -Wunused:imports reporting. + */ +trait ImportTracking { self: Analyzer => + import global._ + + // Associate info with info at import keyword, plus owner for warning filtering. `import a.x, b.x` -> `(b, a, owner)` + private type TrackedInfo = (ImportInfo, ImportInfo, Symbol) + + private val usedSelectors = mutable.Map.empty[ImportInfo, mutable.Set[ImportSelector]] + private val importInfos = mutable.Map.empty[CompilationUnit, List[TrackedInfo]].withDefaultValue(Nil) + + def recordImportUsage(info: ImportInfo, sel: ImportSelector): Unit = usedSelectors.get(info) match { + case Some(sels) => sels.addOne(sel) + case None => usedSelectors.put(info, mutable.Set(sel)) + } + + def recordImportContext(ctx: Context): Unit = ctx.firstImport.foreach { info => + val keyword = + if (info.pos.start != info.pos.point) info + else ctx.imports.find(p => p.pos.isDefined && p.pos.start != p.pos.point).getOrElse(info) + importInfos(ctx.unit) ::= (info, keyword, ctx.owner) : @nowarn + } + + def warnUnusedImports(unit: CompilationUnit): Unit = if (!unit.isJava) { + def checkDeprecatedElementInPath(selector: ImportSelector, info: ImportInfo): String = { + def msg(sym: Symbol) = sym.deprecationMessage.map(": " + _).getOrElse("") + def badName(name: Name) = + info.qual.tpe.member(name) match { + case m if m.isDeprecated => Some(s" of deprecated $m${msg(m)}") + case _ => None + } + val badSelected = + if (!selector.isMask && selector.isSpecific) badName(selector.name).orElse(badName(selector.name.toTypeName)) + else None + def badFrom = { + val sym = info.qual.symbol + if (sym.isDeprecated) Some(s" from deprecated $sym${msg(sym)}") else None + } + badSelected.orElse(badFrom).getOrElse("") + } + def warnUnusedSelections(infos: List[TrackedInfo]): Unit = { + type Culled = (ImportSelector, TrackedInfo) + def keyInfoOfTracked(info: TrackedInfo): ImportInfo = info._2 + def keyInfoOfCulled(culled: Culled): ImportInfo = keyInfoOfTracked(culled._2) + def infoOfCulled(culled: Culled): ImportInfo = culled._2._1 + val unused: List[Culled] = + infos.flatMap { + case (tracked @ (info, _, _)) => + val used = usedSelectors.remove(info).getOrElse(mutable.Set.empty) + info.tree.selectors.collect { + case selector if !selector.isMask && !used(selector) => selector -> tracked + } + }.sortBy { case (_, (info, _, _)) => info.pos.start } // stable sort on info.pos preserves order of selectors + def emit(culled: Culled, actions: List[CodeAction]): Unit = culled match { + case (selector, (info, _, owner)) => + val pos = info.posOf(selector) + val origin = info.fullSelectorString(selector) + val addendum = checkDeprecatedElementInPath(selector, info) + runReporting.warning(pos, s"Unused import$addendum", WarningCategory.UnusedImports, owner, origin, actions) + } + // If the rest of the line is blank, include it in the final edit position. (Delete trailing whitespace.) + // If replacement is empty, and the prefix of the line is also blank, then include that, too. (Del blank line.) + def editPosAt(pos: Position, replacement: String): Position = { + val content = pos.source.content + val prev = content.lastIndexWhere(c => !isWhitespace(c), end = pos.start - 1) + val emptyLeft = prev < 0 || isLineBreakChar(content(prev)) + val next = content.indexWhere(c => !isWhitespace(c), from = pos.end) + val emptyRight = next < 0 || isLineBreakChar(content(next)) + val deleteLine = emptyLeft && emptyRight && replacement.isEmpty + val bump = if (deleteLine) 1 else 0 + val p1 = if (next >= 0 && emptyRight) pos.withEnd(next + bump) else pos + val p2 = if (deleteLine) p1.withStart(prev + 1) else p1 + p2 + } + def isSingleSelector(infos: List[TrackedInfo]): Boolean = infos match { + case (info, _, _) :: Nil => info.tree.selectors.size == 1 + case _ => false + } + def emitEdits(): Unit = { + def edit(pos: Position, replacement: String) = + runReporting.codeAction("unused import", editPosAt(pos, replacement), replacement, desc = "remove import") + def delete(pos: Position) = edit(pos, replacement = "") + + val statements = infos.groupBy(keyInfoOfTracked) // keyInfo -> tracked infos in statement + + unused.groupBy(keyInfoOfCulled).foreach { // keyInfo -> culled selectors in statement + case (keyInfo, culled :: Nil) if isSingleSelector(statements(keyInfo)) => // import a.x + emit(culled, actions = delete(keyInfo.pos)) // just one warning with delete + case (keyInfo, culleds) => // import a.x, b.{y, z} + val tracking = culleds.groupBy(infoOfCulled) // info -> Culled selectors (group by import clause) + val deleting = tracking.view.mapValues(_.map(_._1)).toMap // info -> selectors to remove: b.{y, z} -> y + val existing = statements(keyInfo).map(_._1).sortBy(_.tree.pos.start) // infos for a, b + val (editing, keeping) = existing.partition(deleting.contains(_)) // deleting = info has a selector to del + val (removing, updating) = editing.partition(info => info.tree.selectors.length == deleting(info).size) + if (keeping.isEmpty && updating.isEmpty) { // all clauses are removed in the current statement + // existing.flatMap(tracking) + val ordered = culleds.sortBy(_._1.namePos) + ordered.init.foreach(emit(_, actions = Nil)) // emit warnings for N-1 selectors + val imports = existing.map(_.tree) + val editPos = wrappingPos(imports.head.pos, imports) // reconstitute range of import statement + emit(ordered.last, actions = delete(editPos)) // at Nth selector, delete the statement + } + else + foreachWithIndex(existing) { (info, i) => + if (removing.contains(info)) { + val toEmit = tracking(info).sortBy(_._1.namePos) + toEmit.init.foreach(emit(_, actions = Nil)) // emit warnings for N-1 selectors for clause + // normally, delete from start of this clause to start of next clause: a.x, b.{y, z} from a to b + // but if this is the last clause, then also delete the comma following the last undeleted clause. + // also if this is the first clause, start includes the keyword, so advance it to the name (point) + val n = existing.size + val editPos = { + val p0 = info.tree.pos.withStart(info.tree.pos.point) + if (i == n - 1) p0 + else p0.withEnd(existing(i + 1).tree.pos.start) + } + val actions = + if (n > 1 && i == n - 1) { + val prev = existing.lastIndexWhere(!deleting.contains(_)) + val prevPos = existing(prev).tree.pos + val commaPos = prevPos.copyRange(start = prevPos.end, end = existing(prev + 1).tree.pos.start) + delete(commaPos) ++ delete(editPos) + } + else delete(editPos) + emit(toEmit.last, actions) // at Nth selector, delete the clause (and maybe a comma) + } + else if (updating.contains(info)) { + val toEmit = tracking(info).sortBy(_._1.namePos) + val remaining = info.tree.selectors.filter(!deleting(info).contains(_)) + if (remaining.size == 1) { // reformat without braces if remaining selector a.x + toEmit.init.foreach(emit(_, actions = Nil)) + val editPos = info.tree.pos.withStart(info.tree.pos.point) // exclude import keyword if i == 0 + val revised = info.tree.copy(selectors = remaining) + emit(toEmit.last, edit(editPos, revised.toString.stripPrefix("import "))) // exclude the keyword + } + else { + // emit an edit at each change to preserve formatting. + // there are multiple selectors, comma-separated in braces {x, y => w, z}. + // delete from start of name to start of next name, + // except at last selector, where it's necessary to delete a preceding comma. + // find the previous selector that is not deleted, and delete from its comma to start of next name. + val selectors = info.tree.selectors + val infoPos = info.tree.pos + val last = selectors.last + val content = infoPos.source.content + toEmit.foreach { case culled @ (selector, (_, _, _)) => + if (selector != last) { + val index = selectors.indexWhere(_ == selector) + val editPos = infoPos.copyRange(start = selector.namePos, end = selectors(index + 1).namePos) + emit(culled, delete(editPos)) + } + else { + // info.tree.pos.end is one char after rbrace + val prev = selectors.lastIndexWhere(remaining.contains(_)) + val comma = content.indexWhere(_ == ',', from = selectors(prev).namePos) + val commaPos = infoPos.copyRange(start = comma, end = selectors(prev + 1).namePos) + val editPos = infoPos.copyRange(start = selector.namePos, end = info.tree.pos.end - 1) + emit(culled, delete(commaPos) ++ delete(editPos)) + } + } + } + } + } + } + } + if (settings.quickfix.isSetByUser && !settings.quickFixSilent) emitEdits() + else unused.foreach(emit(_, actions = Nil)) + } + importInfos.remove(unit).foreach(warnUnusedSelections) + } +} diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index c032682bcdb4..820729d21c73 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -473,7 +473,7 @@ trait Infer extends Checkable { if (isConservativelyCompatible(restpe.instantiateTypeParams(tparams, tvars), pt)) map2(tparams, tvars)((tparam, tvar) => try instantiateToBound(tvar, varianceInTypes(formals)(tparam)) - catch { case ex: NoInstance => WildcardType } + catch { case _: NoInstance => WildcardType } ) else WildcardType.fillList(tvars.length) @@ -581,34 +581,17 @@ trait Infer extends Checkable { "argument expression's type is not compatible with formal parameter type" + foundReqMsg(tp1, pt1)) } val targs = solvedTypes(tvars, tparams, varianceInTypes(formals), upper = false, lubDepth(formals) max lubDepth(argtpes)) - if (settings.warnInferAny && !fn.isEmpty) { - // Can warn about inferring Any/AnyVal/Object as long as they don't appear - // explicitly anywhere amongst the formal, argument, result, or expected type. - // ...or lower bound of a type param, since they're asking for it. - var checked, warning = false - def checkForAny(): Unit = { - val collector = new ContainsAnyCollector(topTypes) { - val seen = mutable.Set.empty[Type] - override def apply(t: Type): Unit = { - def saw(dw: Type): Unit = - if (!result && !seen(dw)) { - seen += dw - if (!dw.typeSymbol.isRefinementClass) super.apply(dw) - } - if (!result && !seen(t)) t.dealiasWidenChain.foreach(saw) - } - } - @inline def containsAny(t: Type): Boolean = collector.collect(t) - val hasAny = containsAny(pt) || containsAny(restpe) || - formals.exists(containsAny) || - argtpes.exists(containsAny) || - tparams.exists(x => containsAny(x.info.lowerBound)) - checked = true - warning = !hasAny + // Any "top type" in the constraint mitigates the warning, instead of a precise match such as: + // !tvar.constr.loBounds.contains(targ) + // For example, don't require this arg, where the lub of `AnyRef` and `V` yields the `Any`. + // this.forall(kv => map.getOrElse[Any](kv._1, Map.DefaultSentinelFn()) == kv._2) + if (settings.warnInferAny && !fn.isEmpty) + foreach2(targs, tvars) { (targ, tvar) => + if (topTypes.contains(targ.typeSymbol) && + !tvar.constr.loBounds.exists(t => topTypes.contains(t.typeSymbol)) && + !tvar.constr.hiBounds.exists(t => topTypes.contains(t.typeSymbol))) + context.warning(fn.pos, s"a type was inferred to be `${targ.typeSymbol.name}`; this may indicate a programming error.", WarningCategory.LintInferAny) } - def canWarnAboutAny = { if (!checked) checkForAny() ; warning } - targs.foreach(targ => if (topTypes.contains(targ.typeSymbol) && canWarnAboutAny) context.warning(fn.pos, s"a type was inferred to be `${targ.typeSymbol.name}`; this may indicate a programming error.", WarningCategory.LintInferAny)) - } adjustTypeArgs(tparams, tvars, targs, restpe) } @@ -903,12 +886,13 @@ trait Infer extends Checkable { case _ => tpe2 match { case PolyType(tparams2, rtpe2) => isAsSpecificValueType(tpe1, rtpe2, undef1, undef2 ::: tparams2) - case _ if !currentRun.isScala3ImplicitResolution => existentialAbstraction(undef1, tpe1) <:< existentialAbstraction(undef2, tpe2) + case _ if !currentRun.sourceFeatures.implicitResolution => + existentialAbstraction(undef1, tpe1) <:< existentialAbstraction(undef2, tpe2) case _ => // Backport of fix for https://github.com/scala/bug/issues/2509 - // from Dotty https://github.com/lampepfl/dotty/commit/89540268e6c49fb92b9ca61249e46bb59981bf5a + // from Dotty https://github.com/scala/scala3/commit/89540268e6c49fb92b9ca61249e46bb59981bf5a // - // Note that as of https://github.com/lampepfl/dotty/commit/b9f3084205bc9fcbd2a5181d3f0e539e2a20253a + // Note that as of https://github.com/scala/scala3/commit/b9f3084205bc9fcbd2a5181d3f0e539e2a20253a // Dotty flips variances throughout, not just at the top level. We follow that behaviour here. val e1 = existentialAbstraction(undef1, tpe1) @@ -1529,9 +1513,9 @@ trait Infer extends Checkable { def finish(s: Symbol): Unit = tree.setSymbol(s).setType(pre.memberType(s)) ranked match { case best :: competing :: _ => AmbiguousMethodAlternativeError(tree, pre, best, competing, argtpes, pt, isLastTry) // ambiguous - case best :: nil => finish(best) - case nil if pt.isWildcard => NoBestMethodAlternativeError(tree, argtpes, pt, isLastTry) // failed - case nil => bestForExpectedType(WildcardType, isLastTry) // failed, but retry with WildcardType + case best :: _ => finish(best) + case _ if pt.isWildcard => NoBestMethodAlternativeError(tree, argtpes, pt, isLastTry) // failed + case _ => bestForExpectedType(WildcardType, isLastTry) // failed, but retry with WildcardType } } @@ -1564,10 +1548,9 @@ trait Infer extends Checkable { def finish(sym: Symbol, tpe: Type) = tree setSymbol sym setType tpe // Alternatives which conform to bounds def checkWithinBounds(sym: Symbol): Unit = sym.alternatives match { - case Nil if argtypes.exists(_.isErroneous) => - case Nil => fail() - case alt :: Nil => finish(alt, pre memberType alt) - case alts @ (hd :: _) => + case Nil => if (!argtypes.exists(_.isErroneous)) fail() + case alt :: Nil => finish(alt, pre memberType alt) + case alts @ hd :: _ => log(s"Attaching AntiPolyType-carrying overloaded type to $sym") // Multiple alternatives which are within bounds; spin up an // overloaded type which carries an "AntiPolyType" as a prefix. @@ -1577,7 +1560,7 @@ trait Infer extends Checkable { finish(sym setInfo tpe, tpe) } matchingLength.alternatives match { - case Nil => fail() + case Nil => fail() case alt :: Nil => finish(alt, pre memberType alt) case _ => checkWithinBounds(matchingLength.filter { alt => @@ -1601,7 +1584,8 @@ trait Infer extends Checkable { case _ => mapOver(tp) } } - private lazy val topTypes: List[Symbol] = List(AnyClass, AnyValClass, ObjectClass) + + private lazy val topTypes: Set[Symbol] = Set(AnyClass, AnyValClass, ObjectClass, AnyRefClass) final case class AdjustedTypeArgs(okParams: List[Symbol], okArgs: List[Type], undetParams: List[Symbol], allArgs: List[Type]) } diff --git a/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala b/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala index c2e9710b00c5..7af94b66eabd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MacroAnnotationNamers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -58,11 +58,11 @@ trait MacroAnnotationNamers { self: Analyzer => case _ => abort("Unexpected tree: " + tree) } if (isPastTyper) sym.name.toTermName match { - case nme.IMPORT | nme.OUTER | nme.ANON_CLASS_NAME | nme.ANON_FUN_NAME | nme.CONSTRUCTOR => () - case _ => + case nme.IMPORT | nme.OUTER | nme.ANON_CLASS_NAME | nme.ANON_FUN_NAME | nme.CONSTRUCTOR => + case _ => tree match { - case md: DefDef => log("[+symbol] " + sym.debugLocationString) - case _ => + case _: DefDef => log("[+symbol] " + sym.debugLocationString) + case _ => } } tree.symbol = sym @@ -375,7 +375,7 @@ trait MacroAnnotationNamers { self: Analyzer => private implicit class RichType(tpe: Type) { def completeOnlyExpansions(sym: Symbol) = tpe match { case mec: MacroAnnotationNamer#MaybeExpandeeCompleter => mec.complete(sym, onlyExpansions = true) - case c => () + case _ => } } @@ -774,7 +774,7 @@ trait MacroAnnotationNamers { self: Analyzer => } def rewrapAfterTransform(stat: Tree, transformed: List[Tree]): List[Tree] = (stat, transformed) match { case (stat @ DocDef(comment, _), List(transformed: MemberDef)) => List(treeCopy.DocDef(stat, comment, transformed)) - case (stat @ DocDef(comment, _), List(transformed: DocDef)) => List(transformed) + case (DocDef(_, _), List(transformed: DocDef)) => List(transformed) case (_, Nil | List(_: MemberDef)) => transformed case (_, unexpected) => unexpected // NOTE: who knows how people are already using macro annotations, so it's scary to fail here } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 37ff30e96992..d58ac096241c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,16 +16,17 @@ package typechecker import java.lang.Math.min import symtab.Flags._ -import scala.reflect.internal.util.ScalaClassLoader -import scala.reflect.runtime.ReflectionUtils -import scala.reflect.internal.util.Statistics +import scala.annotation._ import scala.reflect.internal.TypesStats -import scala.reflect.macros.util._ -import scala.util.control.ControlThrowable import scala.reflect.internal.util.ListOfNil -import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes} +import scala.reflect.internal.util.ScalaClassLoader +import scala.reflect.internal.util.Statistics import scala.reflect.macros.compiler.DefaultMacroCompiler +import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes} +import scala.reflect.macros.util._ +import scala.reflect.runtime.ReflectionUtils import scala.tools.reflect.FastTrack +import scala.util.control.ControlThrowable import scala.util.control.NonFatal import Fingerprint._ @@ -186,7 +187,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers { case _ => Other } - val transformed = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => tparam) + val transformed = transformTypeTagEvidenceParams(macroImplRef, (_, tparam) => tparam) mmap(transformed)(p => if (p.isTerm) fingerprint(p.info) else Tagged(p.paramPos)) } @@ -223,9 +224,9 @@ trait Macros extends MacroRuntimes with Traces with Helpers { new AstTransformer { override def transform(tree: Tree) = { tree match { - case Literal(const @ Constant(x)) if tree.tpe == null => tree setType ConstantType(const) - case _ if tree.tpe == null => tree setType NoType - case _ => ; + case Literal(const @ Constant(_)) if tree.tpe == null => tree.setType(ConstantType(const)) + case _ if tree.tpe == null => tree.setType(NoType) + case _ => } super.transform(tree) } @@ -297,7 +298,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers { } ) } - private val macroImplBindingCache = perRunCaches.newAnyRefMap[Symbol, Option[MacroImplBinding]]() + private val macroImplBindingCache = perRunCaches.newMap[Symbol, Option[MacroImplBinding]]() def isBlackbox(expandee: Tree): Boolean = isBlackbox(dissectCore(expandee).symbol) def isBlackbox(macroDef: Symbol): Boolean = pluginsIsBlackbox(macroDef) @@ -549,7 +550,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers { def onSuppressed(expandee: Tree): Tree = expandee def onDelayed(expanded: Tree): Tree = expanded def onSkipped(expanded: Tree): Tree = expanded - def onFailure(expanded: Tree): Tree = { typer.infer.setError(expandee); expandee } + def onFailure(@unused expanded: Tree): Tree = { typer.infer.setError(expandee); expandee } def apply(desugared: Tree): Tree = { if (isMacroExpansionSuppressed(desugared)) onSuppressed(expandee) @@ -757,19 +758,21 @@ trait Macros extends MacroRuntimes with Traces with Helpers { expander(expandee) } - sealed abstract class MacroStatus(val result: Tree) - case class Success(expanded: Tree) extends MacroStatus(expanded) - case class Fallback(fallback: Tree) extends MacroStatus(fallback) { runReporting.seenMacroExpansionsFallingBack = true } - case class Delayed(delayed: Tree) extends MacroStatus(delayed) - case class Skipped(skipped: Tree) extends MacroStatus(skipped) - case class Failure(failure: Tree) extends MacroStatus(failure) - def Delay(expanded: Tree) = Delayed(expanded) - def Skip(expanded: Tree) = Skipped(expanded) + private sealed abstract class MacroStatus(val result: Tree) + private case class Success(expanded: Tree) extends MacroStatus(expanded) + private case class Fallback(fallback: Tree) extends MacroStatus(fallback) { + runReporting.seenMacroExpansionsFallingBack = true + } + private case class Delayed(delayed: Tree) extends MacroStatus(delayed) + private case class Skipped(skipped: Tree) extends MacroStatus(skipped) + private case class Failure(failure: Tree) extends MacroStatus(failure) + private def Delay(expanded: Tree) = Delayed(expanded) + private def Skip(expanded: Tree) = Skipped(expanded) /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroStatus = { + private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroStatus = { val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty @@ -829,7 +832,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers { /** Expands a macro when a runtime (i.e. the macro implementation) cannot be loaded * Meant for internal use within the macro infrastructure, don't use it elsewhere. */ - def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroStatus = { + private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroStatus = { import typer.TyperErrorGen._ val fallbackSym = expandee.symbol.nextOverriddenSymbol orElse MacroImplementationNotFoundError(expandee) macroLogLite(s"falling back to: $fallbackSym") diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index af10794e4145..d513fa6bf567 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index d8566291643c..036491205b2e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,7 @@ package scala.tools.nsc package typechecker -import scala.annotation.{nowarn, tailrec} +import scala.annotation._ import scala.collection.mutable import symtab.Flags._ import scala.reflect.internal.util.ListOfNil @@ -206,26 +206,6 @@ trait Namers extends MethodSynthesis { else innerNamer } - // FIXME - this logic needs to be thoroughly explained - // and justified. I know it's wrong with respect to package - // objects, but I think it's also wrong in other ways. - protected def conflict(newS: Symbol, oldS: Symbol) = ( - ( !oldS.isSourceMethod - || nme.isSetterName(newS.name) - || newS.isTopLevel - ) && - !( // @M: allow repeated use of `_` for higher-order type params - (newS.owner.isTypeParameter || newS.owner.isAbstractType) - // FIXME: name comparisons not successful, are these underscores - // sometimes nme.WILDCARD and sometimes tpnme.WILDCARD? - && (newS.name string_== nme.WILDCARD) - ) - ) - - private def allowsOverload(sym: Symbol) = ( - sym.isSourceMethod && sym.owner.isClass && !sym.isTopLevel - ) - private def inCurrentScope(m: Symbol): Boolean = { if (owner.isClass) owner == m.owner else context.scope.lookupSymbolEntry(m) match { @@ -237,44 +217,42 @@ trait Namers extends MethodSynthesis { /** Enter symbol into context's scope and return symbol itself */ def enterInScope(sym: Symbol): sym.type = enterInScope(sym, context.scope) + // There is nothing which reconciles a package's scope with + // the package object's scope. This is the source of many bugs + // with e.g. defining a case class in a package object. When + // compiling against classes, the class symbol is created in the + // package and in the package object, and the conflict is undetected. + // There is also a non-deterministic outcome for situations like + // an object with the same name as a method in the package object. /** Enter symbol into given scope and return symbol itself */ def enterInScope(sym: Symbol, scope: Scope): sym.type = { - // FIXME - this is broken in a number of ways. - // - // 1) If "sym" allows overloading, that is not itself sufficient to skip - // the check, because "prev.sym" also must allow overloading. - // - // 2) There is nothing which reconciles a package's scope with - // the package object's scope. This is the source of many bugs - // with e.g. defining a case class in a package object. When - // compiling against classes, the class symbol is created in the - // package and in the package object, and the conflict is undetected. - // There is also a non-deterministic outcome for situations like - // an object with the same name as a method in the package object. - - // allow for overloaded methods - if (!allowsOverload(sym)) { - val prev = scope.lookupEntry(sym.name) - if ((prev ne null) && prev.owner == scope && conflict(sym, prev.sym)) { - if (sym.isSynthetic || prev.sym.isSynthetic) { - handleSyntheticNameConflict(sym, prev.sym) - handleSyntheticNameConflict(prev.sym, sym) - } - DoubleDefError(sym, prev.sym) - sym setInfo ErrorType - scope unlink prev.sym // let them co-exist... - // FIXME: The comment "let them co-exist" is confusing given that the - // line it comments unlinks one of them. What does it intend? - } - } if (sym.isModule && sym.isSynthetic && sym.owner.isClass && !sym.isTopLevel) { val entry = scope.lookupEntry(sym.name.toTypeName) if (entry eq null) scope enter sym else scope.enterBefore(sym, entry) - } else - scope enter sym + } else { + val disallowsOverload = !(sym.isSourceMethod && sym.owner.isClass && !sym.isTopLevel) + if (disallowsOverload) { + val prev = scope.lookupEntry(sym.name) + val dde = + (prev ne null) && prev.owner == scope && + (!prev.sym.isSourceMethod || nme.isSetterName(sym.name) || sym.isTopLevel) && + !((sym.owner.isTypeParameter || sym.owner.isAbstractType) && (sym.name string_== nme.WILDCARD)) + // @M: allow repeated use of `_` for higher-order type params + if (dde) { + if (sym.isSynthetic || prev.sym.isSynthetic) { + handleSyntheticNameConflict(sym, prev.sym) + handleSyntheticNameConflict(prev.sym, sym) + } + DoubleDefError(sym, prev.sym) + sym.setInfo(ErrorType) + scope.unlink(prev.sym) // retain the new erroneous symbol in scope (was for IDE); see #scala/bug#2779 + } + } + scope.enter(sym) + } } /** Logic to handle name conflicts of synthetically generated symbols @@ -361,7 +339,7 @@ trait Namers extends MethodSynthesis { } def createImportSymbol(tree: Import) = - NoSymbol.newImport(tree.pos) setInfo (namerOf(tree.symbol) importTypeCompleter tree) + NoSymbol.newImport(tree.pos).setInfo(namerOf(tree.symbol).importTypeCompleter(tree)) /** All PackageClassInfoTypes come from here. */ def createPackageSymbol(pos: Position, pid: RefTree): Symbol = { @@ -385,7 +363,7 @@ trait Namers extends MethodSynthesis { } } - private def enterClassSymbol(tree: ClassDef, clazz: ClassSymbol): Symbol = { + private def enterClassSymbol(@unused tree: ClassDef, clazz: ClassSymbol): Symbol = { var sourceFile = clazz.sourceFile if (sourceFile != null && sourceFile != contextFile) devWarning(s"Source file mismatch in $clazz: ${sourceFile} vs. $contextFile") @@ -467,7 +445,7 @@ trait Namers extends MethodSynthesis { if (existingModule.isModule && !existingModule.hasPackageFlag && inCurrentScope(existingModule) && (currentRun.canRedefine(existingModule) || existingModule.isSynthetic)) { updatePosFlags(existingModule, tree.pos, moduleFlags) setPrivateWithin(tree, existingModule) - existingModule.moduleClass andAlso (setPrivateWithin(tree, _)) + existingModule.moduleClass.andAlso(setPrivateWithin(tree, _)) context.unit.synthetics -= existingModule tree.symbol = existingModule } @@ -574,7 +552,7 @@ trait Namers extends MethodSynthesis { lookup(original.toTermName) != NoSymbol || lookup(original.toTypeName) != NoSymbol } - if (!s.isWildcard && base != ErrorType) { + if (!s.isWildcard && !s.isGiven && base != ErrorType) { val okay = isValid(from, base) || context.unit.isJava && ( // Java code... (nme.isModuleName(from) && isValid(from.dropModule, base)) // - importing Scala module classes || isValid(from, base.companion) // - importing type members from types @@ -589,8 +567,10 @@ trait Namers extends MethodSynthesis { // so don't warn for them. There is a corresponding special treatment // in the shadowing rules in typedIdent to (scala/bug#7232). In any case, // we shouldn't be emitting warnings for .java source files. - if (!context.unit.isJava) - checkNotRedundant(tree.pos withPoint fromPos, from, to) + if (!context.unit.isJava) { + val at = if (tree.pos.isRange) tree.pos.withPoint(fromPos) else tree.pos + checkNotRedundant(at, from, to) + } } } selectors.foreach(checkSelector) @@ -747,7 +727,7 @@ trait Namers extends MethodSynthesis { newNamer(context.make(tree, sym.moduleClass, sym.info.decls)) enterSyms tree.stats } - private def enterImport(tree: Import) = { + private def enterImport(tree: Import): Unit = { val sym = createImportSymbol(tree) tree.symbol = sym } @@ -811,10 +791,10 @@ trait Namers extends MethodSynthesis { } // Hooks which are overridden in the presentation compiler - def enterExistingSym(sym: Symbol, tree: Tree): Context = { + def enterExistingSym(@unused sym: Symbol, @unused tree: Tree): Context = { this.context } - def enterIfNotThere(sym: Symbol): Unit = { } + def enterIfNotThere(sym: Symbol): Unit = () def enterSyntheticSym(tree: Tree): Symbol = { enterSym(tree) @@ -830,7 +810,7 @@ trait Namers extends MethodSynthesis { case TypeBounds(lo, _) => // check that lower bound is not an F-bound // but carefully: class Foo[T <: Bar[_ >: T]] should be allowed - for (tp1 @ TypeRef(_, sym, _) <- lo) { + for (TypeRef(_, sym, _) <- lo) { if (settings.breakCycles.value) { if (!sym.maybeInitialize) { log(s"Cycle inspecting $lo for possible f-bounds: ${sym.fullLocationString}") @@ -1089,7 +1069,7 @@ trait Namers extends MethodSynthesis { /** Computes the type of the body in a ValDef or DefDef, and * assigns the type to the tpt's node. Returns the type. * - * Under `-Xsource:3-cross`, use `pt`, the type of the overridden member. + * Under `-Xsource-features`, use `pt`, the type of the overridden member. * But preserve the precise type of a whitebox macro. * For `def f = macro g`, here we see `def f = xp(g)` the expansion, * not the `isMacro` case: `openMacros` will be nonEmpty. @@ -1100,14 +1080,48 @@ trait Namers extends MethodSynthesis { * inline the def to "opt in". */ private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = { + class CheckOrDropStructural(drop: Boolean, rhsTpe: Type) extends TypeMap { + override def apply(tp: Type): Type = tp match { + case rt: RefinedType => + val sym = tree.symbol + val warns = rt.decls.filter(_.isOnlyRefinementMember) + if (warns.nonEmpty) { + if (drop) { + val keep = rt.decls.toList.filterNot(warns.toSet) + if (keep.isEmpty && rt.parents.sizeIs == 1) rt.parents.head + else { + val res = refinedType(rt.parents, rt.typeSymbol) + keep.foreach(res.decls.enter) + res + } + } else { + val cat = if (currentRun.isScala3) WarningCategory.Scala3Migration else WarningCategory.LintStructuralType + val msg = + if (currentRun.isScala3) s"in Scala 3 (or with -Xsource-features:no-infer-structural), $sym will no longer have a structural type" + else s"$sym has an inferred structural type" + context.warning(sym.pos, + s"""$msg: $rhsTpe + | members that can be accessed with a reflective call: ${warns.mkString(",")}""".stripMargin, + cat) + rt + } + } else rt + case _ => + mapOver(tp) + } + } val rhsTpe = tree match { case ddef: DefDef if tree.symbol.isTermMacro => defnTyper.computeMacroDefType(ddef, pt) // unreached, see methodSig case _ => defnTyper.computeType(tree.rhs, pt) } + val nonStructural = if (!tree.symbol.isLocalToBlock && (currentRun.isScala3 || settings.warnInferStructural)) + new CheckOrDropStructural(currentRun.sourceFeatures.noInferStructural, rhsTpe)(rhsTpe) + else rhsTpe tree.tpt.defineType { + // infer from overridden symbol, contingent on Xsource; exclude constants and whitebox macros val inferOverridden = currentRun.isScala3 && !pt.isWildcard && pt != NoType && !pt.isErroneous && - !(tree.isInstanceOf[ValDef] && tree.symbol.isFinal && isConstantType(rhsTpe)) && + !(tree.isInstanceOf[ValDef] && tree.symbol.isFinal && isConstantType(nonStructural)) && openMacros.isEmpty && { context.unit.transformed.get(tree.rhs) match { case Some(t) if t.hasAttachment[MacroExpansionAttachment] => @@ -1116,12 +1130,13 @@ trait Namers extends MethodSynthesis { case _ => true } } - val legacy = dropIllegalStarTypes(widenIfNecessary(tree.symbol, rhsTpe, pt)) - if (inferOverridden && currentRun.isScala3 && !currentRun.isScala3Cross && !(legacy =:= pt)) { + val legacy = dropIllegalStarTypes(widenIfNecessary(tree.symbol, nonStructural, pt)) + // <:< check as a workaround for scala/bug#12968 + def warnIfInferenceChanged(): Unit = if (!(legacy =:= pt || legacy <:< pt && pt <:< legacy)) { val pts = pt.toString val leg = legacy.toString val help = if (pts != leg) s" instead of $leg" else "" - val msg = s"under -Xsource:3-cross, the inferred type changes to $pts$help" + val msg = s"in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to $pts$help" val src = tree.pos.source val pos = { val eql = src.indexWhere(_ == '=', start = tree.rhs.pos.start, step = -1) @@ -1131,8 +1146,11 @@ trait Namers extends MethodSynthesis { val action = pos.map(p => runReporting.codeAction("add explicit type", p.focus, s": $leg", msg)).getOrElse(Nil) runReporting.warning(tree.pos, msg, WarningCategory.Scala3Migration, tree.symbol, action) } - if (inferOverridden && currentRun.isScala3Cross) pt - else legacy.tap(InferredImplicitError(tree, _, context)) + if (inferOverridden && currentRun.sourceFeatures.inferOverride) pt + else { + if (inferOverridden) warnIfInferenceChanged() + legacy.tap(InferredImplicitError(tree, _, context)) + } }.setPos(tree.pos.focus) tree.tpt.tpe } @@ -1453,7 +1471,7 @@ trait Namers extends MethodSynthesis { val resTp = { // When return type is inferred, we don't just use resTpFromOverride -- it must be packed and widened. - // Here, C.f has type String (unless -Xsource:3-cross): + // Here, C.f has type String (unless -Xsource-features:infer-override): // trait T { def f: Object }; class C extends T { def f = "" } // using resTpFromOverride as expected type allows for the following (C.f has type A): // trait T { def f: A }; class C extends T { implicit def b2a(t: B): A = ???; def f = new B } @@ -1494,7 +1512,7 @@ trait Namers extends MethodSynthesis { /** * For every default argument, insert a method symbol computing that default */ - def enterDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], tparams: List[TypeDef]): Unit = { + def enterDefaultGetters(meth: Symbol, @unused ddef: DefDef, vparamss: List[List[ValDef]], @unused tparams: List[TypeDef]): Unit = { val methOwner = meth.owner val search = DefaultGetterNamerSearch(context, meth, initCompanionModule = false) var posCounter = 1 @@ -1535,7 +1553,7 @@ trait Namers extends MethodSynthesis { * typechecked, the corresponding param would not yet have the "defaultparam" * flag. */ - private def addDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], tparams: List[TypeDef], overridden: Symbol): Unit = { + private def addDefaultGetters(meth: Symbol, ddef: DefDef, vparamss: List[List[ValDef]], @unused tparams: List[TypeDef], overridden: Symbol): Unit = { val DefDef(_, _, rtparams0, rvparamss0, _, _) = resetAttrs(deriveDefDef(ddef)(_ => EmptyTree).duplicate): @unchecked // having defs here is important to make sure that there's no sneaky tree sharing // in methods with multiple default parameters @@ -1656,7 +1674,7 @@ trait Namers extends MethodSynthesis { def createAndEnter(f: Symbol => Symbol): Unit } - private class DefaultGetterInCompanion(c: Context, meth: Symbol, initCompanionModule: Boolean) extends DefaultGetterNamerSearch { + private class DefaultGetterInCompanion(@unused c: Context, meth: Symbol, initCompanionModule: Boolean) extends DefaultGetterNamerSearch { private val module = companionSymbolOf(meth.owner, context) if (initCompanionModule) module.initialize private val cda: Option[ConstructorDefaultsAttachment] = module.attachments.get[ConstructorDefaultsAttachment] @@ -1694,7 +1712,7 @@ trait Namers extends MethodSynthesis { } } - private class DefaultMethodInOwningScope(c: Context, meth: Symbol) extends DefaultGetterNamerSearch { + private class DefaultMethodInOwningScope(@unused c: Context, meth: Symbol) extends DefaultGetterNamerSearch { private lazy val ownerNamer: Namer = { val ctx = context.nextEnclosing(c => c.scope.toList.contains(meth)) // TODO use lookup rather than toList.contains assert(ctx != NoContext, meth) @@ -1740,7 +1758,7 @@ trait Namers extends MethodSynthesis { patchSymInfo(pt) if (vdef.hasAttachment[MultiDefAttachment.type]) - vdef.symbol.updateAttachment(MultiDefAttachment) + vdef.symbol.updateAttachment[MultiDefAttachment.type](MultiDefAttachment) // derives the val's result type from type checking its rhs under the expected type `pt` // vdef.tpt is mutated, and `vdef.tpt.tpe` is `assignTypeToTree`'s result @@ -1806,12 +1824,9 @@ trait Namers extends MethodSynthesis { // log("typeDefSig(" + tpsym + ", " + tparams + ")") val tparamSyms = typer.reenterTypeParams(tparams) //@M make tparams available in scope (just for this abstypedef) val tp = typer.typedType(rhs).tpe match { - case TypeBounds(lt, rt) if (lt.isError || rt.isError) => - TypeBounds.empty - case tp @ TypeBounds(lt, rt) if (tdef.symbol hasFlag JAVA) => - TypeBounds(lt, rt) - case tp => - tp + case TypeBounds(lt, rt) if lt.isError || rt.isError => TypeBounds.empty + case TypeBounds(lt, rt) if tdef.symbol.hasFlag(JAVA) => TypeBounds(lt, rt) + case tp => tp } // see neg/bug1275, #3419 // used to do a rudimentary kind check here to ensure overriding in refinements diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index b28c136281b9..e22b682b98ca 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,9 +13,9 @@ package scala.tools.nsc package typechecker -import symtab.Flags._ import scala.collection.mutable import scala.reflect.ClassTag +import symtab.Flags._ import PartialFunction.cond /** @@ -55,20 +55,24 @@ trait NamesDefaults { self: Analyzer => qual: Option[Tree], targs: List[Tree], vargss: List[List[Tree]], - blockTyper: Typer - ) { } + blockTyper: Typer, + original: Tree, + ) object NamedApplyBlock { private[this] val tag = reflect.classTag[NamedApplyInfo] + def namedApplyInfo(t: Tree): Option[NamedApplyInfo] = t.attachments.get[NamedApplyInfo](tag) def unapply(b: Tree): Option[NamedApplyInfo] = b match { - case _: Block => b.attachments.get[NamedApplyInfo](tag) + case _: Block => namedApplyInfo(b) case _ => None } + def apply(stats: List[Tree], expr: Tree)(nai: NamedApplyInfo): Block = + Block(stats, expr.updateAttachment(nai)).updateAttachment(nai) } private def nameOfNamedArg(arg: Tree) = Some(arg) collect { case NamedArg(Ident(name), _) => name } def isNamedArg(arg: Tree) = arg match { case NamedArg(Ident(_), _) => true - case _ => false + case _ => false } /** @param pos maps indices from old to new */ @@ -81,7 +85,7 @@ trait NamesDefaults { self: Analyzer => /** @param pos maps indices from new to old (!) */ private def reorderArgsInv[T: ClassTag](args: List[T], pos: Int => Int): List[T] = { val argsArray = args.toArray - (argsArray.indices map (i => argsArray(pos(i)))).toList + argsArray.indices.map(i => argsArray(pos(i))).toList } /** returns `true` if every element is equal to its index */ @@ -184,11 +188,12 @@ trait NamesDefaults { self: Analyzer => // never used for constructor calls, they always have a stable qualifier def blockWithQualifier(qual: Tree, selected: Name) = { - val sym = blockTyper.context.owner.newValue(freshTermName(nme.QUAL_PREFIX)(typer.fresh), newFlags = ARTIFACT) setInfo uncheckedBounds(qual.tpe) setPos (qual.pos.makeTransparent) + val sym = blockTyper.context.owner.newValue(freshTermName(nme.QUAL_PREFIX)(typer.fresh), newFlags = ARTIFACT) + .setInfo(uncheckedBounds(qual.tpe)) + .setPos(qual.pos.makeTransparent) blockTyper.context.scope enter sym val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType) - // it stays in Vegas: scala/bug#5720, scala/bug#5727 - qual.changeOwner(blockTyper.context.owner, sym) + qual.changeOwner(blockTyper.context.owner, sym) // scala/bug#5720, scala/bug#5727 val newQual = atPos(qual.pos.focus)(blockTyper.typedQualifier(Ident(sym.name))) val baseFunTransformed = atPos(baseFun.pos.makeTransparent) { @@ -196,24 +201,23 @@ trait NamesDefaults { self: Analyzer => // assigning the correct method symbol, typedSelect will just assign the type. the reason // to still call 'typed' is to correctly infer singleton types, scala/bug#5259. val selectPos = - if(qual.pos.isRange && baseFun1.pos.isRange) qual.pos.union(baseFun1.pos).withStart(Math.min(qual.pos.end, baseFun1.pos.end)) + if (qual.pos.isRange && baseFun1.pos.isRange) + if (qual.pos == baseFun1.pos) qual.pos + else baseFun1.pos.union(qual.pos).withStart(Math.min(qual.pos.end, baseFun1.pos.end)) // use basefun point; why isn't start always qual.pos.end else baseFun1.pos val f = blockTyper.typedOperator(Select(newQual, selected).setSymbol(baseFun1.symbol).setPos(selectPos)) if (funTargs.isEmpty) f else TypeApply(f, funTargs).setType(baseFun.tpe) } - val b = Block(List(vd), baseFunTransformed) - .setType(baseFunTransformed.tpe).setPos(baseFun.pos.makeTransparent) - b.updateAttachment(NamedApplyInfo(Some(newQual), defaultTargs, Nil, blockTyper)) - b + NamedApplyBlock(List(vd), baseFunTransformed)(NamedApplyInfo(Some(newQual), defaultTargs, Nil, blockTyper, tree)) + .setType(baseFunTransformed.tpe) + .setPos(baseFun.pos.makeTransparent) } - def blockWithoutQualifier(defaultQual: Option[Tree]) = { - val b = atPos(baseFun.pos)(Block(Nil, baseFun).setType(baseFun.tpe)) - b.updateAttachment(NamedApplyInfo(defaultQual, defaultTargs, Nil, blockTyper)) - b - } + def blockWithoutQualifier(defaultQual: Option[Tree]) = + atPos(baseFun.pos)(NamedApplyBlock(Nil, baseFun)(NamedApplyInfo(defaultQual, defaultTargs, Nil, blockTyper, tree))) + .setType(baseFun.tpe) def moduleQual(pos: Position, classType: Type) = { // prefix does 'normalize', which fixes #3384 @@ -339,50 +343,61 @@ trait NamesDefaults { self: Analyzer => // begin transform tree match { - case NamedApplyBlock(info) => tree + case NamedApplyBlock(_) => tree // `fun` is typed. `namelessArgs` might be typed or not, if they are types are kept. case Apply(fun, namelessArgs) => val transformedFun = transformNamedApplication(typer, mode, pt)(fun, x => x) if (transformedFun.isErroneous) setError(tree) else { - val NamedApplyBlock(NamedApplyInfo(qual, targs, vargss, blockTyper)) = transformedFun: @unchecked + val NamedApplyBlock(NamedApplyInfo(qual, targs, vargss, blockTyper, _)) = transformedFun: @unchecked val Block(stats, funOnly) = transformedFun: @unchecked // type the application without names; put the arguments in definition-site order val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt) typedApp match { - case Apply(expr, typedArgs) if (typedApp :: typedArgs).exists(_.isErrorTyped) => + case Apply(_, typedArgs) if (typedApp :: typedArgs).exists(_.isErrorTyped) => setError(tree) // bail out with and erroneous Apply *or* erroneous arguments, see scala/bug#7238, scala/bug#7509 case Apply(expr, typedArgs) => - // Extract the typed arguments, restore the call-site evaluation order (using - // ValDef's in the block), change the arguments to these local values. - - // typedArgs: definition-site order - val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) - // valDefs: call-site order - val valDefs = argValDefs(reorderArgsInv(typedArgs, argPos), - reorderArgsInv(formals, argPos), - blockTyper) - // refArgs: definition-site order again - val refArgs = map3(reorderArgs(valDefs, argPos), formals, typedArgs)((vDefOpt, tpe, origArg) => vDefOpt match { - case None => origArg - case Some(vDef) => - val ref = gen.mkAttributedRef(vDef.symbol) - atPos(vDef.pos.focus) { - // for by-name parameters, the local value is a nullary function returning the argument - tpe.typeSymbol match { - case ByNameParamClass => Apply(ref, Nil) - case RepeatedParamClass => Typed(ref, Ident(tpnme.WILDCARD_STAR)) - case _ => ref + val isAnnot = mode.in(Mode.ANNOTmode) && { + val s = funOnly.symbol + s != null && s.isConstructor && s.owner.isNonBottomSubClass(AnnotationClass) + } + + if (isAnnot) { + NamedApplyBlock(stats, typedApp)(NamedApplyInfo(qual, targs, vargss :+ typedArgs, blockTyper, tree)) + .setType(typedApp.tpe) + .setPos(tree.pos.makeTransparent) + } else { + // Extract the typed arguments, restore the call-site evaluation order (using + // ValDef's in the block), change the arguments to these local values. + + // typedArgs: definition-site order + val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) + // valDefs: call-site order + val valDefs = argValDefs(reorderArgsInv(typedArgs, argPos), + reorderArgsInv(formals, argPos), + blockTyper) + // refArgs: definition-site order again + val refArgs = map3(reorderArgs(valDefs, argPos), formals, typedArgs)((vDefOpt, tpe, origArg) => vDefOpt match { + case None => origArg + case Some(vDef) => + val ref = gen.mkAttributedRef(vDef.symbol) + atPos(vDef.pos.focus) { + // for by-name parameters, the local value is a nullary function returning the argument + tpe.typeSymbol match { + case ByNameParamClass => Apply(ref, Nil) + case RepeatedParamClass => Typed(ref, Ident(tpnme.WILDCARD_STAR)) + case _ => origArg.attachments.get[UnnamedArg.type].foreach(ref.updateAttachment); ref + } } - } - }) - // cannot call blockTyper.typedBlock here, because the method expr might be partially applied only - val res = blockTyper.doTypedApply(tree, expr, refArgs, mode, pt) - res.setPos(res.pos.makeTransparent) - val block = Block(stats ::: valDefs.flatten, res).setType(res.tpe).setPos(tree.pos.makeTransparent) - block.updateAttachment(NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper)) - block + }) + // cannot call blockTyper.typedBlock here, because the method expr might be partially applied only + val res = blockTyper.doTypedApply(tree, expr, refArgs, mode, pt) + res.setPos(res.pos.makeTransparent) + NamedApplyBlock(stats ::: valDefs.flatten, res)(NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper, tree)) + .setType(res.tpe) + .setPos(tree.pos.makeTransparent) + } case _ => tree } } @@ -441,28 +456,39 @@ trait NamesDefaults { self: Analyzer => */ def addDefaults(givenArgs: List[Tree], qual: Option[Tree], targs: List[Tree], previousArgss: List[List[Tree]], params: List[Symbol], - pos: scala.reflect.internal.util.Position, context: Context): (List[Tree], List[Symbol]) = { + pos: scala.reflect.internal.util.Position, context: Context, mode : Mode): (List[Tree], List[Symbol]) = { if (givenArgs.length < params.length) { val (missing, positional) = missingParams(givenArgs, params, nameOfNamedArg) if (missing.forall(_.hasDefault)) { val defaultArgs = missing flatMap { p => - val defGetter = defaultGetter(p, context) - // TODO #3649 can create spurious errors when companion object is gone (because it becomes unlinked from scope) - if (defGetter == NoSymbol) None // prevent crash in erroneous trees, #3649 - else { - var default1: Tree = qual match { - case Some(q) => gen.mkAttributedSelect(q.duplicate, defGetter) - case None => gen.mkAttributedRef(defGetter) + val annDefault = + if (mode.in(Mode.ANNOTmode) && p.owner.isConstructor && p.enclClass.isNonBottomSubClass(AnnotationClass) && !p.enclClass.isNonBottomSubClass(ConstantAnnotationClass)) + p.getAnnotation(DefaultArgAttr).flatMap(_.args.headOption).map(dflt => atPos(pos) { + // The `arg.tpe` is tagged with the `@defaultArg` annotation, see AnnotationInfo.argIsDefault + val arg = dflt.duplicate.setType(dflt.tpe.withAnnotation(AnnotationInfo(DefaultArgAttr.tpe, Nil, Nil))) + if (positional) arg + else NamedArg(Ident(p.name), arg) + }) + else None + annDefault orElse { + val defGetter = defaultGetter(p, context) + // TODO #3649 can create spurious errors when companion object is gone (because it becomes unlinked from scope) + if (defGetter == NoSymbol) None // prevent crash in erroneous trees, #3649 + else { + var default1: Tree = qual match { + case Some(q) => gen.mkAttributedSelect(q.duplicate, defGetter) + case None => gen.mkAttributedRef(defGetter) + } + default1 = if (targs.isEmpty) default1 + else TypeApply(default1, targs.map(_.duplicate)) + val default2 = previousArgss.foldLeft(default1)((tree, args) => + Apply(tree, args.map(_.duplicate))) + Some(atPos(pos) { + if (positional) default2 + else NamedArg(Ident(p.name), default2) + }) } - default1 = if (targs.isEmpty) default1 - else TypeApply(default1, targs.map(_.duplicate)) - val default2 = previousArgss.foldLeft(default1)((tree, args) => - Apply(tree, args.map(_.duplicate))) - Some(atPos(pos) { - if (positional) default2 - else NamedArg(Ident(p.name), default2) - }) } } (givenArgs ::: defaultArgs, Nil) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala index ff65fd4a5bd3..45cf52bce8ee 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -163,17 +163,20 @@ trait PatternTypers { val baseClass = exprTyped.tpe.typeSymbol match { case ArrayClass => ArrayClass case NothingClass => NothingClass + case NullClass => NullClass case _ => SeqClass } val starType = baseClass match { case ArrayClass if isPrimitiveValueType(pt) || !isFullyDefined(pt) => arrayType(pt) case ArrayClass => boundedArrayType(pt) + case NullClass => seqType(NothingTpe) case _ => seqType(pt) } val exprAdapted = adapt(exprTyped, mode, starType) - exprAdapted.tpe baseType baseClass match { + exprAdapted.tpe.baseType(baseClass) match { case TypeRef(_, _, elemtp :: Nil) => treeCopy.Typed(tree, exprAdapted, tpt setType elemtp) setType elemtp case _ if baseClass eq NothingClass => exprAdapted + case _ if baseClass eq NullClass => treeCopy.Typed(tree, exprAdapted, tpt.setType(NothingTpe)).setType(NothingTpe) case _ => setError(tree) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 22bfdc69eb60..253779e3e5af 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,10 +13,11 @@ package scala.tools.nsc package typechecker +import scala.annotation._ import scala.collection.mutable import scala.collection.mutable.ListBuffer import scala.reflect.internal.util.CodeAction -import scala.tools.nsc.Reporting.WarningCategory +import scala.tools.nsc.Reporting.WarningCategory, WarningCategory.{LintOverload} import scala.tools.nsc.settings.ScalaVersion import scala.tools.nsc.settings.NoScalaVersion import symtab.Flags._ @@ -79,7 +80,7 @@ abstract class RefChecks extends Transform { false } - class RefCheckTransformer(unit: CompilationUnit) extends AstTransformer { + class RefCheckTransformer(@unused unit: CompilationUnit) extends AstTransformer { private final val indent = " " var localTyper: analyzer.Typer = typer @@ -97,11 +98,17 @@ abstract class RefChecks extends Transform { private val checkedCombinations = mutable.Map[List[Symbol], (Symbol, Type)]() private def notYetCheckedOrAdd(rt: RefinedType, currentBase: Symbol) = { val seen = checkedCombinations.get(rt.parents.map(_.typeSymbol)).exists { - case (prevBase, prevTp) => currentBase.isSubClass(prevBase) && rt =:= prevTp.asSeenFrom(currentBase.thisType, prevBase) + case (prevBase, prevTp) => + val isSub = (currentBase, prevBase) match { + case (cRef: RefinementClassSymbol, pRef: RefinementClassSymbol) => + cRef.info.parents.map(_.typeSymbol) == pRef.info.parents.map(_.typeSymbol) + case _ => + currentBase.isSubClass(prevBase) + } + val sameTp = rt =:= prevTp.asSeenFrom(currentBase.thisType, prevBase) + isSub && sameTp } - if (!seen) checkedCombinations.addOne((rt.parents.map(_.typeSymbol), (currentBase, rt))) - !seen } @@ -120,10 +127,6 @@ abstract class RefChecks extends Transform { defaultMethodNames.toList.distinct foreach { name => val methods = clazz.info.findMember(name, 0L, requiredFlags = METHOD, stableOnly = false).alternatives - def hasDefaultParam(tpe: Type): Boolean = tpe match { - case MethodType(params, restpe) => (params exists (_.hasDefault)) || hasDefaultParam(restpe) - case _ => false - } val haveDefaults = methods.filter(sym => mexists(sym.info.paramss)(_.hasDefault) && !nme.isProtectedAccessorName(sym.name)) if (haveDefaults.lengthCompare(1) > 0) { @@ -143,11 +146,9 @@ abstract class RefChecks extends Transform { } // Check for doomed attempt to overload applyDynamic - if (clazz isSubClass DynamicClass) { - for ((_, m1 :: m2 :: _) <- (clazz.info member nme.applyDynamic).alternatives groupBy (_.typeParams.length)) { + if (clazz.isSubClass(DynamicClass)) + for ((_, m1 :: _ :: _) <- clazz.info.member(nme.applyDynamic).alternatives.groupBy(_.typeParams.length)) reporter.error(m1.pos, "implementation restriction: applyDynamic cannot be overloaded except by methods with different numbers of type parameters, e.g. applyDynamic[T1](method: String)(arg: T1) and applyDynamic[T1, T2](method: String)(arg1: T1, arg2: T2)") - } - } // This has become noisy with implicit classes. if (settings.isDeveloper && settings.warnPolyImplicitOverload) { @@ -159,6 +160,73 @@ abstract class RefChecks extends Transform { }) } } + private def checkDubiousOverloads(clazz: Symbol): Unit = if (settings.warnDubiousOverload) { + // nullary members or methods with leading implicit params + def ofInterest(tp: Type): Boolean = tp match { + case mt: MethodType => mt.isImplicit + case PolyType(_, rt) => ofInterest(rt) + case _ => true // includes NullaryMethodType + } + // takes no value parameters + def isNullary(tp: Type): Boolean = tp match { + case _: MethodType => false + case PolyType(_, rt) => isNullary(rt) + case _ => true // includes NullaryMethodType + } + def warnDubious(sym: Symbol, alts: List[Symbol]): Unit = { + val usage = if (sym.isMethod && !sym.isGetter) "Calls to parameterless" else "Usages of" + val simpl = "a single implicit parameter list" + val suffix = alts.filter(_ != sym).map(_.defString) match { + case impl :: Nil => s"$impl, which has $simpl." + case impls => + sm"""|overloads which have $simpl: + | ${impls.mkString("\n ")}""" + } + val warnAt = + if (sym.owner == clazz) sym.pos + else + alts.find(_.owner == clazz) match { + case Some(conflict) => conflict.pos + case _ => clazz.pos + } + refchecksWarning(warnAt, s"$usage $sym will be easy to mistake for calls to $suffix", LintOverload) + } + val byName = + clazz.info.members + .reverseIterator + .filter(m => ofInterest(m.info)) + .toList + .groupBy(_.name.dropLocal) + def isCompetitive(syms: List[Symbol], sawNlly: Boolean, sawNonNlly: Boolean): Boolean = + sawNlly && sawNonNlly || (syms match { + case sym :: syms => + if (!sawNlly && isNullary(sym.info)) isCompetitive(syms, sawNlly = true, sawNonNlly) + else if (!sawNonNlly && !isNullary(sym.info)) isCompetitive(syms, sawNlly, sawNonNlly = true) + else isCompetitive(syms, sawNlly, sawNonNlly) + case _ => false + }) + for ((_, syms) <- byName if syms.lengthCompare(1) > 0 && isCompetitive(syms, sawNlly=false, sawNonNlly=false)) { + val (nullaries, alts) = syms.partition(sym => isNullary(sym.info)) + //assert(!alts.isEmpty) + nullaries match { + case nullary :: Nil => warnDubious(nullary, syms) + case nullaries => + //assert(!nullaries.isEmpty) + val dealiased = + nullaries.find(_.isPrivateLocal) match { + case Some(local) => + nullaries.find(sym => sym.isAccessor && sym.accessed == local) match { + case Some(accessor) => nullaries.filter(_ != local) // drop local if it has an accessor + case _ => nullaries + } + case _ => nullaries + } + // there are multiple exactly for a private local and an inherited member + for (nullary <- dealiased) + warnDubious(nullary, nullary :: alts) + } + } + } // Override checking ------------------------------------------------------------ @@ -902,7 +970,7 @@ abstract class RefChecks extends Transform { } } if (warnCloneable && baseClass.eq(JavaCloneableClass)) - reporter.warning(clazz.pos, s"$clazz should not extend Cloneable.") + refchecksWarning(clazz.pos, s"$clazz should not extend Cloneable.", WarningCategory.LintCloneable) val remaining = tp.parents.filterNot(seenParents) seenParents ++= remaining remaining.foreach(register) @@ -993,8 +1061,8 @@ abstract class RefChecks extends Transform { def apply(tp: Type) = mapOver(tp).normalize } - def checkImplicitViewOptionApply(pos: Position, fn: Tree, args: List[Tree]): Unit = if (settings.warnOptionImplicit) (fn, args) match { - case (tap@TypeApply(fun, targs), List(view: ApplyImplicitView)) if fun.symbol == currentRun.runDefinitions.Option_apply => + def checkImplicitViewOptionApply(pos: Position, fun: Tree, argss: List[List[Tree]]): Unit = if (settings.warnOptionImplicit) argss match { + case List(List(view: ApplyImplicitView)) if fun.symbol == currentRun.runDefinitions.Option_apply => refchecksWarning(pos, s"Suspicious application of an implicit view (${view.fun}) in the argument to Option.apply.", WarningCategory.LintOptionImplicit) // scala/bug#6567 case _ => } @@ -1009,7 +1077,7 @@ abstract class RefChecks extends Transform { * * NOTE: I'm really not convinced by the logic here. I also think this would work better after erasure. */ - private def checkSensibleEquals(pos: Position, qual: Tree, name: Name, sym: Symbol, other: Tree) = { + private def checkSensibleEquals(pos: Position, qual: Tree, name: Name, sym: Symbol, other: Tree): Unit = { def isReferenceOp = sym == Object_eq || sym == Object_ne def isNew(tree: Tree) = tree match { case Function(_, _) | Apply(Select(New(_), nme.CONSTRUCTOR), _) => true @@ -1025,6 +1093,10 @@ abstract class RefChecks extends Transform { def onTrees[T](f: List[Tree] => T) = f(List(qual, other)) def onSyms[T](f: List[Symbol] => T) = f(List(receiver, actual)) + // many parts of the implementation assume that `actual` and `receiver` are one `ClassSymbol` + // to support intersection types we'd need to work with lists of class symbols + if (onSyms(_.exists(_.isRefinementClass))) return + // @MAT normalize for consistency in error message, otherwise only part is normalized due to use of `typeSymbol` def typesString = s"${normalizeAll(qual.tpe.widen)} and ${normalizeAll(other.tpe.widen)}" @@ -1041,7 +1113,7 @@ abstract class RefChecks extends Transform { // equals. def isUsingWarnableEquals = { val m = receiver.info.member(nme.equals_) - ((m == Object_equals) || (m == Any_equals) || isMethodCaseEquals(m)) + (m == Object_equals) || (m == Any_equals) || isMethodCaseEquals(m) } def isMethodCaseEquals(m: Symbol) = m.isSynthetic && m.owner.isCase def isCaseEquals = isMethodCaseEquals(receiver.info.member(nme.equals_)) @@ -1074,6 +1146,17 @@ abstract class RefChecks extends Transform { && !isCaseEquals ) + def isCollection(s: Symbol) = s.isNonBottomSubClass(IterableClass) + lazy val SeqClass = rootMirror.getClassIfDefined("scala.collection.Seq") + lazy val SetClass = rootMirror.getClassIfDefined("scala.collection.Set") + lazy val MapClass = rootMirror.getClassIfDefined("scala.collection.Map") + def collectionBase(s: Symbol) = { + if (s.isNonBottomSubClass(SeqClass)) SeqClass + else if (s.isNonBottomSubClass(SetClass)) SetClass + else if (s.isNonBottomSubClass(MapClass)) MapClass + else NoSymbol + } + def isEffectivelyFinalDeep(sym: Symbol): Boolean = ( sym.isEffectivelyFinal // If a parent of an intersection is final, the resulting type must effectively be final. @@ -1128,7 +1211,21 @@ abstract class RefChecks extends Transform { if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc" nonSensiblyNeq() } - else if (isWarnable && !isCaseEquals) { + else if (receiver == StringClass) { + if (!haveSubclassRelationship) + nonSensiblyNeq() + } + else if (isCollection(receiver)) { + val rBase = collectionBase(receiver) + val aBase = collectionBase(actual) + if (rBase != NoSymbol) { + if (aBase != NoSymbol && rBase != aBase) + nonSensiblyNeq() + else if (!isCollection(actual) && !haveSubclassRelationship) + nonSensiblyNeq() + } + } + else if (isWarnable && !isCaseEquals) { // case equals is handled below if (isNew(qual)) // new X == y nonSensiblyNew() else if (isNew(other) && (isEffectivelyFinalDeep(receiver) || isReferenceOp)) // object X ; X == new Y @@ -1211,11 +1308,13 @@ abstract class RefChecks extends Transform { } /** Sensibility check examines flavors of equals. */ - def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match { - case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && (!currentOwner.isSynthetic || currentOwner.isAnonymousFunction) => - checkSensibleEquals(pos, qual, name, fn.symbol, args.head) - case Select(qual, name @ nme.equals_) if args.length == 1 && (!currentOwner.isSynthetic || currentOwner.isAnonymousFunction) => - checkSensibleAnyEquals(pos, qual, name, fn.symbol, args.head) + def checkSensible(pos: Position, fn: Tree, argss: List[List[Tree]]) = (fn, argss) match { + case (Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)), List(List(arg))) + if isObjectOrAnyComparisonMethod(fn.symbol) && (!currentOwner.isSynthetic || currentOwner.isAnonymousFunction) => + checkSensibleEquals(pos, qual, name, fn.symbol, arg) + case (Select(qual, name @ nme.equals_), List(List(arg))) + if !currentOwner.isSynthetic || currentOwner.isAnonymousFunction => + checkSensibleAnyEquals(pos, qual, name, fn.symbol, arg) case _ => } @@ -1232,20 +1331,6 @@ abstract class RefChecks extends Transform { // Transformation ------------------------------------------------------------ - /* Convert a reference to a case factory of type `tpe` to a new of the class it produces. */ - def toConstructor(pos: Position, tpe: Type): Tree = { - val rtpe = tpe.finalResultType - assert(rtpe.typeSymbol hasFlag CASE, tpe) - val tree = localTyper.typedOperator { - atPos(pos) { - Select(New(TypeTree(rtpe)), rtpe.typeSymbol.primaryConstructor) - } - } - checkUndesiredProperties(rtpe.typeSymbol, tree.pos) - checkUndesiredProperties(rtpe.typeSymbol.primaryConstructor, tree.pos) - tree - } - override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = { pushLevel() try { @@ -1305,7 +1390,7 @@ abstract class RefChecks extends Transform { clazz == seltpe.typeSymbol && clazz.isCaseClass && (args corresponds clazz.primaryConstructor.tpe.asSeenFrom(seltpe, clazz).paramTypes)(isIrrefutable) - case Typed(pat, tpt) => + case Typed(_, tpt) => seltpe <:< tpt.tpe case Ident(tpnme.WILDCARD) => true @@ -1577,8 +1662,8 @@ abstract class RefChecks extends Transform { def groupRepeatableAnnotations(sym: Symbol, anns: List[AnnotationInfo]): List[AnnotationInfo] = if (!sym.isJavaDefined) anns else anns match { - case single :: Nil => anns - case multiple => + case single @ _ :: Nil => single + case multiple => sym.getAnnotation(AnnotationRepeatableAttr) match { case Some(repeatable) => repeatable.assocs.collectFirst { @@ -1599,7 +1684,7 @@ abstract class RefChecks extends Transform { } } - def checkIsElidable(sym: Symbol): Unit = if (sym ne null) sym.elisionLevel.foreach { level => + def checkIsElidable(sym: Symbol): Unit = if (sym ne null) sym.elisionLevel.foreach { _ => if (!sym.isMethod || sym.isAccessor || sym.isLazy || sym.isDeferred) { val rest = if (sym.isDeferred) " The annotation affects only the annotated method, not overriding methods in subclasses." else "" reporter.error(sym.pos, s"${sym.name}: Only concrete methods can be marked @elidable.$rest") @@ -1653,98 +1738,118 @@ abstract class RefChecks extends Transform { } } - private def isSimpleCaseApply(tree: Tree): Boolean = { - val sym = tree.symbol - def isClassTypeAccessible(tree: Tree): Boolean = tree match { - case TypeApply(fun, targs) => - isClassTypeAccessible(fun) - case Select(module, apply) => - // scala/bug#4859 `CaseClass1().InnerCaseClass2()` must not be rewritten to `new InnerCaseClass2()`; - // {expr; Outer}.Inner() must not be rewritten to `new Outer.Inner()`. - treeInfo.isQualifierSafeToElide(module) && + private def isSimpleCaseApply(fun: Tree): Boolean = { + val sym = fun.symbol + def isClassTypeAccessible = { + val Select(module, _) = fun: @unchecked + // scala/bug#4859 `CaseClass1().InnerCaseClass2()` must not be rewritten to `new InnerCaseClass2()`; + // {expr; Outer}.Inner() must not be rewritten to `new Outer.Inner()`. + treeInfo.isQualifierSafeToElide(module) && // scala/bug#5626 Classes in refinement types cannot be constructed with `new`. !module.exists { case t @ Select(_, _) => t.symbol != null && t.symbol.isStructuralRefinementMember case _ => false } - case x => throw new MatchError(x) + } sym.name == nme.apply && - !sym.hasStableFlag && // ??? - sym.isCase && - isClassTypeAccessible(tree) && - !tree.tpe.finalResultType.typeSymbol.primaryConstructor.isLessAccessibleThan(tree.symbol) + sym.isCase && // only synthetic case apply methods + isClassTypeAccessible && + !sym.tpe.finalResultType.typeSymbol.primaryConstructor.isLessAccessibleThan(sym) } - private def transformCaseApply(tree: Tree) = { - def loop(t: Tree): Unit = t match { - case Ident(_) => - checkUndesiredProperties(t.symbol, t.pos) - case Select(qual, _) => - checkUndesiredProperties(t.symbol, t.pos) - loop(qual) - case _ => - } - - tree foreach { - case i@Ident(_) => - enterReference(i.pos, i.symbol) // scala/bug#5390 need to `enterReference` for `a` in `a.B()` - case _ => + private def transformCaseApply(tpe: Type, pos: Position) = { + val rtpe = tpe.finalResultType + assert(rtpe.typeSymbol hasFlag CASE, tpe) + localTyper.typedOperator { + atPos(pos) { + Select(New(TypeTree(rtpe)), rtpe.typeSymbol.primaryConstructor) + } } - loop(tree) - toConstructor(tree.pos, tree.tpe) } - private def transformApply(tree: Apply): Tree = tree match { - case Apply( - Select(qual, nme.withFilter), - List(Function( - List(ValDef(_, pname, tpt, _)), - Match(_, CaseDef(pat1, _, _) :: _)))) - if ((pname startsWith nme.CHECK_IF_REFUTABLE_STRING) && + private def transformApplication(tree: Tree, fun: Tree, @unused targs: List[Tree], argss: List[List[Tree]]): Tree = { + (fun, argss) match { + case ( + Select(qual, nme.withFilter), + List(List(Function( + List(ValDef(_, pname, tpt, _)), + Match(_, CaseDef(pat1, _, _) :: _))))) + if ((pname startsWith nme.CHECK_IF_REFUTABLE_STRING) && isIrrefutable(pat1, tpt.tpe) && (qual.tpe <:< tree.tpe)) => - - transform(qual) - case Apply(fn, args) => - // sensicality should be subsumed by the unreachability/exhaustivity/irrefutability - // analyses in the pattern matcher - if (!inPattern) { - checkImplicitViewOptionApply(tree.pos, fn, args) - checkSensible(tree.pos, fn, args) // TODO: this should move to preEraseApply, as reasoning about runtime semantics makes more sense in the JVM type system - checkNamedBooleanArgs(fn, args) - } - currentApplication = tree - tree + qual + case _ => + currentApplication = tree + // sensicality should be subsumed by the unreachability/exhaustivity/irrefutability + // analyses in the pattern matcher + if (!inPattern) { + checkImplicitViewOptionApply(tree.pos, fun, argss) + checkSensible(tree.pos, fun, argss) // TODO: this should move to preEraseApply, as reasoning about runtime semantics makes more sense in the JVM type system + checkNamedBooleanArgs(fun, argss) + } + if (isSimpleCaseApply(fun)) { + transform(fun) + val callee = new treeInfo.Applied(tree).callee + val fun1 = transformCaseApply(callee.tpe, callee.pos) + def res(t: Tree): Tree = t match { + case Apply(f, args) => treeCopy.Apply(t, res(f), args) + case _ => fun1 + } + res(tree) + } else + tree + } } /** Check that boolean literals are passed as named args. - * The rule is enforced when the type of the parameter is `Boolean`. - * The rule is relaxed when the method has exactly one boolean parameter + * The rule is enforced when the type of the parameter is `Boolean`, + * and there is more than one parameter with an unnamed argument. + * The stricter lint warns for any unnamed argument, + * except that the rule is relaxed when the method has exactly one boolean parameter * and it is the first parameter, such as `assert(false, msg)`. */ - private def checkNamedBooleanArgs(fn: Tree, args: List[Tree]): Unit = { + private def checkNamedBooleanArgs(fn: Tree, argss: List[List[Tree]]): Unit = { val sym = fn.symbol - def applyDepth: Int = { - def loop(t: Tree, d: Int): Int = - t match { - case Apply(f, _) => loop(f, d+1) - case _ => d + if (settings.warnUnnamedBoolean.value && !sym.isJavaDefined) { + for ((params, args) <- sym.paramLists.zip(argss) if args.nonEmpty) { + val strictly = settings.warnUnnamedStrict.value // warn about any unnamed boolean arg, modulo "assert" + val numBools = params.count(_.tpe == BooleanTpe) + def onlyLeadingBool = numBools == 1 && params.head.tpe == BooleanTpe + val checkable = if (strictly) numBools > 0 && !onlyLeadingBool else numBools >= 2 + if (checkable) { + def isUnnamedArg(t: Tree) = t.hasAttachment[UnnamedArg.type] + def isNameableBoolean(param: Symbol) = param.tpe.typeSymbol == BooleanClass && !param.deprecatedParamName.contains(nme.NO_NAME) + val unnamed = args.lazyZip(params).filter { + case (arg @ Literal(Constant(_: Boolean)), param) => isNameableBoolean(param) && isUnnamedArg(arg) + case _ => false + } + def numSuspicious = unnamed.length + { + analyzer.NamedApplyBlock.namedApplyInfo(currentApplication) match { + case Some(analyzer.NamedApplyInfo(_, _, _, _, original)) => + val treeInfo.Applied(_, _, argss) = original + argss match { + case h :: _ => + val allParams = sym.paramLists.flatten + h.count { + case treeInfo.Applied(getter, _, _) if getter.symbol != null && getter.symbol.isDefaultGetter => + val (_, i) = nme.splitDefaultGetterName(getter.symbol.name) + i > 0 && isNameableBoolean(allParams(i-1)) + case _ => false + } + case _ => 0 + } + case _ => args.count(arg => arg.symbol != null && arg.symbol.isDefaultGetter) + } + } + val warn = !unnamed.isEmpty && (strictly || numSuspicious >= 2) + if (warn) + unnamed.foreach { + case (arg, param) => + val msg = s"Boolean literals should be passed using named argument syntax for parameter ${param.name}." + val action = runReporting.codeAction("name boolean literal", arg.pos.focusStart, s"${param.name} = ", msg) + runReporting.warning(arg.pos, msg, WarningCategory.WFlagUnnamedBooleanLiteral, sym, action) + case _ => + } } - loop(fn, 0) - } - def isAssertParadigm(params: List[Symbol]): Boolean = !sym.isConstructor && !sym.isCaseApplyOrUnapply && { - params match { - case h :: t => h.tpe == BooleanTpe && !t.exists(_.tpe == BooleanTpe) - case _ => false } } - if (settings.lintNamedBooleans && !sym.isJavaDefined && !args.isEmpty) { - val params = sym.paramLists(applyDepth) - if (!isAssertParadigm(params)) - foreach2(args, params)((arg, param) => arg match { - case Literal(Constant(_: Boolean)) - if arg.hasAttachment[UnnamedArg.type] && param.tpe.typeSymbol == BooleanClass && !param.deprecatedParamName.contains(nme.NO_NAME) => - runReporting.warning(arg.pos, s"Boolean literals should be passed using named argument syntax for parameter ${param.name}.", WarningCategory.LintNamedBooleans, sym) - case _ => - }) - } } private def transformSelect(tree: Select): Tree = { @@ -1764,25 +1869,20 @@ abstract class RefChecks extends Transform { // term should have been eliminated by super accessors assert(!(qual.symbol.isTrait && sym.isTerm && mix == tpnme.EMPTY), (qual.symbol, sym, mix)) - // Rewrite eligible calls to monomorphic case companion apply methods to the equivalent constructor call. - // - // Note: for generic case classes the rewrite needs to be handled at the enclosing `TypeApply` to transform - // `TypeApply(Select(C, apply), targs)` to `Select(New(C[targs]), )`. In case such a `TypeApply` - // was deemed ineligible for transformation (e.g. the case constructor was private), the refchecks transform - // will recurse to this point with `Select(C, apply)`, which will have a type `[T](...)C[T]`. - // - // We don't need to perform the check on the Select node, and `!isHigherKinded will guard against this - // redundant (and previously buggy, scala/bug#9546) consideration. - if (!tree.tpe.isHigherKinded && isSimpleCaseApply(tree)) { - transformCaseApply(tree) - } else { - qual match { - case Super(_, mix) => checkSuper(mix) - case _ => - } - tree + qual match { + case Super(_, mix) => checkSuper(mix) + case _ => + } + + if (sym.name == nme.apply && sym.isCase && qual.symbol == sym.owner.module) { + val clazz = sym.tpe.finalResultType.typeSymbol + checkUndesiredProperties(clazz, tree.pos) + checkUndesiredProperties(clazz.primaryConstructor, tree.pos) } + + tree } + private def transformIf(tree: If): Tree = { val If(cond, thenpart, elsepart) = tree def unitIfEmpty(t: Tree): Tree = @@ -1809,7 +1909,9 @@ abstract class RefChecks extends Transform { ) if (!isOk) { val msg = s"side-effecting nullary methods are discouraged: suggest defining as `def ${sym.name.decode}()` instead" - val namePos = sym.pos.focus.withEnd(sym.pos.point + sym.decodedName.length) + val namePos = + if (sym.pos.isRange) sym.pos + else sym.pos.toRange.withEnd(sym.pos.point + sym.decodedName.length) val action = if (namePos.source.sourceAt(namePos) == sym.decodedName) runReporting.codeAction("add empty parameter list", namePos.focusEnd, "()", msg) @@ -1880,6 +1982,13 @@ abstract class RefChecks extends Transform { && !treeInfo.hasExplicitUnit(t) // suppressed by explicit expr: Unit && !isJavaApplication(t) // Java methods are inherently side-effecting ) + def checkDiscardValue(t: Tree): Boolean = + t.attachments.containsElement(DiscardedValue) && { + t.setAttachments(t.attachments.removeElement(DiscardedValue)) + val msg = s"discarded non-Unit value of type ${t.tpe}" + refchecksWarning(t.pos, msg, WarningCategory.WFlagValueDiscard) + true + } // begin checkInterestingResultInStatement settings.warnNonUnitStatement.value && checkInterestingShapes(t) && { val where = t match { @@ -1891,10 +2000,10 @@ abstract class RefChecks extends Transform { } case _ => t } - def msg = s"unused value of type ${where.tpe} (add `: Unit` to discard silently)" + def msg = s"unused value of type ${where.tpe}" refchecksWarning(where.pos, msg, WarningCategory.OtherPureStatement) true - } + } || checkDiscardValue(t) } // end checkInterestingResultInStatement override def transform(tree: Tree): Tree = { @@ -1920,7 +2029,7 @@ abstract class RefChecks extends Transform { if (!sym.isConstructor && !sym.isEffectivelyFinalOrNotOverridden && !sym.owner.isSealed && !sym.isSynthetic) checkAccessibilityOfReferencedTypes(tree) } - tree match { + val r = tree match { case dd: DefDef if sym.hasAnnotation(NativeAttr) => if (sym.owner.isTrait) { reporter.error(tree.pos, "A trait cannot define a native method.") @@ -1933,27 +2042,32 @@ abstract class RefChecks extends Transform { tree case _ => tree } + r.transform(this) - case Template(parents, self, body) => + case Template(_, _, body) => localTyper = localTyper.atOwner(tree, currentOwner) for (stat <- body) if (!checkInterestingResultInStatement(stat) && treeInfo.isPureExprForWarningPurposes(stat)) { val msg = "a pure expression does nothing in statement position" - val clause = if (body.lengthCompare(1) > 0) "; multiline expressions may require enclosing parentheses" else "" + val clause = if (body.lengthCompare(2) > 0) "; multiline expressions may require enclosing parentheses" else "" refchecksWarning(stat.pos, s"$msg$clause", WarningCategory.OtherPureStatement) } validateBaseTypes(currentOwner) checkOverloadedRestrictions(currentOwner, currentOwner) // scala/bug#7870 default getters for constructors live in the companion module checkOverloadedRestrictions(currentOwner, currentOwner.companionModule) + checkDubiousOverloads(currentOwner) val bridges = addVarargBridges(currentOwner) // TODO: do this during uncurry? checkAllOverrides(currentOwner) checkAnyValSubclass(currentOwner) if (currentOwner.isDerivedValueClass) currentOwner.primaryConstructor makeNotPrivate NoSymbol // scala/bug#6601, must be done *after* pickler! - if (bridges.nonEmpty) deriveTemplate(tree)(_ ::: bridges) else tree + val res = if (bridges.nonEmpty) deriveTemplate(tree)(_ ::: bridges) else tree + res.transform(this) + + case _: TypeTreeWithDeferredRefCheck => + abort("adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc") - case _: TypeTreeWithDeferredRefCheck => abort("adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc") case tpt@TypeTree() => if(tpt.original != null) { tpt.original foreach { @@ -1964,28 +2078,24 @@ abstract class RefChecks extends Transform { } } - tree.setType(RefCheckTypeMap.check(tree.tpe, tree, inPattern)) - - case TypeApply(fn, args) => - checkBounds(tree, NoPrefix, NoSymbol, fn.tpe.typeParams, args map (_.tpe)) - if (isSimpleCaseApply(tree)) - transformCaseApply(tree) - else - tree + tree.setType(RefCheckTypeMap.check(tree.tpe, tree, inPattern)).transform(this) - case x @ Apply(_, _) => - transformApply(x) + case treeInfo.Application(fun, targs, argss) => + if (targs.nonEmpty) + checkBounds(tree, NoPrefix, NoSymbol, fun.tpe.typeParams, targs map (_.tpe)) + val res = transformApplication(tree, fun, targs, argss) + res.transform(this) case x @ If(_, _, _) => - transformIf(x) + transformIf(x).transform(this) case New(tpt) => enterReference(tree.pos, tpt.tpe.typeSymbol) - tree + tree.transform(this) case treeInfo.WildcardStarArg(_) => checkRepeatedParamArg(tree) - tree + tree.transform(this) case Ident(name) => checkUndesiredProperties(sym, tree.pos) @@ -1993,57 +2103,66 @@ abstract class RefChecks extends Transform { assert(sym != NoSymbol, "transformCaseApply: name = " + name.debugString + " tree = " + tree + " / " + tree.getClass) //debug enterReference(tree.pos, sym) } - tree + tree.transform(this) case x @ Select(_, _) => - transformSelect(x) + transformSelect(x).transform(this) case Literal(Constant(tpe: Type)) => RefCheckTypeMap.check(tpe, tree) - tree + tree.transform(this) case UnApply(fun, args) => transform(fun) // just make sure we enterReference for unapply symbols, note that super.transform(tree) would not transform(fun) // transformTrees(args) // TODO: is this necessary? could there be forward references in the args?? // probably not, until we allow parameterised extractors - tree + tree.transform(this) - case blk @ Block(stats, expr) => + case Block(stats, expr) => // diagnostic info - val (count, result0, adapted) = + val (count, result0) = expr match { - case Block(expr :: Nil, Literal(Constant(()))) => (1, expr, true) - case Literal(Constant(())) => (0, EmptyTree, false) - case _ => (1, EmptyTree, false) + case Block(expr :: Nil, Literal(Constant(()))) => (1, expr) + case Literal(Constant(())) => (0, EmptyTree) + case _ => (1, EmptyTree) } val isMultiline = stats.lengthCompare(1 - count) > 0 - def checkPure(t: Tree, supple: Boolean): Unit = + def checkPure(t: Tree): Unit = if (!treeInfo.hasExplicitUnit(t) && treeInfo.isPureExprForWarningPurposes(t)) { - val msg = "a pure expression does nothing in statement position" - val parens = if (isMultiline) "multiline expressions might require enclosing parentheses" else "" - val discard = if (adapted) "; a value can be silently discarded when Unit is expected" else "" + val msg = + if (t.attachments.containsElement(DiscardedExpr)) { + t.setAttachments(t.attachments.removeElement(DiscardedExpr)) + "discarded pure expression does nothing" + } + else "a pure expression does nothing in statement position" val text = - if (supple) s"$parens$discard" - else if (!parens.isEmpty) s"$msg; $parens" else msg + if (!isMultiline) msg + else s"$msg; multiline expressions might require enclosing parentheses" refchecksWarning(t.pos, text, WarningCategory.OtherPureStatement) } // check block for unintended "expression in statement position" - stats.foreach { t => if (!checkInterestingResultInStatement(t)) checkPure(t, supple = false) } - if (result0.nonEmpty) checkPure(result0, supple = true) - - def checkImplicitlyAdaptedBlockResult(t: Tree): Unit = - expr match { - case treeInfo.Applied(f, _, _) if f.symbol != null && f.symbol.isImplicit => - f.symbol.paramLists match { - case (p :: Nil) :: _ if p.isByNameParam => refchecksWarning(t.pos, s"Block result was adapted via implicit conversion (${f.symbol}) taking a by-name parameter", WarningCategory.LintBynameImplicit) - case _ => - } - case _ => - } + stats.foreach { t => if (!checkInterestingResultInStatement(t)) checkPure(t) } + if (result0.nonEmpty) result0.updateAttachment(DiscardedExpr) // see checkPure on recursion into result + + def checkImplicitlyAdaptedBlockResult(t: Tree): Unit = { + def loop(t: Tree): Unit = + t match { + case Apply(coercion, _) if t.isInstanceOf[ApplyImplicitView] => + coercion.symbol.paramLists match { + case (p :: Nil) :: _ if p.isByNameParam => refchecksWarning(t.pos, s"Block result expression was adapted via implicit conversion (${coercion.symbol}) taking a by-name parameter; only the result was passed, not the entire block.", WarningCategory.LintBynameImplicit) + case _ => + } + case TypeApply(fun, _) => loop(fun) + case Apply(fun, _) => loop(fun) + case _ => + } + loop(t) + } if (isMultiline && settings.warnByNameImplicit) checkImplicitlyAdaptedBlockResult(expr) - tree + tree.transform(this) + case Match(selector, cases) => // only warn if it could be put in backticks in a pattern def isWarnable(sym: Symbol): Boolean = @@ -2117,33 +2236,32 @@ abstract class RefChecks extends Transform { } // check the patterns for unfriendly shadowing, patvars bearing PatShadowAttachment if (settings.warnPatternShadow) for (cdef <- cases) checkPattern(cdef.pat) - tree - case _ => tree - } + tree.transform(this) - // skip refchecks in patterns.... - val result1 = result match { + // skip refchecks in patterns.... case CaseDef(pat, guard, body) => val pat1 = savingInPattern { inPattern = true transform(pat) } treeCopy.CaseDef(tree, pat1, transform(guard), transform(body)) + case _ => - result.transform(this) + tree.transform(this) } - result1 match { + + result match { case ClassDef(_, _, _, _) | TypeDef(_, _, _, _) | ModuleDef(_, _, _) => - if (result1.symbol.isLocalToBlock || result1.symbol.isTopLevel) - varianceValidator.traverse(result1) + if (result.symbol.isLocalToBlock || result.symbol.isTopLevel) + varianceValidator.traverse(result) case tt @ TypeTree() if tt.original != null => varianceValidator.validateVarianceOfPolyTypesIn(tt.tpe) case _ => } - checkUnexpandedMacro(result1) + checkUnexpandedMacro(result) - result1 + result } catch { case ex: TypeError => if (settings.isDebug) ex.printStackTrace() diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 7a920f21971f..69d78ad1fb5d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 0652bcd3d76a..398ecfaf5639 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -19,8 +19,7 @@ package scala package tools.nsc package typechecker -import scala.collection.{immutable, mutable} -import mutable.ListBuffer +import scala.collection.{immutable, mutable}, mutable.ListBuffer import scala.tools.nsc.Reporting.WarningCategory import symtab.Flags._ @@ -192,8 +191,8 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT } def mixIsTrait = sup.tpe match { - case SuperType(thisTpe, superTpe) => superTpe.typeSymbol.isTrait - case x => throw new MatchError(x) + case SuperType(_, superTpe) => superTpe.typeSymbol.isTrait + case x => throw new MatchError(x) } val needAccessor = name.isTermName && { @@ -376,7 +375,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case DefDef(_, _, _, _, _, _) if tree.symbol.isMethodWithExtension => deriveDefDef(tree)(rhs => withInvalidOwner(transform(rhs))) - case TypeApply(sel @ Select(qual, name), args) => + case TypeApply(sel @ Select(_, _), args) => mayNeedProtectedAccessor(sel, args, goToSuper = true) case Assign(lhs @ Select(qual, name), rhs) => diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 910802567d70..5eec1b3852ef 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,6 +15,7 @@ package typechecker import scala.collection.mutable import scala.collection.mutable.ListBuffer +import scala.runtime.Statics import scala.tools.nsc.Reporting.WarningCategory import symtab.Flags._ @@ -90,11 +91,13 @@ trait SyntheticMethods extends ast.TreeDSL { else templ } + def Lit(c: Any) = LIT.typed(c) + def accessors = clazz.caseFieldAccessors val arity = accessors.size def forwardToRuntime(method: Symbol): Tree = - forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_")))(mkThis :: _) + forwardMethod(method, getMember(ScalaRunTimeModule, method.name.prepend("_")))(mkThis :: _) def callStaticsMethodName(name: TermName)(args: Tree*): Tree = { val method = RuntimeStaticsModule.info.member(name) @@ -241,7 +244,7 @@ trait SyntheticMethods extends ast.TreeDSL { /* The hashcode method for value classes * def hashCode(): Int = this.underlying.hashCode */ - def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntTpe) { m => + def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntTpe) { _ => Select(mkThisSelect(clazz.derivedValueClassUnbox), nme.hashCode_) } @@ -285,8 +288,8 @@ trait SyntheticMethods extends ast.TreeDSL { def hashcodeImplementation(sym: Symbol): Tree = { sym.tpe.finalResultType.typeSymbol match { - case UnitClass | NullClass => Literal(Constant(0)) - case BooleanClass => If(Ident(sym), Literal(Constant(1231)), Literal(Constant(1237))) + case UnitClass | NullClass => Lit(0) + case BooleanClass => If(Ident(sym), Lit(1231), Lit(1237)) case IntClass => Ident(sym) case ShortClass | ByteClass | CharClass => Select(Ident(sym), nme.toInt) case LongClass => callStaticsMethodName(nme.longHash)(Ident(sym)) @@ -299,29 +302,51 @@ trait SyntheticMethods extends ast.TreeDSL { def specializedHashcode = { createMethod(nme.hashCode_, Nil, IntTpe) { m => val accumulator = m.newVariable(newTermName("acc"), m.pos, SYNTHETIC) setInfo IntTpe - val valdef = ValDef(accumulator, Literal(Constant(0xcafebabe))) + val valdef = ValDef(accumulator, Lit(0xcafebabe)) val mixPrefix = Assign( Ident(accumulator), - callStaticsMethod("mix")(Ident(accumulator), - Apply(gen.mkAttributedSelect(gen.mkAttributedSelect(mkThis, Product_productPrefix), Object_hashCode), Nil))) + callStaticsMethod("mix")(Ident(accumulator), Lit(clazz.name.decode.hashCode))) val mixes = accessors map (acc => Assign( Ident(accumulator), callStaticsMethod("mix")(Ident(accumulator), hashcodeImplementation(acc)) ) ) - val finish = callStaticsMethod("finalizeHash")(Ident(accumulator), Literal(Constant(arity))) + val finish = callStaticsMethod("finalizeHash")(Ident(accumulator), Lit(arity)) Block(valdef :: mixPrefix :: mixes, finish) } } - def chooseHashcode = { + + def productHashCode: Tree = { + // case `hashCode` used to call `ScalaRunTime._hashCode`, but that implementation mixes in the result + // of `productPrefix`, which causes scala/bug#13033. + // Because case hashCode has two possible implementations (`specializedHashcode` and `productHashCode`) we + // need to fix it twice. + // 1. `specializedHashcode` above was changed to mix in the case class name statically. + // 2. we can achieve the same thing here by calling `MurmurHash3Module.productHash` with a `seed` that mixes + // in the case class name already. This is backwards and forwards compatible: + // - the new generated code works with old and new standard libraries + // - the `MurmurHash3Module.productHash` implementation returns the same result as before when called by + // previously compiled case classes + // Alternatively, we could decide to always generate the full implementation (like `specializedHashcode`) + // at the cost of bytecode size. + createMethod(nme.hashCode_, Nil, IntTpe) { _ => + if (arity == 0) Lit(clazz.name.decode.hashCode) + else gen.mkMethodCall(MurmurHash3Module, TermName("productHash"), List( + mkThis, + Lit(Statics.mix(0xcafebabe, clazz.name.decode.hashCode)), + Lit(true) + )) + } + } + + def chooseHashcode = if (accessors exists (x => isPrimitiveValueType(x.tpe.finalResultType))) specializedHashcode else - forwardToRuntime(Object_hashCode) - } + productHashCode def valueClassMethods = List( Any_hashCode -> (() => hashCodeDerivedValueClassMethod), @@ -425,7 +450,7 @@ trait SyntheticMethods extends ast.TreeDSL { } def nameSuffixedByParamIndex = original.name.append(s"${nme.CASE_ACCESSOR}$$${i}").toTermName val newName = if (i < 0) freshAccessorName else nameSuffixedByParamIndex - val newAcc = deriveMethod(ddef.symbol, name => newName) { newAcc => + val newAcc = deriveMethod(ddef.symbol, _ => newName) { newAcc => newAcc.makePublic newAcc resetFlag (ACCESSOR | PARAMACCESSOR | OVERRIDE) ddef.rhs.duplicate diff --git a/src/compiler/scala/tools/nsc/typechecker/Tags.scala b/src/compiler/scala/tools/nsc/typechecker/Tags.scala index 5a3bfa198a11..f9ee5c2cc8ec 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Tags.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Tags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 23db339135ee..1a98d6c0c530 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -324,7 +324,7 @@ abstract class TreeCheckers extends Analyzer { if (args exists (_ == EmptyTree)) errorFn(tree.pos, "Apply arguments to " + fn + " contains an empty tree: " + args) - case Select(qual, name) => + case Select(_, _) => checkSym(tree) case This(_) => checkSym(tree) @@ -406,7 +406,7 @@ abstract class TreeCheckers extends Analyzer { val fmt = "%-" + width + "s" val lines = pairs map { case (s: Symbol, msg) => fmt.format(msg) + " in " + ownersString(s) - case (x, msg) => fmt.format(msg) + case (_, msg) => fmt.format(msg) } lines.mkString("Out of scope symbol reference {\n", "\n", "\n}") } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 55f79ae29bd4..66ff438bb599 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,14 +13,13 @@ package scala.tools.nsc package typechecker -import scala.collection.mutable -import scala.collection.mutable.ListBuffer +import scala.annotation._ +import scala.collection.mutable, mutable.ListBuffer +import scala.tools.nsc.Reporting.WarningCategory import scala.util.chaining._ import scala.util.control.Exception.ultimately import symtab.Flags._ import PartialFunction.{cond, condOpt} -import scala.annotation.{nowarn, tailrec} -import scala.tools.nsc.Reporting.WarningCategory /** An interface to enable higher configurability of diagnostic messages * regarding type errors. This is barely a beginning as error messages are @@ -49,9 +48,9 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { /** For errors which are artifacts of the implementation: such messages * indicate that the restriction may be lifted in the future. */ - def restrictionWarning(pos: Position, unit: CompilationUnit, msg: String, category: WarningCategory, site: Symbol): Unit = + def restrictionWarning(pos: Position, @unused unit: CompilationUnit, msg: String, category: WarningCategory, site: Symbol): Unit = runReporting.warning(pos, "Implementation restriction: " + msg, category, site) - def restrictionError(pos: Position, unit: CompilationUnit, msg: String): Unit = + def restrictionError(pos: Position, @unused unit: CompilationUnit, msg: String): Unit = reporter.error(pos, "Implementation restriction: " + msg) /** A map of Positions to addendums - if an error involves a position in @@ -87,12 +86,6 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { prefix + name.decode } - // Bind of pattern var was `x @ _` - private def atBounded(t: Tree) = t.hasAttachment[NoWarnAttachment.type] - - // ValDef was a PatVarDef `val P(x) = ???` - private def wasPatVarDef(t: Tree) = t.hasAttachment[PatVarDefAttachment.type] - /** Does the positioned line assigned to t1 precede that of t2? */ def posPrecedes(p1: Position, p2: Position) = p1.isDefined && p2.isDefined && p1.line < p2.line @@ -117,11 +110,9 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { else "" private def methodTypeErrorString(tp: Type) = tp match { - case mt @ MethodType(params, resultType) => - def forString = params map (_.defString) - - forString.mkString("(", ",", ")") + resultType - case x => x.toString + case MethodType(params, resultType) => + params.map(_.defString).mkString("(", ",", s")$resultType") + case tp => tp.toString } /** @@ -500,19 +491,39 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { val ignoreNames: Set[TermName] = Set( "readResolve", "readObject", "writeObject", "writeReplace" ).map(TermName(_)) + + // Bind of pattern var was `x @ _`; also used for wildcard, e.g. `_ <- e` + private def nowarn(tree: Bind): Boolean = tree.hasAttachment[NoWarnAttachment.type] + private def nowarn(tree: ValDef): Boolean = tree.hasAttachment[NoWarnAttachment.type] + + // ValDef was a PatVarDef `val P(x) = ???` + private def wasPatVarDef(tree: ValDef): Boolean = tree.hasAttachment[PatVarDefAttachment.type] + private def wasPatVarDef(sym: Symbol): Boolean = sym.hasAttachment[PatVarDefAttachment.type] } class UnusedPrivates extends Traverser { - import UnusedPrivates.ignoreNames - def isEffectivelyPrivate(sym: Symbol): Boolean = false - val defnTrees = ListBuffer[MemberDef]() - val targets = mutable.Set[Symbol]() - val setVars = mutable.Set[Symbol]() - val treeTypes = mutable.Set[Type]() - val params = mutable.Set[Symbol]() - val patvars = mutable.Set[Symbol]() - - def varsWithoutSetters = defnTrees.iterator.map(_.symbol).filter(t => t.isVar && !isExisting(t.setter)) + import UnusedPrivates.{ignoreNames, nowarn, wasPatVarDef} + def isEffectivelyPrivate(sym: Symbol): Boolean = false // see REPL + val defnTrees = ListBuffer.empty[MemberDef] + val targets = mutable.Set.empty[Symbol] + val setVars = mutable.Set.empty[Symbol] + val treeTypes = mutable.Set.empty[Type] + val params = mutable.Set.empty[Symbol] + val patvars = ListBuffer.empty[Tree /*Bind|ValDef*/] + val ignore = mutable.Set.empty[Symbol] // nowarn + + val annots = mutable.Set.empty[AnnotationInfo] // avoid revisiting annotations of symbols and types + + def recordReference(sym: Symbol): Unit = targets.addOne(sym) + + def checkNowarn(tree: Tree): Unit = + tree match { + case tree: Bind => + if (nowarn(tree)) ignore += tree.symbol + case tree: ValDef => + if (nowarn(tree)) ignore += tree.symbol + case _ => + } def qualifiesTerm(sym: Symbol) = ( (sym.isModule || sym.isMethod || sym.isPrivateLocal || sym.isLocalToBlock || isEffectivelyPrivate(sym)) @@ -528,43 +539,104 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { && (sym.isTerm && qualifiesTerm(sym) || sym.isType && qualifiesType(sym)) ) def isExisting(sym: Symbol) = sym != null && sym.exists + def addPatVar(t: Tree) = { + checkNowarn(t) + patvars += t + } // so trivial that it never consumes params def isTrivial(rhs: Tree): Boolean = rhs.symbol == Predef_??? || rhs.tpe == null || rhs.tpe =:= NothingTpe || (rhs match { case Literal(_) => true - case _ => isConstantType(rhs.tpe) || isSingleType(rhs.tpe) + case _ => isConstantType(rhs.tpe) || isSingleType(rhs.tpe) || rhs.isInstanceOf[This] }) override def traverse(t: Tree): Unit = { - val sym = t.symbol t match { - case m: MemberDef if qualifies(sym) && !t.isErrorTyped => + case t: ValDef if wasPatVarDef(t) => // include field excluded by qualifies test + if (settings.warnUnusedPatVars) + addPatVar(t) + case t: MemberDef if qualifies(t.symbol) && !t.isErrorTyped => + val sym = t.symbol t match { - case ValDef(mods@_, name@_, tpt@_, rhs@_) if wasPatVarDef(t) => - if (settings.warnUnusedPatVars && !atBounded(t)) patvars += sym - case DefDef(mods@_, name@_, tparams@_, vparamss, tpt@_, rhs@_) if !sym.isAbstract && !sym.isDeprecated && !sym.isMacro => + case DefDef(_, _, _, vparamss, _, rhs) if !sym.isAbstract && !sym.isDeprecated && !sym.isMacro => + if (isSuppressed(sym)) return // ignore params and rhs of @unused def if (sym.isPrimaryConstructor) for (cpa <- sym.owner.constrParamAccessors if cpa.isPrivateLocal) params += cpa else if (sym.isSynthetic && sym.isImplicit) return else if (!sym.isConstructor && !sym.isVar && !isTrivial(rhs)) - for (vs <- vparamss) params ++= vs.map(_.symbol) - defnTrees += m - case TypeDef(mods@_, name@_, tparams@_, rhs@_) => + for (vs <- vparamss; v <- vs) if (!isSingleType(v.symbol.tpe)) params += v.symbol + if (sym.isGetter && wasPatVarDef(sym.accessed)) { + if (settings.warnUnusedPatVars) + addPatVar(t) + } + else defnTrees += t + case TypeDef(_, _, _, _) => if (!sym.isAbstract && !sym.isDeprecated) - defnTrees += m + defnTrees += t case _ => - defnTrees += m + defnTrees += t } - case CaseDef(pat, guard@_, rhs@_) if settings.warnUnusedPatVars && !t.isErrorTyped => + case Match(selector, cases) => + // don't warn when a patvar redefines the selector ident: x match { case x: X => } + // or extracts a single patvar named identically to the selector + def allowVariableBindings(n: Name, pat: Tree): Unit = + pat match { + case Bind(`n`, _) => pat.updateAttachment(NoWarnAttachment) + case Apply(_, _) | UnApply(_, _) => // really interested in args + pat.filter(_.isInstanceOf[Bind]) match { // never nme.WILDCARD + case (bind @ Bind(`n`, _)) :: Nil => bind.updateAttachment(NoWarnAttachment) // one only + case _ => + } + case _ => + } + def allow(n: Name): Unit = cases.foreach(k => allowVariableBindings(n, k.pat)) + def loop(selector: Tree): Unit = + selector match { + case Ident(n) => allow(n) + case Typed(expr, _) => loop(expr) + case Select(This(_), n) => allow(n) + case _ => + } + loop(selector) + case CaseDef(pat, _, _) if settings.warnUnusedPatVars && !t.isErrorTyped => + def allowVariableBindings(app: Apply, args: List[Tree]): Unit = + treeInfo.dissectApplied(app).core.tpe match { + case MethodType(ps, _) => + foreach2(ps, args) { (p, x) => + x match { + case Bind(n, _) if p.name == n => x.updateAttachment(NoWarnAttachment) + case _ => + } + } + case _ => + } pat.foreach { - case b @ Bind(n, _) if !atBounded(b) && n != nme.DEFAULT_CASE => patvars += b.symbol + case app @ Apply(_, args) => allowVariableBindings(app, args) + case b @ Bind(n, _) if n != nme.DEFAULT_CASE => addPatVar(b) case _ => } - case _: RefTree if isExisting(sym) => targets += sym + case t: RefTree => + val sym = t.symbol + if (isExisting(sym) && !currentOwner.hasTransOwner(sym) && !t.hasAttachment[ForAttachment.type]) + recordReference(sym) case Assign(lhs, _) if isExisting(lhs.symbol) => setVars += lhs.symbol - case Function(ps, _) if settings.warnUnusedParams && !t.isErrorTyped => params ++= - ps.filterNot(p => atBounded(p) || p.symbol.isSynthetic).map(_.symbol) + case Function(ps, _) if !t.isErrorTyped => + for (p <- ps) { + if (wasPatVarDef(p)) { + if (settings.warnUnusedPatVars) + addPatVar(p) + } + else { + if (settings.warnUnusedParams && !p.symbol.isSynthetic) { + checkNowarn(p) + params += p.symbol + } + } + } + case treeInfo.Applied(fun, _, _) + if t.hasAttachment[ForAttachment.type] && fun.symbol != null && isTupleSymbol(fun.symbol.owner.companion) => + return // ignore tupling of assignments case Literal(_) => t.attachments.get[OriginalTreeAttachment].foreach(ota => traverse(ota.original)) case tt: TypeTree => @@ -576,8 +648,13 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { case _ => } - if (t.tpe ne null) { - for (tp <- t.tpe) if (!treeTypes(tp)) { + def descend(annot: AnnotationInfo): Unit = + if (!annots(annot)) { + annots.addOne(annot) + traverse(annot.original) + } + if ((t.tpe ne null) && t.tpe != NoType) { + for (tp <- t.tpe if tp != NoType) if (!treeTypes(tp)) { // Include references to private/local aliases (which might otherwise refer to an enclosing class) val isAlias = { val td = tp.typeSymbolDirect @@ -596,13 +673,20 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { log(s"${if (isAlias) "alias " else ""}$tp referenced from $currentOwner") treeTypes += tp } + for (annot <- tp.annotations) + descend(annot) } // e.g. val a = new Foo ; new a.Bar ; don't let a be reported as unused. t.tpe.prefix foreach { - case SingleType(_, sym) => targets += sym + case SingleType(_, sym) => recordReference(sym) case _ => () } } + + if (t.symbol != null && t.symbol.exists) + for (annot <- t.symbol.annotations) + descend(annot) + super.traverse(t) } def isSuppressed(sym: Symbol): Boolean = sym.hasAnnotation(UnusedClass) @@ -611,7 +695,7 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { && !isSuppressed(m) && !m.isTypeParameterOrSkolem // would be nice to improve this && (m.isPrivate || m.isLocalToBlock || isEffectivelyPrivate(m)) - && !(treeTypes.exists(_.exists(_.typeSymbolDirect == m))) + && !treeTypes.exists(_.exists(_.typeSymbolDirect == m)) ) def isSyntheticWarnable(sym: Symbol) = { def privateSyntheticDefault: Boolean = @@ -629,7 +713,6 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { && !targets(m) && !(m.name == nme.WILDCARD) // e.g. val _ = foo && (m.isValueParameter || !ignoreNames(m.name.toTermName)) // serialization/repl methods - && !isConstantType(m.info.resultType) // subject to constant inlining && !treeTypes.exists(_ contains m) // e.g. val a = new Foo ; new a.Bar ) def isUnusedParam(m: Symbol): Boolean = ( @@ -641,47 +724,104 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { targets.exists(s => s.isParameter && s.name == m.name && s.owner.isConstructor && s.owner.owner == m.owner) // exclude ctor params )) + && !(m.info.typeSymbol == UnitClass) + && !(m.owner.isClass && m.owner.thisType.baseClasses.contains(AnnotationClass)) + && !ignore(m) ) - def sympos(s: Symbol): Int = - if (s.pos.isDefined) s.pos.point else if (s.isTerm) s.asTerm.referenced.pos.point else -1 - def treepos(t: Tree): Int = - if (t.pos.isDefined) t.pos.point else sympos(t.symbol) - - def unusedTypes = defnTrees.toList.filter(t => isUnusedType(t.symbol)).sortBy(treepos) + def unusedTypes = defnTrees.iterator.filter(t => isUnusedType(t.symbol)) def unusedTerms = { - val all = defnTrees.toList.filter(v => isUnusedTerm(v.symbol)) - // is this a getter-setter pair? and why is this a difficult question for traits? def sameReference(g: Symbol, s: Symbol) = if (g.accessed.exists && s.accessed.exists) g.accessed == s.accessed - else g.owner == s.owner && g.setterName == s.name //sympos(g) == sympos(s) + else g.owner == s.owner && g.setterName == s.name + val all = defnTrees.iterator.filter(v => isUnusedTerm(v.symbol)).toSet // filter out setters if already warning for getter. val clean = all.filterNot(v => v.symbol.isSetter && all.exists(g => g.symbol.isGetter && sameReference(g.symbol, v.symbol))) - clean.sortBy(treepos) + clean.iterator } // local vars which are never set, except those already returned in unused - def unsetVars = varsWithoutSetters.filter(v => !isSuppressed(v) && !setVars(v) && !isUnusedTerm(v)).toList.sortBy(sympos) - def unusedParams = params.iterator.filter(isUnusedParam).toList.sortBy(sympos) + def unsetVars = { + def varsWithoutSetters = defnTrees.iterator.map(_.symbol).filter(t => t.isVar && !isExisting(t.setter)) + varsWithoutSetters.filter(v => !isSuppressed(v) && !setVars(v) && !isUnusedTerm(v)) + } + def unusedParams = params.iterator.filter(isUnusedParam) def inDefinedAt(p: Symbol) = p.owner.isMethod && p.owner.name == nme.isDefinedAt && p.owner.owner.isAnonymousFunction - def unusedPatVars = patvars.toList.filter(p => isUnusedTerm(p) && !inDefinedAt(p)).sortBy(sympos) + def unusedPatVars = { + // in elaboration of for comprehensions, patterns are duplicated; + // track a patvar by its symbol position; "original" has a range pos + val all = patvars.filterInPlace(_.symbol.pos.isDefined) + val byPos = all.groupBy(_.symbol.pos.start) + def isNotPrivateOrLocal(s: Symbol) = s.hasAccessorFlag && s.hasNoFlags(PRIVATE | LOCAL) + def isUnusedPatVar(t: Tree): Boolean = + byPos(t.symbol.pos.start).forall(p => + !targets(p.symbol) + && !isNotPrivateOrLocal(p.symbol) + && !ignore(p.symbol) + ) + // the "original" tree has an opaque range; + // for multi-var patdef, tree pos is transparent but sym pos is opaque; + // use the field as the primary definition, and also remove it from targets + // if it has a getter (in which case it has the "local" name to disambiguate). + // Note that for uni-var patdef `val Some(x)`, tree pos is opaque. + def isPrimaryPatVarDefinition(p: Tree): Boolean = + p.symbol.pos.isOpaqueRange && { + val primary = p.pos.isOpaqueRange || p.symbol.isPrivateLocal + if (primary && nme.isLocalName(p.symbol.name)) + targets.subtractOne(p.symbol) // field is trivially accessed by its getter if it has one + primary + } + all.iterator.filter(p => + isPrimaryPatVarDefinition(p) + && isUnusedTerm(p.symbol) + && isUnusedPatVar(p) + && !nme.isFreshTermName(p.symbol.name) + && !inDefinedAt(p.symbol) + ) + } } class checkUnused(typer: Typer) { + private def isMacroAnnotationExpansion(tree: Tree): Boolean = tree.hasSymbolField && isExpanded(tree.symbol) + + private def isMacroExpansion(tree: Tree): Boolean = hasMacroExpansionAttachment(tree) || isMacroAnnotationExpansion(tree) + object skipMacroCall extends UnusedPrivates { override def qualifiesTerm(sym: Symbol): Boolean = super.qualifiesTerm(sym) && !sym.isMacro } object skipMacroExpansion extends UnusedPrivates { - override def traverse(t: Tree): Unit = - if (!hasMacroExpansionAttachment(t) && !(t.hasSymbolField && isExpanded(t.symbol))) - super.traverse(t) + override def traverse(tree: Tree): Unit = if (!isMacroExpansion(tree)) super.traverse(tree) } object checkMacroExpandee extends UnusedPrivates { - override def traverse(t: Tree): Unit = - if (!(t.hasSymbolField && isExpanded(t.symbol))) - super.traverse(if (hasMacroExpansionAttachment(t)) macroExpandee(t) else t) + override def traverse(tree: Tree): Unit = + if (!isMacroAnnotationExpansion(tree)) + super.traverse(if (hasMacroExpansionAttachment(tree)) macroExpandee(tree) else tree) + } + // collect definitions and refs from expandee (and normal trees) but only refs from expanded trees + object checkMacroExpandeeAndExpandedRefs extends UnusedPrivates { + object refCollector extends Traverser { + override def traverse(tree: Tree): Unit = { + tree match { + case _: RefTree if isExisting(tree.symbol) => recordReference(tree.symbol) + case _ => + } + if (tree.tpe != null) tree.tpe.prefix.foreach { + case SingleType(_, sym) => recordReference(sym) + case _ => + } + super.traverse(tree) + } + } + override def traverse(tree: Tree): Unit = + if (hasMacroExpansionAttachment(tree)) { + super.traverse(macroExpandee(tree)) + refCollector.traverse(tree) + } + else if (isMacroAnnotationExpansion(tree)) + refCollector.traverse(tree) + else super.traverse(tree) } private def warningsEnabled: Boolean = { @@ -692,7 +832,17 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { // `checkUnused` is invoked after type checking. we have to avoid using `typer.context.warning`, which uses // `context.owner` as the `site` of the warning, but that's the root symbol at this point. - def emitUnusedWarning(pos: Position, msg: String, category: WarningCategory, site: Symbol): Unit = runReporting.warning(pos, msg, category, site) + private val unusedWarnings = ListBuffer.empty[(Position, String, WarningCategory, Symbol)] + private def emitUnusedWarning(pos: Position, msg: String, category: WarningCategory, site: Symbol): Unit = + unusedWarnings.addOne((pos, msg, category, site)) + private def reportAll(): Unit = { + implicit val ordering = new Ordering[Position] { + def posOf(p: Position): Int = if (p.isDefined) p.point else -1 + override def compare(x: Position, y: Position): Int = posOf(x) - posOf(y) + } + unusedWarnings.toArray.sortBy(_._1).foreach { case (pos, msg, category, site) => runReporting.warning(pos, msg, category, site) } + unusedWarnings.clear() + } def run(unusedPrivates: UnusedPrivates)(body: Tree): Unit = { unusedPrivates.traverse(body) @@ -743,10 +893,9 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { emitUnusedWarning(v.pos, s"local var ${v.nameString} in ${v.owner} ${varAdvice(v)}", WarningCategory.UnusedPrivates, v) } } - if (settings.warnUnusedPatVars) { + if (settings.warnUnusedPatVars) for (v <- unusedPrivates.unusedPatVars) - emitUnusedWarning(v.pos, s"pattern var ${v.name} in ${v.owner} is never used: use a wildcard `_` or suppress this warning with `${v.name}@_`", WarningCategory.UnusedPatVars, v) - } + emitUnusedWarning(v.symbol.pos, s"pattern var ${v.symbol.name.dropLocal} in ${v.symbol.owner} is never used", WarningCategory.UnusedPatVars, v.symbol) if (settings.warnUnusedParams) { // don't warn unused args of overriding methods (or methods matching in self-type) def isImplementation(m: Symbol): Boolean = m.isMethod && { @@ -762,6 +911,7 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { opc.iterator.exists(_.low == m) } } + def isEmptyMarker(p: Symbol): Boolean = p.info.members.reverseIterator.forall(isUniversalMember(_)) // nonTrivialMembers(p).isEmpty def isConvention(p: Symbol): Boolean = ( p.name.decoded == "args" && p.owner.isMethod && p.owner.name.decoded == "main" || @@ -769,8 +919,10 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { ) def warningIsOnFor(s: Symbol) = if (!s.isImplicit) settings.warnUnusedExplicits - else if (!s.isSynthetic) settings.warnUnusedImplicits - else settings.warnUnusedSynthetics + else { + if (!s.isSynthetic) settings.warnUnusedImplicits + else settings.warnUnusedSynthetics + } && !isEmptyMarker(s) def warnable(s: Symbol) = ( warningIsOnFor(s) && !isImplementation(s.owner) @@ -790,11 +942,13 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { val body = unit.body // TODO the message should distinguish whether the non-usage is before or after macro expansion. settings.warnMacros.value match { + case "default"=> run(checkMacroExpandeeAndExpandedRefs)(body) case "none" => run(skipMacroExpansion)(body) case "before" => run(checkMacroExpandee)(body) case "after" => run(skipMacroCall)(body) case "both" => run(checkMacroExpandee)(body) ; run(skipMacroCall)(body) } + reportAll() } } @@ -805,19 +959,29 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { def permanentlyHiddenWarning(pos: Position, hidden: Name, defn: Symbol) = context.warning(pos, "imported `%s` is permanently hidden by definition of %s".format(hidden, defn.fullLocationString), WarningCategory.OtherShadowing) - private def symWasOverloaded(sym: Symbol) = sym.owner.isClass && sym.owner.info.member(sym.name).isOverloaded - private def cyclicAdjective(sym: Symbol) = if (symWasOverloaded(sym)) "overloaded" else "recursive" - /** Returns Some(msg) if the given tree is untyped apparently due * to a cyclic reference, and None otherwise. */ - def cyclicReferenceMessage(sym: Symbol, tree: Tree) = condOpt(tree) { - case ValDef(_, _, TypeTree(), _) => s"recursive $sym needs type" - case DefDef(_, _, _, _, TypeTree(), _) => s"${cyclicAdjective(sym)} $sym needs result type" - case Import(expr, selectors) => - """encountered unrecoverable cycle resolving import. - |Note: this is often due in part to a class depending on a definition nested within its companion. - |If applicable, you may wish to try moving some members into another object.""".stripMargin + def cyclicReferenceMessage(sym: Symbol, tree: Tree, trace: Array[Symbol], pos: Position) = { + def symWasOverloaded(sym: Symbol) = sym.owner.isClass && sym.owner.info.member(sym.name).isOverloaded + def cyclicAdjective(sym: Symbol) = if (symWasOverloaded(sym)) "overloaded" else "recursive" + + val badsym = if (!sym.isSynthetic) sym else { + val organics = trace.filter(!_.isSynthetic) + if (organics.length == 0) sym + else if (organics.length == 1) organics(0) + else organics.find(_.pos.focus == pos.focus).getOrElse(organics(0)) + } + def help = if (!badsym.isSynthetic || settings.cyclic.value) "" else + s"; $badsym is synthetic; use -Vcyclic to find which definition needs an explicit type" + condOpt(tree) { + case ValDef(_, _, TypeTree(), _) => s"recursive $badsym needs type$help" + case DefDef(_, _, _, _, TypeTree(), _) => s"${cyclicAdjective(badsym)} $badsym needs result type$help" + case Import(_, _) => + sm"""encountered unrecoverable cycle resolving import. + |Note: this is often due in part to a class depending on a definition nested within its companion. + |If applicable, you may wish to try moving some members into another object.""" + } } // warn about class/method/type-members' type parameters that shadow types already in scope @@ -852,23 +1016,79 @@ trait TypeDiagnostics extends splain.SplainDiagnostics { if (settings.isDebug) ex.printStackTrace() ex match { - case CyclicReference(sym, info: TypeCompleter) => - if (context0.owner.isTermMacro) { - // see comments to TypeSigError for an explanation of this special case - throw ex - } else { - val pos = info.tree match { - case Import(expr, _) => expr.pos - case _ => ex.pos - } - context0.error(pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage()) - - if (sym == ObjectClass) - throw new FatalError("cannot redefine root "+sym) + // see comments to TypeSigError for an explanation of this special case + case _: CyclicReference if context0.owner.isTermMacro => throw ex + case CyclicReference(sym, info: TypeCompleter, trace) => + val pos = info.tree match { + case Import(expr, _) => expr.pos + case _ => ex.pos } + context0.error(pos, cyclicReferenceMessage(sym, info.tree, trace, pos).getOrElse(ex.getMessage)) + + if (sym == ObjectClass) throw new FatalError(s"cannot redefine root $sym") case _ => context0.error(ex.pos, ex.msg) } } + + /** Check that type `tree` does not refer to private + * components unless itself is wrapped in something private + * (`owner` tells where the type occurs). + */ + def checkNoEscapingPrivates(typer: Typer, owner: Symbol, tree: Tree): Tree = + if (owner.isJavaDefined) tree + else new CheckNoEscaping(typer, owner, tree).check(tree) + + /** Check that type of given tree does not contain local or private components. */ + private final class CheckNoEscaping(typer: Typer, owner: Symbol, tree: Tree) extends TypeMap { + private var hiddenSymbols: List[Symbol] = Nil + + def check(tree: Tree): Tree = { + import typer.TyperErrorGen._ + val tp1 = apply(tree.tpe) + if (hiddenSymbols.isEmpty) tree setType tp1 + else if (hiddenSymbols exists (_.isErroneous)) HiddenSymbolWithError(tree) + else if (tp1.typeSymbol.isAnonymousClass) + check(tree setType tp1.typeSymbol.classBound) + else if (owner == NoSymbol) + tree setType packSymbols(hiddenSymbols.reverse, tp1) + else if (!isPastTyper) { // privates + val badSymbol = hiddenSymbols.head + SymbolEscapesScopeError(tree, badSymbol) + } else tree + } + + def addHidden(sym: Symbol) = + if (!(hiddenSymbols contains sym)) hiddenSymbols = sym :: hiddenSymbols + + override def apply(t: Type): Type = { + def checkNoEscape(sym: Symbol): Unit = { + if (sym.isPrivate && !sym.hasFlag(SYNTHETIC_PRIVATE)) { + var o = owner + while (o != NoSymbol && o != sym.owner && o != sym.owner.linkedClassOfClass && + !o.isLocalToBlock && !o.isPrivate && + !o.privateWithin.hasTransOwner(sym.owner)) + o = o.owner + if (o == sym.owner || o == sym.owner.linkedClassOfClass) + addHidden(sym) + } + } + mapOver( + t match { + case TypeRef(_, sym, args) => + checkNoEscape(sym) + if (!hiddenSymbols.isEmpty && hiddenSymbols.head == sym && + sym.isAliasType && sameLength(sym.typeParams, args)) { + hiddenSymbols = hiddenSymbols.tail + t.dealias + } else t + case SingleType(_, sym) => + checkNoEscape(sym) + t + case _ => + t + }) + } + } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeStrings.scala b/src/compiler/scala/tools/nsc/typechecker/TypeStrings.scala index 48b7b7c45bae..12f84de815b3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeStrings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1b10d34e1f66..f00f25359682 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,9 +14,8 @@ package scala package tools.nsc package typechecker -import scala.annotation.{tailrec, unused} -import scala.collection.mutable -import mutable.ListBuffer +import scala.annotation._ +import scala.collection.mutable, mutable.{ArrayBuffer, ListBuffer} import scala.reflect.internal.{Chars, TypesStats} import scala.reflect.internal.util.{CodeAction, FreshNameCreator, ListOfNil, Statistics} import scala.tools.nsc.Reporting.{MessageFilter, Suppression, WConf, WarningCategory}, WarningCategory.Scala3Migration @@ -41,7 +40,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper final val shortenImports = false // All typechecked RHS of ValDefs for right-associative operator desugaring - private val rightAssocValDefs = new mutable.AnyRefMap[Symbol, Tree] + private val rightAssocValDefs = new mutable.HashMap[Symbol, Tree] // Symbols of ValDefs for right-associative operator desugaring which are passed by name and have been inlined private val inlinedRightAssocValDefs = new mutable.HashSet[Symbol] @@ -50,7 +49,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // chain, this is used to determine which are true aliases, ones where the field can be elided from this class. // And yes, if you were asking, this is yet another binary fragility, as we bake knowledge of the super class into // this class. - private val superConstructorCalls: mutable.AnyRefMap[Symbol, collection.Map[Symbol, Symbol]] = perRunCaches.newAnyRefMap() + private val superConstructorCalls: mutable.HashMap[Symbol, collection.Map[Symbol, Symbol]] = perRunCaches.newMap() // allows override of the behavior of the resetTyper method w.r.t comments def resetDocComments() = clearDocComments() @@ -80,10 +79,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper @inline final def filter(p: T => Boolean): SilentResult[T] = this match { case SilentResultValue(value) if !p(value) => SilentTypeError(TypeErrorWrapper(new TypeError(NoPosition, "!p"))) case _ => this - } + } @inline final def orElse[T1 >: T](f: Seq[AbsTypeError] => T1): T1 = this match { case SilentResultValue(value) => value - case s : SilentTypeError => f(s.reportableErrors) + case s: SilentTypeError => f(s.reportableErrors) } } class SilentTypeError private(val errors: List[AbsTypeError], val warnings: List[ContextWarning]) extends SilentResult[Nothing] { @@ -113,89 +112,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // A transient flag to mark members of anonymous classes // that are turned private by typedBlock - private final val SYNTHETIC_PRIVATE = TRANS_FLAG + private[typechecker] final val SYNTHETIC_PRIVATE = TRANS_FLAG private final val InterpolatorCodeRegex = """\$\{\s*(.*?)\s*\}""".r - private final val InterpolatorIdentRegex = """\$[$\w]+""".r // note that \w doesn't include $ - - /** Check that type of given tree does not contain local or private - * components. - */ - object checkNoEscaping extends TypeMap { - private var owner: Symbol = _ - private var scope: Scope = _ - private var hiddenSymbols: List[Symbol] = _ - - /** Check that type `tree` does not refer to private - * components unless itself is wrapped in something private - * (`owner` tells where the type occurs). - */ - def privates[T <: Tree](typer: Typer, owner: Symbol, tree: T): T = - if (owner.isJavaDefined) tree else check(typer, owner, EmptyScope, WildcardType, tree) - - @tailrec - private def check[T <: Tree](typer: Typer, owner: Symbol, scope: Scope, pt: Type, tree: T): T = { - this.owner = owner - this.scope = scope - hiddenSymbols = Nil - import typer.TyperErrorGen._ - val tp1 = apply(tree.tpe) - if (hiddenSymbols.isEmpty) tree setType tp1 - else if (hiddenSymbols exists (_.isErroneous)) HiddenSymbolWithError(tree) - else if (isFullyDefined(pt)) tree setType pt - else if (tp1.typeSymbol.isAnonymousClass) - check(typer, owner, scope, pt, tree setType tp1.typeSymbol.classBound) - else if (owner == NoSymbol) - tree setType packSymbols(hiddenSymbols.reverse, tp1) - else if (!isPastTyper) { // privates - val badSymbol = hiddenSymbols.head - SymbolEscapesScopeError(tree, badSymbol) - } else tree - } - - def addHidden(sym: Symbol) = - if (!(hiddenSymbols contains sym)) hiddenSymbols = sym :: hiddenSymbols - - override def apply(t: Type): Type = { - def checkNoEscape(sym: Symbol): Unit = { - if (sym.isPrivate && !sym.hasFlag(SYNTHETIC_PRIVATE)) { - var o = owner - while (o != NoSymbol && o != sym.owner && o != sym.owner.linkedClassOfClass && - !o.isLocalToBlock && !o.isPrivate && - !o.privateWithin.hasTransOwner(sym.owner)) - o = o.owner - if (o == sym.owner || o == sym.owner.linkedClassOfClass) - addHidden(sym) - } else if (sym.owner.isTerm && !sym.isTypeParameterOrSkolem) { - var e = scope.lookupEntry(sym.name) - var found = false - while (!found && (e ne null) && e.owner == scope) { - if (e.sym == sym) { - found = true - addHidden(sym) - } else { - e = scope.lookupNextEntry(e) - } - } - } - } - mapOver( - t match { - case TypeRef(_, sym, args) => - checkNoEscape(sym) - if (!hiddenSymbols.isEmpty && hiddenSymbols.head == sym && - sym.isAliasType && sameLength(sym.typeParams, args)) { - hiddenSymbols = hiddenSymbols.tail - t.dealias - } else t - case SingleType(_, sym) => - checkNoEscape(sym) - t - case _ => - t - }) - } - } + private final val InterpolatorIdentRegex = """\$[\w]+""".r // note that \w doesn't include $ private final val typerFreshNameCreators = perRunCaches.newAnyRefMap[Symbol, FreshNameCreator]() def freshNameCreatorFor(context: Context) = typerFreshNameCreators.getOrElseUpdate(context.outermostContextAtCurrentPos.enclClassOrMethod.owner, new FreshNameCreator) @@ -215,9 +135,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } /** Overridden to false in scaladoc and/or interactive. */ + def isInteractive = false def canAdaptConstantTypeToLiteral = true def canTranslateEmptyListToNil = true - def missingSelectErrorTree(tree: Tree, qual: Tree, name: Name): Tree = tree + def missingSelectErrorTree(tree: Tree, @unused qual: Tree, @unused name: Name): Tree = tree // used to exempt synthetic accessors (i.e. those that are synthesized by the compiler to access a field) // from skolemization because there's a weird bug that causes spurious type mismatches @@ -228,8 +149,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // requiring both the ACCESSOR and the SYNTHETIC bits to trigger the exemption private def isSyntheticAccessor(sym: Symbol) = sym.isAccessor && (!sym.isLazy || isPastTyper) - private val fixableFunctionMembers = List(nme.tupled, TermName("curried")) - // when type checking during erasure, generate erased types in spots that aren't transformed by erasure // (it erases in TypeTrees, but not in, e.g., the type a Function node) def phasedAppliedType(sym: Symbol, args: List[Type]) = { @@ -408,7 +327,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper private val maxRecursion = 42 // For each abstract type symbol (type member, type parameter), keep track of seen types represented by that symbol - private lazy val map = collection.mutable.HashMap[Symbol, mutable.ListBuffer[Type]]() + private lazy val map = mutable.HashMap[Symbol, ListBuffer[Type]]() def lockSymbol[T](sym: Symbol, tp: Type)(body: => T): T = { val stk = map.getOrElseUpdate(sym, ListBuffer.empty) @@ -550,7 +469,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper || mode.inQualMode && !tree.symbol.isConstant || !(tree.tpe <:< pt) && (ptSym.isAbstractType && pt.lowerBound.isStable || ptSym.isRefinementClass) ) - + def isNarrowable(tpe: Type): Boolean = unwrapWrapperTypes(tpe) match { + case TypeRef(_, _, _) | RefinedType(_, _) => true + case tpe => !isConstantType(tpe) && !phase.erasedTypes + } ( isNarrowable(tree.tpe) && mode.typingExprNotLhs && expectsStable @@ -601,15 +523,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper */ protected def stabilize(tree: Tree, pre: Type, mode: Mode, pt: Type): Tree = { - // Side effect time! Don't be an idiot like me and think you - // can move "val sym = tree.symbol" before this line, because - // inferExprAlternative side-effects the tree's symbol. - if (tree.symbol.isOverloaded && !mode.inFunMode) - inferExprAlternative(tree, pt) - - val sym = tree.symbol + val sym = { + // inferExprAlternative side-effects the tree's symbol. + if (tree.symbol.isOverloaded && !mode.inFunMode) + inferExprAlternative(tree, pt) + tree.symbol + } val isStableIdPattern = mode.typingPatternNotConstructor && tree.isTerm - def isModuleTypedExpr = ( treeInfo.admitsTypeSelection(tree) && (isStableContext(tree, mode, pt) || sym.isModuleNotMethod) @@ -626,33 +546,22 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // this so for now it requires the type symbol be public. def isGetClassCall = isGetClass(sym) && pre.typeSymbol.isPublic - def narrowIf(tree: Tree, condition: Boolean) = - if (condition) tree setType singleType(pre, sym) else tree - - def checkStable(tree: Tree): Tree = - if (treeInfo.isStableIdentifierPattern(tree)) tree - else UnstableTreeError(tree) - if (tree.isErrorTyped) tree else if (!sym.isValue && isStableValueRequired) // (2) NotAValueError(tree, sym) else if (isStableIdPattern) // (1) - // A module reference in a pattern has type Foo.type, not "object Foo" - narrowIf(checkStable(tree), sym.isModuleNotMethod) + if (!treeInfo.isStableIdentifierPattern(tree)) UnstableTreeError(tree) + else if (sym.isModuleNotMethod) tree.setType(singleType(pre, sym)) + else tree else if (isModuleTypedExpr) // (3) - narrowIf(tree, condition = true) + tree.setType(singleType(pre, sym)) else if (isGetClassCall) // (4) - tree setType MethodType(Nil, getClassReturnType(pre)) + tree.setType(MethodType(Nil, getClassReturnType(pre))) else tree } - private def isNarrowable(tpe: Type): Boolean = unwrapWrapperTypes(tpe) match { - case TypeRef(_, _, _) | RefinedType(_, _) => true - case _ => !phase.erasedTypes - } - def stabilizeFun(tree: Tree, mode: Mode, pt: Type): Tree = { val sym = tree.symbol val pre = tree match { @@ -962,7 +871,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (arity == 0) expectingFunctionOfArity && warnEtaZero() else - expectingFunctionOfArity || expectingSamOfArity && warnEtaSam() || currentRun.isScala3 + expectingFunctionOfArity || expectingSamOfArity && warnEtaSam() || currentRun.sourceFeatures.etaExpandAlways } def matchNullaryLoosely: Boolean = { @@ -995,10 +904,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val apply = Apply(tree, Nil).setPos(tree.pos).updateAttachment(AutoApplicationAttachment) if (tree.hasAttachment[PostfixAttachment.type]) apply.updateAttachment(InfixAttachment) adapt(typed(apply), mode, pt, original) - } else - if (context.implicitsEnabled) MissingArgsForMethodTpeError(tree, meth) // `context.implicitsEnabled` implies we are not in a pattern - else UnstableTreeError(tree) - } + } + // `context.implicitsEnabled` implies we are not in a pattern + else if (context.implicitsEnabled) MissingArgsForMethodTpeError(tree, meth) + else UnstableTreeError(tree) + } // end adaptMethodTypeToExpr def adaptType(): Tree = { // @M When not typing a type constructor (!context.inTypeConstructorAllowed) @@ -1052,10 +962,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } def adaptConstant(value: Constant): Tree = { val sym = tree.symbol - if (sym != null && sym.isDeprecated) + if (sym != null && !context.unit.isJava && sym.isDeprecated) context.deprecationWarning(tree.pos, sym) tree match { - case Literal(`value`) => tree + case Literal(`value`) /*| Bind(_, _)*/ => tree case _ => // If the original tree is not a literal, make it available to plugins in an attachment treeCopy.Literal(tree, value).updateAttachment(OriginalTreeAttachment(tree)) @@ -1128,7 +1038,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def adaptApplyInsertion(): Tree = doAdaptApplyInsertion(retry = false) def doAdaptApplyInsertion(retry: Boolean): Tree = - if (currentRun.isScala3Cross && !isPastTyper && tree.symbol != null && tree.symbol.isModule && tree.symbol.companion.isCase && isFunctionType(pt)) + if (!isPastTyper && tree.symbol != null && tree.symbol.isModule && tree.symbol.companion.isCase && isFunctionType(pt)) silent(_.typed(atPos(tree.pos)(Select(tree, nme.apply)), mode, if (retry) WildcardType else pt)) match { case SilentResultValue(applicator) => val arity = definitions.functionArityFromType(applicator.tpe) @@ -1170,7 +1080,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper @inline def warnValueDiscard(): Unit = if (!isPastTyper && settings.warnValueDiscard.value && !treeInfo.isThisTypeResult(tree) && !treeInfo.hasExplicitUnit(tree)) - context.warning(tree.pos, s"discarded non-Unit value of type ${tree.tpe}", WarningCategory.WFlagValueDiscard) + tree.updateAttachment(DiscardedValue) @inline def warnNumericWiden(tpSym: Symbol, ptSym: Symbol): Unit = if (!isPastTyper) { val targetIsWide = ptSym == FloatClass || ptSym == DoubleClass val isInharmonic = { @@ -1293,9 +1203,15 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // TODO: we really shouldn't use T* as a first class types (e.g. for repeated case fields), // but we can't allow T* to conform to other types (see isCompatible) because that breaks overload resolution adapt(tree.setType(repeatedToSeq(tree.tpe)), mode, pt, original = EmptyTree) - else if (tree.tpe <:< pt) + else if (tree.tpe <:< pt) { + val sym = tree.symbol + if (sym != null && !isPastTyper && currentRun.isScala3 && isFunctionType(pt) && sym.isModule && sym.isSynthetic && sym.companion.isCase) { + val msg = s"Synthetic case companion used as a function. In Scala 3 (or with -Xsource-features:case-companion-function), case companions no longer extend FunctionN. Use ${sym.name}.apply instead." + val action = runReporting.codeAction("add `.apply`", tree.pos.focusEnd, ".apply", msg) + context.warning(tree.pos, msg, Scala3Migration, action) + } tree - else if (mode.inPatternMode && { inferModulePattern(tree, pt); isPopulated(tree.tpe, approximateAbstracts(pt)) }) + } else if (mode.inPatternMode && { inferModulePattern(tree, pt); isPopulated(tree.tpe, approximateAbstracts(pt)) }) tree else { val constFolded = constfold(tree, pt, context.owner) @@ -1411,11 +1327,34 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case _ => } inferView(qual, qual.tpe, searchTemplate, reportAmbiguous, saveErrors) match { - case EmptyTree => qual - case coercion => + case EmptyTree => qual + case coercion => if (settings.logImplicitConv.value) context.echo(qual.pos, s"applied implicit conversion from ${qual.tpe} to ${searchTemplate} = ${coercion.symbol.defString}") - + if (currentRun.isScala3 && coercion.symbol == currentRun.runDefinitions.Predef_any2stringaddMethod) + if (!currentRun.sourceFeatures.any2StringAdd) + runReporting.warning(qual.pos, s"Converting to String for concatenation is not supported in Scala 3 (or with -Xsource-features:any2stringadd).", Scala3Migration, coercion.symbol) + if (settings.lintUniversalMethods) { + def targetsUniversalMember(target: => Type): Option[Symbol] = searchTemplate match { + case HasMethodMatching(name, argtpes, restpe) => + target.member(name) + .alternatives + .find { m => + def argsOK = m.paramLists match { + case h :: _ => argtpes.corresponds(h.map(_.info))(_ <:< _) + case nil => argtpes.isEmpty + } + isUniversalMember(m) && argsOK + } + case RefinedType(WildcardType :: Nil, decls) => + decls.find(d => d.isMethod && d.info == WildcardType && isUniversalMember(target.member(d.name))) + case _ => + None + } + for (target <- targetsUniversalMember(coercion.symbol.info.finalResultType)) + context.warning(qual.pos, s"conversion ${coercion.symbol.nameString} adds universal member $target to ${qual.tpe.typeSymbol}", + WarningCategory.LintUniversalMethods) + } typedQualifier(atPos(qual.pos)(new ApplyImplicitView(coercion, List(qual)))) } } @@ -1584,7 +1523,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } private def warnMultiargInfix(tree: Tree): Unit = - context.warning(tree.pos, "multiarg infix syntax looks like a tuple and will be deprecated", WarningCategory.LintMultiargInfix) + context.warning(tree.pos, "multiarg infix syntax looks like a tuple", WarningCategory.Other) /** Typechecks a parent type reference. * @@ -1831,7 +1770,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (treeInfo.hasUntypedPreSuperFields(templ.body)) typedPrimaryConstrBody(templ)(EmptyTree) - supertpts mapConserve (tpt => checkNoEscaping.privates(this, context.owner, tpt)) + supertpts mapConserve (tpt => checkNoEscapingPrivates(this, context.owner, tpt)) } catch { case ex: TypeError if !global.propagateCyclicReferences => @@ -2084,7 +2023,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper templ setSymbol clazz.newLocalDummy(templ.pos) val self1 = (templ.self: @unchecked) match { case vd @ ValDef(_, _, tpt, EmptyTree) => - val tpt1 = checkNoEscaping.privates( + val tpt1 = checkNoEscapingPrivates( this, clazz.thisSym, treeCopy.TypeTree(tpt).setOriginal(tpt) setType vd.symbol.tpe @@ -2196,7 +2135,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper sym.annotations.foreach(_.completeInfo()) sym.filterAnnotations(_ != UnmappableAnnotation) - val tpt1 = checkNoEscaping.privates(this, sym, transformedOr(vdef.tpt, typedType(vdef.tpt))) + val tpt1 = checkNoEscapingPrivates(this, sym, transformedOr(vdef.tpt, typedType(vdef.tpt))) checkNonCyclic(vdef, tpt1) // allow trait accessors: it's the only vehicle we have to hang on to annotations that must be passed down to @@ -2229,27 +2168,30 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } else tpt1.tpe transformedOrTyped(vdef.rhs, EXPRmode | BYVALmode, tpt2) } + if (!isPastTyper && sym.hasDefault && sym.owner.isConstructor && sym.enclClass.isNonBottomSubClass(AnnotationClass)) + sym.addAnnotation(AnnotationInfo(DefaultArgAttr.tpe, List(duplicateAndResetPos.transform(rhs1)), Nil)) val vdef1 = treeCopy.ValDef(vdef, typedMods, sym.name, tpt1, checkDead(context, rhs1)) setType NoType if (sym.isSynthetic && sym.name.startsWith(nme.RIGHT_ASSOC_OP_PREFIX)) rightAssocValDefs += ((sym, vdef1.rhs)) - if (vdef.hasAttachment[PatVarDefAttachment.type]) + if (vdef.hasAttachment[PatVarDefAttachment.type]) { sym.updateAttachment(PatVarDefAttachment) - if (sym.isSynthetic && sym.owner.isClass && (tpt1.tpe eq UnitTpe) && vdef.hasAttachment[PatVarDefAttachment.type] && sym.isPrivateThis && vdef.mods.isPrivateLocal && !sym.enclClassChain.exists(_.isInterpreterWrapper)) { - context.warning(vdef.pos, s"Pattern definition introduces Unit-valued member of ${sym.owner.name}; consider wrapping it in `locally { ... }`.", WarningCategory.OtherMatchAnalysis) + if (sym.isSynthetic && sym.owner.isClass && (tpt1.tpe eq UnitTpe)) + if (sym.isPrivateThis && vdef.mods.isPrivateLocal && !sym.enclClassChain.exists(_.isInterpreterWrapper)) + context.warning(vdef.pos, + s"Pattern definition introduces Unit-valued member of ${sym.owner.name}; consider wrapping it in `locally { ... }`.", + WarningCategory.OtherMatchAnalysis) } vdef1 } /** Analyze the super constructor call to record information used later to compute parameter aliases */ - def analyzeSuperConstructor(meth: Symbol, vparamss: List[List[ValDef]], rhs: Tree): Unit = { + def analyzeSuperConstructor(meth: Symbol, vparamss: List[List[ValDef]], rhs: Tree): Unit = if (!rhs.isErrorTyped) { val clazz = meth.owner debuglog(s"computing param aliases for $clazz:${clazz.primaryConstructor.tpe}:$rhs") val pending = ListBuffer[AbsTypeError]() // !!! This method is redundant with other, less buggy ones. def decompose(call: Tree): (Tree, List[Tree]) = call match { - case _ if call.isErrorTyped => // e.g. scala/bug#7636 - (call, Nil) case Apply(fn, args) => // an object cannot be allowed to pass a reference to itself to a superconstructor // because of initialization issues; scala/bug#473, scala/bug#3913, scala/bug#6928. @@ -2284,7 +2226,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!superClazz.isJavaDefined) { val superParamAccessors = superClazz.constrParamAccessors if (sameLength(superParamAccessors, superArgs)) { - val accToSuperAcc = mutable.AnyRefMap[Symbol, Symbol]() + val accToSuperAcc = mutable.HashMap[Symbol, Symbol]() for ((superAcc, superArg@Ident(name)) <- superParamAccessors zip superArgs) { if (mexists(vparamss)(_.symbol == superArg.symbol)) { val ownAcc = clazz.info decl name suchThat (_.isParamAccessor) match { @@ -2436,11 +2378,47 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // we only have to move annotations around for accessors -- see annotSig as used by AccessorTypeCompleter and ValTypeCompleter if (meth.isAccessor) meth.filterAnnotations(_ != UnmappableAnnotation) + if (meth.isPrimaryConstructor && !isPastTyper) { + // add `@superArg` / `@superFwdArg` to subclasses of concrete annotations, e.g., + // `@superArg("value", "cat=deprecation")` for `class nodep extends nowarn("cat=deprecation")` + // this is done by duplicating the untyped super arguments before type checking the super call, because the + // super call can be transformed by named/default arguments. to build the `@superArg` annotations, the super + // call is type checked using `typedAnnotation`, which uses Mode.ANNOTmode. + def superArgs(t: Tree): List[Tree] = t match { + case treeInfo.Application(fn, _, List(args)) => args.map(_.duplicate) + case Block(_ :+ superCall, _) => superArgs(superCall) + case _ => Nil + } + val cls = meth.enclClass + val supCls = cls.superClass + if (!supCls.isAbstract && supCls.isNonBottomSubClass(AnnotationClass)) { + val superAnnotArgs = superArgs(ddef.rhs) + if (superAnnotArgs.nonEmpty && supCls.primaryConstructor.paramss.size == 1) + silent(_.typedAnnotation(New(cls.info.parents.head, superAnnotArgs: _*), None)).map(i => { + if (supCls.isNonBottomSubClass(ConstantAnnotationClass)) { + i.assocs.foreach { + case (p, LiteralAnnotArg(arg)) => + cls.addAnnotation(AnnotationInfo(SuperArgAttr.tpe, List(CODE.LIT.typed(p.toString), CODE.LIT.typed(arg.value)), Nil)) + case _ => + } + } else { + val ps = vparamss1.headOption.getOrElse(Nil).map(_.symbol).toSet + i.symbol.primaryConstructor.paramss.headOption.getOrElse(Nil).zip(i.args).foreach { + case (p, arg) if ps(arg.symbol) => + cls.addAnnotation(AnnotationInfo(SuperFwdArgAttr.tpe, List(CODE.LIT.typed(p.name.toString), CODE.LIT.typed(arg.symbol.name.toString)), Nil)) + case (p, arg) => + cls.addAnnotation(AnnotationInfo(SuperArgAttr.tpe, List(CODE.LIT.typed(p.name.toString), arg), Nil)) + } + } + }) + } + } + for (vparams1 <- vparamss1; vparam1 <- vparams1 dropRight 1) if (isRepeatedParamType(vparam1.symbol.tpe)) StarParamNotLastError(vparam1) - val tpt1 = checkNoEscaping.privates(this, meth, transformedOr(ddef.tpt, typedType(ddef.tpt))) + val tpt1 = checkNoEscapingPrivates(this, meth, transformedOr(ddef.tpt, typedType(ddef.tpt))) checkNonCyclic(ddef, tpt1) ddef.tpt.setType(tpt1.tpe) val typedMods = typedModifiers(ddef.mods) @@ -2538,7 +2516,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper tdef.symbol.deSkolemize.removeAnnotation(definitions.SpecializedClass) } - val rhs1 = checkNoEscaping.privates(this, tdef.symbol, typedType(tdef.rhs)) + val rhs1 = checkNoEscapingPrivates(this, tdef.symbol, typedType(tdef.rhs)) checkNonCyclic(tdef.symbol) if (tdef.symbol.owner.isType) rhs1.tpe match { @@ -2783,22 +2761,25 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper * an alternative TODO: add partial function AST node or equivalent and get rid of this synthesis --> do everything in uncurry (or later) * however, note that pattern matching codegen is designed to run *before* uncurry */ - def synthesizePartialFunction(paramName: TermName, paramPos: Position, paramSynthetic: Boolean, + def synthesizePartialFunction(paramName: TermName, paramPos: Position, paramType: Type, paramSynthetic: Boolean, tree: Tree, mode: Mode, pt: Type): Tree = { assert(pt.typeSymbol == PartialFunctionClass, s"PartialFunction synthesis for match in $tree requires PartialFunction expected type, but got $pt.") - val (argTp, resTp) = partialFunctionArgResTypeFromProto(pt) + val (argTp0, resTp) = partialFunctionArgResTypeFromProto(pt) // if argTp isn't fully defined, we can't translate --> error // NOTE: resTp still might not be fully defined - if (!isFullyDefined(argTp)) { + if (!isFullyDefined(argTp0)) { MissingParameterTypeAnonMatchError(tree, pt) return setError(tree) } + val argTp = + if (paramType.ne(NoType)) paramType + else argTp0 // targs must conform to Any for us to synthesize an applyOrElse (fallback to apply otherwise -- typically for @cps annotated targs) val targsValidParams = (argTp <:< AnyTpe) && (resTp <:< AnyTpe) - val anonClass = context.owner newAnonymousFunctionClass tree.pos addAnnotation SerialVersionUIDAnnotation + val anonClass = context.owner.newAnonymousFunctionClass(tree.pos).addAnnotation(SerialVersionUIDAnnotation) import CODE._ @@ -2838,7 +2819,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } // `def applyOrElse[A1 <: $argTp, B1 >: $matchResTp](x: A1, default: A1 => B1): B1 = - // ${`$selector match { $cases; case default$ => default(x) }` + // ${`$selector match { $cases; case default$ => default(x) }`} def applyOrElseMethodDef = { val methodSym = anonClass.newMethod(nme.applyOrElse, tree.pos, FINAL | OVERRIDE) @@ -2858,8 +2839,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // First, type without the default case; only the cases provided // by the user are typed. The LUB of these becomes `B`, the lower - // bound of `B1`, which in turn is the result type of the default - // case + // bound of `B1`, which in turn is the result type of the default case val match0 = methodBodyTyper.typedMatch(selector(x), cases, mode, resTp) val matchResTp = match0.tpe @@ -3147,7 +3127,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // After typer, no need for further checks, parameter type inference or PartialFunction synthesis. if (isPastTyper) doTypedFunction(fun, resProto) else { - val paramsMissingType = mutable.ArrayBuffer.empty[ValDef] //.sizeHint(numVparams) probably useless, since initial size is 16 and max fun arity is 22 + val paramsMissingType = ArrayBuffer.empty[ValDef] //.sizeHint(numVparams) probably useless, since initial size is 16 and max fun arity is 22 // first, try to define param types from expected function's arg types if needed foreach2(vparams, argProtos) { (vparam, argpt) => @@ -3155,6 +3135,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // because I don't see how we could recurse after the `setError(vparam)` call below if (vparam.tpt.isEmpty) { if (isFullyDefined(argpt)) vparam.tpt setType argpt + else if (vparam.hasAttachment[BooleanParameterType.type]) vparam.tpt.setType(definitions.BooleanTpe) // `if (_)` else paramsMissingType += vparam if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus @@ -3167,12 +3148,22 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // we ran out of things to try, missing parameter types are an irrevocable error var issuedMissingParameterTypeError = false paramsMissingType.foreach { vparam => - setError(vparam) // see neg/t8675b.scala (we used to set vparam.tpt to ErrorType, but that isn't as effective) + setError(vparam) // see neg/t8675b.scala setting vparam.tpt to ErrorType isn't as effective MissingParameterTypeError(fun, vparam, pt, withTupleAddendum = !issuedMissingParameterTypeError) issuedMissingParameterTypeError = true } - - setError(fun) + fun match { + case Function(_, Match(_, _)) => setError(fun) + case _ if !issuedMissingParameterTypeError => setError(fun) + case _ => + // Improve error reporting: propagate what we know about the function's type for better failure. + val paramTypesForErrorMessage = vparams.map { param => + if (param.tpt.isEmpty) WildcardType + else silent(_.typedType(param.tpt).tpe) + .fold(WildcardType: Type) { case ErrorType => NoType case tp => tp } + } + fun.setType(appliedType(FunctionClass(numVparams), paramTypesForErrorMessage :+ WildcardType)) + } } } else if (numVparams == 1 && pt.typeSymbol == PartialFunctionClass) { // dodge auto-tupling with the == 1 // translate `x => x match { }` : PartialFunction to @@ -3189,9 +3180,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner) val outerTyper = newTyper(context.outer) val p = vparams.head - if (p.tpt.tpe == null) p.tpt setType outerTyper.typedType(p.tpt).tpe - - outerTyper.synthesizePartialFunction(p.name, p.pos, paramSynthetic = false, funBody, mode, pt) + if (p.tpt.tpe == null) p.tpt.setType(outerTyper.typedType(p.tpt).tpe) + outerTyper.synthesizePartialFunction(p.name, p.pos, p.tpt.tpe, paramSynthetic = false, funBody, mode, pt) } else doTypedFunction(fun, resProto) } } @@ -3400,49 +3390,59 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper result } - // TODO: adapt to new trait field encoding, figure out why this exemption is made - // 'accessor' and 'accessed' are so similar it becomes very difficult to - //follow the logic, so I renamed one to something distinct. - def accesses(looker: Symbol, accessed: Symbol) = ( - accessed.isLocalToThis - && (accessed.isParamAccessor || looker.hasAccessorFlag && !accessed.hasAccessorFlag && accessed.isPrivate) - ) - + /* From the spec (refchecks checks other conditions regarding erasing to the same type and default arguments): + * + * A block expression [... its] statement sequence may not contain two definitions or + * declarations that bind the same name --> `inBlock` + * + * It is an error if a template directly defines two matching members. + * + * A member definition $M$ _matches_ a member definition $M'$, if $M$ and $M'$ bind the same name, + * and one of following holds: + * 1. Neither $M$ nor $M'$ is a method definition. + * 2. $M$ and $M'$ define both monomorphic methods with equivalent argument types. + * 3. $M$ defines a parameterless method and $M'$ defines a method with an empty parameter list `()` or _vice versa_. + * 4. $M$ and $M'$ define both polymorphic methods with equal number of argument types $\overline T$, $\overline T'$ + * and equal numbers of type parameters $\overline t$, $\overline t'$, say, + * and $\overline T' = [\overline t'/\overline t]\overline T$. + */ def checkNoDoubleDefs(scope: Scope): Unit = { var e = scope.elems while ((e ne null) && e.owner == scope) { + val sym = e.sym var e1 = scope.lookupNextEntry(e) while ((e1 ne null) && e1.owner == scope) { - val sym = e.sym val sym1 = e1.sym - /* From the spec (refchecks checks other conditions regarding erasing to the same type and default arguments): - * - * A block expression [... its] statement sequence may not contain two definitions or - * declarations that bind the same name --> `inBlock` - * - * It is an error if a template directly defines two matching members. - * - * A member definition $M$ _matches_ a member definition $M'$, if $M$ and $M'$ bind the same name, - * and one of following holds: - * 1. Neither $M$ nor $M'$ is a method definition. - * 2. $M$ and $M'$ define both monomorphic methods with equivalent argument types. - * 3. $M$ defines a parameterless method and $M'$ defines a method with an empty parameter list `()` or _vice versa_. - * 4. $M$ and $M'$ define both polymorphic methods with equal number of argument types $\overline T$, $\overline T'$ - * and equal numbers of type parameters $\overline t$, $\overline t'$, say, - * and $\overline T' = [\overline t'/\overline t]\overline T$. - */ - if (!(accesses(sym, sym1) || accesses(sym1, sym)) // TODO: does this purely defer errors until later? - && (inBlock || !(sym.isMethod || sym1.isMethod) || (sym.tpe matches sym1.tpe)) - // default getters are defined twice when multiple overloads have defaults. - // The error for this is deferred until RefChecks.checkDefaultsInOverloaded - && !sym.isErroneous && !sym1.isErroneous && !sym.hasDefault) { - log("Double definition detected:\n " + - ((sym.getClass, sym.info, sym.ownerChain)) + "\n " + - ((sym1.getClass, sym1.info, sym1.ownerChain))) + def allowPrivateLocalAcc: Boolean = + sym.isParamAccessor && sym.isPrivateLocal || sym1.isParamAccessor && sym1.isPrivateLocal + def nullaryNilary: Boolean = { + def nn(m: Symbol): Boolean = m.isParamAccessor || m.hasAccessorFlag || !m.isMethod || { + m.tpe match { + case MethodType(Nil, _) | NullaryMethodType(_) => true + case _ => false + } + } + nn(sym) && nn(sym1) + } + def correctly: Boolean = nullaryNilary.tap(if (_) reportCorrection()) && currentRun.sourceFeatures.doubleDefinitions + def reportCorrection(): Unit = + if (currentRun.isScala3 && !currentRun.sourceFeatures.doubleDefinitions) + context.warning(sym.pos, s"Double definition will be detected in Scala 3; the conflicting $sym1 is defined at ${sym1.pos.line}:${sym1.pos.column}", Scala3Migration) + + val conflicted = inBlock || (!sym.isMethod && !sym1.isMethod) || + sym.tpe.matches(sym1.tpe) && !allowPrivateLocalAcc || // Scala 2: allow `class C(x: A) { def x: B }` + correctly // Scala 3: warn / err for `class C(x: A) { def x: B }`, and with nilary `def x(): B` + + // default getters are defined twice when multiple overloads have defaults. + // The error for this is deferred until RefChecks.checkDefaultsInOverloaded + if (conflicted && !sym.isErroneous && !sym1.isErroneous && !sym.hasDefault) { + log(sm"""Double definition detected: + | ${(sym.getClass, sym.info, sym.ownerChain)} + | ${(sym1.getClass, sym1.info, sym1.ownerChain)}""") DefDefinedTwiceError(sym, sym1) - scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779 + scope.unlink(e1) // need to unlink to avoid later problems with lub; see #scala/bug#2779 } e1 = scope.lookupNextEntry(e1) } @@ -3477,7 +3477,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!sym.initialize.hasFlag(IS_ERROR)) { newStats += typedStat(tree) // might add even more synthetics to the scope tree.getAndRemoveAttachment[CaseApplyInheritAccess.type].foreach(_ => - runReporting.warning(tree.pos, "access modifiers for `apply` method are copied from the case class constructor", Scala3Migration, sym)) + runReporting.warning(tree.pos, "access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access)", Scala3Migration, sym)) } context.unit.synthetics -= sym case _ => () @@ -3533,7 +3533,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // As packages are open, it doesn't make sense to check double definitions here. Furthermore, // it is expensive if the package is large. Instead, such double definitions are checked in `Namers.enterInScope` - if (!context.owner.isPackageClass) + if (!context.owner.isPackageClass && !unit.isJava) checkNoDoubleDefs(scope) // Note that Java units don't have synthetics, but there's no point in making a special case (for performance or correctness), @@ -3598,7 +3598,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // No need for phasedAppliedType, as we don't get here during erasure -- // overloading resolution happens during type checking. // During erasure, the condition above (fun.symbol.isOverloaded) is false. - functionType(vparams map (_ => AnyTpe), shapeType(body)) + functionType(vparams.map(_ => AnyTpe), shapeType(body)) case Match(EmptyTree, _) => // A partial function literal appliedType(PartialFunctionClass, AnyTpe :: NothingTpe :: Nil) case NamedArg(Ident(name), rhs) => @@ -3606,7 +3606,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case _ => NothingTpe } - val argtypes = args map shapeType + val argtypes = args.map(shapeType) val pre = fun.symbol.tpe.prefix var sym = fun.symbol filter { alt => // must use pt as expected type, not WildcardType (a tempting quick fix to #2665) @@ -3633,12 +3633,14 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case sym1 => sym = sym1 } } - if (sym == NoSymbol) fun + if (sym == NoSymbol) EmptyTree else adaptAfterOverloadResolution(fun setSymbol sym setType pre.memberType(sym), mode.forFunMode) } else fun } - val fun = preSelectOverloaded(fun0) + val preSelected = preSelectOverloaded(fun0) + val shapeless = preSelected.isEmpty + val fun = if (shapeless) fun0 else preSelected val argslen = args.length fun.tpe match { @@ -3656,10 +3658,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } arg match { - // scala/bug#8197/scala/bug#4592 call for checking whether this named argument could be interpreted as an assign - // infer.checkNames must not use UnitType: it may not be a valid assignment, or the setter may return another type from Unit - // TODO: just make it an error to refer to a non-existent named arg, as it's far more likely to be - // a typo than an assignment passed as an argument case NamedArg(lhs@Ident(name), rhs) => // named args: only type the righthand sides ("unknown identifier" errors otherwise) // the assign is untyped; that's ok because we call doTypedApply @@ -3677,8 +3675,22 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } } } - if (context.reporter.hasErrors) + if (context.reporter.hasErrors) { + if (shapeless) { + val argsWilded = args1.zip(argTpes).map { + case (Function(vparams, _), argTpe) if argTpe.isError => + val paramTypesForErrorMessage = vparams.map { param => + if (param.tpt.isEmpty) WildcardType + else silent(_.typedType(param.tpt).tpe) + .fold(WildcardType: Type) { case ErrorType => NoType case tp => tp } + } + appliedType(FunctionClass(vparams.length), paramTypesForErrorMessage :+ WildcardType) + case (_, argTpe) => if (argTpe.isError) WildcardType else argTpe + } + InferErrorGen.NoMatchingAlternative(fun, alts, argsWilded, pt) + } setError(tree) + } else { // warn about conversions applied to blocks (#9386) in lieu of fixing def checkConversionsToBlockArgs(appl: Tree): Unit = @@ -3688,12 +3700,12 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper argss.find { case (aiv: ApplyImplicitView) :: Nil => aiv.args match { - case Block(_, _) :: Nil => true + case Block(_ :: _, _) :: Nil => true case _ => false } case _ => false } - needsAdjust.foreach(ts => context.warning(ts.head.pos, "Implicits applied to block expressions after overload resolution may have unexpected semantics", WarningCategory.LintBynameImplicit)) + needsAdjust.foreach(ts => context.warning(ts.head.pos, "Overloaded implicit conversions that take a by-name parameter are applied to the entire block, not just the result expression.", WarningCategory.LintBynameImplicit)) } inferMethodAlternative(fun, undetparams, argTpes.toList, pt) doTypedApply(tree, adaptAfterOverloadResolution(fun, mode.forFunMode, WildcardType), args1, mode, pt).tap(checkConversionsToBlockArgs) @@ -3768,7 +3780,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper duplErrorTree(WrongNumberOfArgsError(tree, fun)) } else if (lencmp > 0) { tryTupleApply orElse duplErrorTree { - val (_, argPos) = removeNames(Typer.this)(args, params) + val (argsNoNames, argPos) = removeNames(Typer.this)(args, params) + argsNoNames.foreach(typed(_, mode, ErrorType)) // typecheck args TooManyArgsNamesDefaultsError(tree, fun, formals, args, argPos) } } else if (lencmp == 0) { @@ -3819,7 +3832,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x) if (fun1.isErroneous) duplErrTree else { - val NamedApplyBlock(NamedApplyInfo(qual, targs, previousArgss, _)) = fun1: @unchecked + val NamedApplyBlock(NamedApplyInfo(qual, targs, previousArgss, _, _)) = fun1: @unchecked val blockIsEmpty = fun1 match { case Block(Nil, _) => // if the block does not have any ValDef we can remove it. Note that the call to @@ -3828,7 +3841,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper true case _ => false } - val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos.focus, context) + val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos.focus, context, mode) val funSym = fun1 match { case Block(_, expr) => expr.symbol case x => throw new MatchError(x) } val lencmp2 = compareLengths(allArgs, formals) @@ -3849,7 +3862,17 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } else { rollbackNamesDefaultsOwnerChanges() tryTupleApply orElse { - removeNames(Typer.this)(allArgs, params) // report bad names + // If we don't have enough arguments we still try to type the arguments that we do have, in order to + // propagate known types throughout the subtree to support queries in the presentation compiler. + if (isInteractive && missing.nonEmpty) { + // You would expect `missing` to be non-empty in this branch, but `addDefaults` has a corner case + // for t3649 that causes it to drop some params from `missing` (see `addDefaults` for the reasoning). + val allArgsPlusMissingErrors = allArgs ++ missing.map(s => NamedArg(Ident(s.name), gen.mkZero(NothingTpe))) + silent(_.doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgsPlusMissingErrors, mode, pt)) + } + + val (argsNoNames, _) = removeNames(Typer.this)(allArgs, params) // report bad names + argsNoNames.foreach(typed(_, mode, ErrorType)) // typecheck args duplErrorTree(NotEnoughArgsError(tree, fun, missing)) } } @@ -3953,14 +3976,15 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!argtparams.isEmpty) { val strictPt = formal.instantiateTypeParams(tparams, strictTargs) inferArgumentInstance(arg1, argtparams, strictPt, lenientPt) - arg1 - } else arg1 + } + arg1 } val args1 = map2(args, formals)(typedArgToPoly) - if (args1 exists { _.isErrorTyped }) duplErrTree + if (args1.exists(_.isErrorTyped)) duplErrTree else { debuglog("infer method inst " + fun + ", tparams = " + tparams + ", args = " + args1.map(_.tpe) + ", pt = " + pt + ", lobounds = " + tparams.map(_.tpe.lowerBound) + ", parambounds = " + tparams.map(_.info)) //debug - // define the undetparams which have been fixed by this param list, replace the corresponding symbols in "fun" + // define the undetparams which have been fixed by this param list, + // replace the corresponding symbols in "fun" // returns those undetparams which have not been instantiated. val undetparams = inferMethodInstance(fun, tparams, args1, pt) try doTypedApply(tree, fun, args1, mode, pt) @@ -4020,19 +4044,24 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } def registerNowarn(info: AnnotationInfo): Unit = { if (annotee.isDefined && NowarnClass.exists && info.matches(NowarnClass) && !runReporting.suppressionExists(info.pos)) { - val filters = (info.assocs: @unchecked) match { + var verbose = false + val filters = (info.assocsForSuper(NowarnClass): @unchecked) match { case Nil => List(MessageFilter.Any) case (_, LiteralAnnotArg(s)) :: Nil => - if (s.stringValue.isEmpty) Nil - else { - val (ms, fs) = s.stringValue.split('&').map(WConf.parseFilter(_, runReporting.rootDirPrefix)).toList.partitionMap(identity) + val str = s.stringValue + if (str.isEmpty) Nil + else if (str == "v" || str == "verbose") { + verbose = true + List(MessageFilter.Any) + } else { + val (ms, fs) = str.split('&').map(WConf.parseFilter(_, runReporting.rootDirPrefix)).toList.partitionMap(identity) if (ms.nonEmpty) reporter.error(info.pos, s"Invalid message filter:\n${ms.mkString("\n")}") fs } } val (start, end) = rangeFinder() - runReporting.addSuppression(Suppression(info.pos, filters, start, end)) + runReporting.addSuppression(Suppression(info.pos, filters, start, end, verbose = verbose)) } } def registerDeprecationSuppression(info: AnnotationInfo): Unit = @@ -4092,6 +4121,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } } + // Usually, defaults are the default expression ASTs, but only for annotations compiled with a recent compiler + // that have `annotation.meta.defaultArg` meta annotations on them. def isDefaultArg(tree: Tree) = tree match { case treeInfo.Applied(fun, _, _) => fun.symbol != null && fun.symbol.isDefaultGetter case _ => false @@ -4224,22 +4255,16 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val typedAnn: Tree = { // local dummy fixes scala/bug#5544 val localTyper = newTyper(context.make(ann, context.owner.newLocalDummy(ann.pos))) - localTyper.typed(ann, mode) + localTyper.typed(ann, mode | ANNOTmode) } @tailrec def annInfo(t: Tree): AnnotationInfo = t match { + case Block(Nil, expr) => annInfo(expr) + case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => // `tpt.tpe` is more precise than `annType`, since it incorporates the types of `args` AnnotationInfo(tpt.tpe, args, Nil).setOriginal(typedAnn).setPos(t.pos) - case Block(_, expr) => - if (!annTypeSym.isNonBottomSubClass(ConstantAnnotationClass)) - context.warning(t.pos, "Usage of named or default arguments transformed this annotation\n"+ - "constructor call into a block. The corresponding AnnotationInfo\n"+ - "will contain references to local values and default getters instead\n"+ - "of the actual argument trees", WarningCategory.Other) - annInfo(expr) - case Apply(fun, args) => context.warning(t.pos, "Implementation limitation: multiple argument lists on annotations are\n"+ "currently not supported; ignoring arguments "+ args, WarningCategory.Other) @@ -4892,7 +4917,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val cases = tree.cases if (selector == EmptyTree) { if (pt.typeSymbol == PartialFunctionClass) - synthesizePartialFunction(newTermName(fresh.newName("x")), tree.pos, paramSynthetic = true, tree, mode, pt) + synthesizePartialFunction(newTermName(fresh.newName("x")), tree.pos, paramType = NoType, paramSynthetic = true, tree, mode, pt) else { val arity = functionArityFromType(pt) match { case -1 => 1 case arity => arity } // scala/bug#8429: consider sam and function type equally in determining function arity @@ -5172,7 +5197,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def reportError(error: SilentTypeError): Tree = { error.reportableErrors.foreach(context.issue) error.warnings.foreach { case ContextWarning(p, m, c, s, as) => context.warning(p, m, c, s, as) } - args.foreach(typed(_, mode, ErrorType)) + args.map { case NamedArg(_, rhs) => rhs case arg => arg } + .foreach(typed(_, mode, ErrorType)) setError(tree) } def advice1(convo: Tree, errors: List[AbsTypeError], err: SilentTypeError): List[AbsTypeError] = @@ -5385,17 +5411,38 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree } - // For Java, instance and static members are in the same scope, but we put the static ones in the companion object // so, when we can't find a member in the class scope, check the companion def inCompanionForJavaStatic(cls: Symbol, name: Name): Symbol = if (!(context.unit.isJava && cls.isClass)) NoSymbol else context.javaFindMember(cls.typeOfThis, name, s => s.isStaticMember || s.isStaticModule)._2 + // For Java, a selection p.q requires checking if p is a type with member q; otherwise it is a package. + // If a non-package term was found, look for a class; otherwise just look for a package. + def repairJavaSelection(qual: Tree, name: Name): Symbol = + if (!context.unit.isJava || !qual.hasAttachment[RootSelection.type] || qual.symbol.hasPackageFlag) NoSymbol + else qual match { + case Ident(qname) => + val found = + if (qual.symbol.isTerm) { + val lookup = context.lookupSymbol(qname.toTypeName, s => qualifies(s) && s.isClass) + if (lookup.isSuccess) inCompanionForJavaStatic(lookup.symbol, name) else NoSymbol + } + else NoSymbol + found.orElse { + context.lookupSymbol(qname, s => qualifies(s) && s.hasPackageFlag) match { + case LookupSucceeded(_, pkg) => member(pkg.info, name) + case _ => NoSymbol + } + } + case _ => NoSymbol + } // If they try C.tupled, make it (C.apply _).tupled - def fixUpCaseTupled(tree: Tree, qual: Tree, name: Name, mode: Mode): Tree = - if (currentRun.isScala3Cross && !isPastTyper && qual.symbol != null && qual.symbol.isModule && qual.symbol.companion.isCase && - context.undetparams.isEmpty && fixableFunctionMembers.contains(name)) { + def fixUpCaseTupled(tree: Tree, qual: Tree, name: Name, mode: Mode): Tree = { + def isFixable(name: Name) = name == nme.tupled || name == nme.curried + + if (!isPastTyper && qual.symbol != null && qual.symbol.isModule && qual.symbol.companion.isCase && + context.undetparams.isEmpty && isFixable(name)) { val t2 = { val t = atPos(tree.pos)(Select(qual, nme.apply)) val t1 = typedSelect(t, qual, nme.apply) @@ -5409,6 +5456,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper else EmptyTree } else EmptyTree + } /* Attribute a selection where `tree` is `qual.name`. * `qual` is already attributed. @@ -5429,7 +5477,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (!isPastTyper && isUniversalMember(result.symbol)) context.warning(tree.pos, s"dubious usage of ${result.symbol} with unit value", WarningCategory.LintUniversalMethods) - val sym = tree.symbol orElse member(qualTp, name) orElse inCompanionForJavaStatic(qualTp.typeSymbol, name) + val sym = tree.symbol + .orElse(member(qualTp, name)) + .orElse(inCompanionForJavaStatic(qualTp.typeSymbol, name)) + .orElse(repairJavaSelection(qual, name)) if ((sym eq NoSymbol) && name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) { // symbol not found? --> try to convert implicitly to a type that does have the required // member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an @@ -5514,7 +5565,12 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper context.pendingStabilizers ::= vdef qual.changeOwner(context.owner -> vsym) val newQual = Ident(vsym) setType singleType(NoPrefix, vsym) setPos qual.pos.focus - return typedSelect(tree, newQual, name) + return typedSelect(tree, newQual, name).modifyType(_.map { + // very specific fix for scala/bug#12987 (details in the ticket) + case t: AliasTypeRef if t.pre.termSymbol == vsym && context.undetparams.contains(t.normalize.typeSymbol) => + t.normalize + case t => t + }) } val tree1 = tree match { @@ -5644,7 +5700,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper startContext.lookupSymbol(name.toTypeName, qualifies).symbol } else NoSymbol - // in Java, only pick a package if it is rooted + // in Java, only pick a package p if it is rooted (no relative packaging) def termQualifies(sym: Symbol) = qualifies(sym) && ( !startContext.unit.isJava || !sym.hasPackageFlag || sym.owner.isEffectiveRoot || sym.owner.isRootPackage || sym.isRootPackage @@ -5659,7 +5715,32 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case LookupInaccessible(symbol, msg) => issue(AccessError(tree, symbol, context, msg)) case LookupNotFound => asTypeName orElse inEmptyPackage orElse lookupInRoot(name) match { - case NoSymbol => issue(SymbolNotFoundError(tree, name, context.owner, startContext, mode.in(all = PATTERNmode, none = APPSELmode | TYPEPATmode))) + case NoSymbol => + def hasOutput = settings.outputDirs.getSingleOutput.isDefined || settings.outputDirs.outputs.nonEmpty + val hidden = !unit.isJava && hasOutput && { + startContext.lookupSymbol(name.companionName, _ => true) match { + case LookupSucceeded(qualifier, symbol) if symbol.owner.hasPackageFlag && symbol.sourceFile != null => + symbol.owner.info.decls.lookupAll(name).toList match { + case other :: Nil if other.sourceFile == null => + val nameString = name.toString + classPath.classes(symbol.owner.fullNameString).find(_.name == nameString).exists { repr => + settings.outputDirs.getSingleOutput match { + // is the class file not in the output directory, so it's a dependency not a stale symbol + case Some(out) => repr.binary.exists(!_.path.startsWith(out.path)) + // is the class file not in any output directory + case _ => repr.binary.exists { bin => + !settings.outputDirs.outputs.exists { case (_, out) => + bin.path.startsWith(out.path) + } + } + } + } + case _ => false + } + case _ => false + } + } + issue(SymbolNotFoundError(tree, name, context.owner, inPattern = mode.in(all = PATTERNmode, none = APPSELmode | TYPEPATmode), hidden = hidden)) case oksymbol => typed1(tree.setSymbol(oksymbol), mode, pt) } case LookupSucceeded(qual, symbol) => @@ -5673,7 +5754,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (symbol != definitions.StringContextModule) runReporting.warning( tree.pos, - s"String interpolations always use scala.StringContext in Scala 3 (${symbol.fullNameString} is used here)", + s"In Scala 3 (or with -Xsource-features:string-context-scope), String interpolations always use scala.StringContext (${symbol.fullNameString} is used here)", Scala3Migration, context.owner) ) @@ -5707,8 +5788,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // to avoid inference errors in pattern matching. stabilize(tree2, pre2, mode, pt).modifyType(dropIllegalStarTypes) } - if (!isPastTyper && currentRun.isScala3 && !currentRun.isScala3Cross && isFunctionType(pt) && symbol.isModule && symbol.isSynthetic && symbol.companion.isCase) - context.deprecationWarning(tree.pos, symbol, s"Synthetic case companion used as a Function, use explicit object with Function parent", "2.13.13") onSuccess.setAttachments(tree.attachments) } } @@ -5823,6 +5902,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } } + // pre-begin typed1 val sym: Symbol = tree.symbol if ((sym ne null) && (sym ne NoSymbol)) sym.initialize @@ -5883,8 +5963,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper tree } - - val Try(block, catches, fin) = tree + val Try(block, catches, finalizer) = tree val block1 = typed(block, pt) val cases = catches match { case CaseDef(EmptyTree, EmptyTree, catchExpr) :: Nil => @@ -5899,7 +5978,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case _ => catches } val catches1 = typedCases(cases, ThrowableTpe, pt) - val fin1 = if (fin.isEmpty) fin else typed(fin, UnitTpe) + val fin1 = if (finalizer.isEmpty) finalizer else typed(finalizer, UnitTpe) def finish(ownType: Type) = treeCopy.Try(tree, block1, catches1, fin1) setType ownType @@ -6017,22 +6096,26 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // attempt to avoid warning about trees munged by macros def isMacroExpansion = { // context.tree is not the expandee; it is plain new SC(ps).m(args) - //context.tree exists (t => (t.pos includes lit.pos) && hasMacroExpansionAttachment(t)) + //context.tree.exists(t => t.pos.includes(lit.pos) && hasMacroExpansionAttachment(t)) // testing pos works and may suffice - //openMacros exists (_.macroApplication.pos includes lit.pos) + //openMacros.exists(_.macroApplication.pos.includes(lit.pos)) // tests whether the lit belongs to the expandee of an open macro - openMacros exists (_.macroApplication.attachments.get[MacroExpansionAttachment] match { - case Some(MacroExpansionAttachment(_, t: Tree)) => t exists (_ == lit) + openMacros.exists(_.macroApplication.attachments.get[MacroExpansionAttachment] match { + case Some(MacroExpansionAttachment(_, t: Tree)) => t.exists(_ eq lit) case _ => false }) } + val checkMacroExpansion = settings.warnMacros.value match { + case "both" | "after" => true + case _ => !isMacroExpansion + } // An interpolation desugars to `StringContext(parts).m(args)`, so obviously not missing. // `implicitNotFound` annotations have strings with `${A}`, so never warn for that. - // Also don't warn for macro expansion. + // Also don't warn for macro expansion unless they ask for it. def mightBeMissingInterpolation: Boolean = context.enclosingApply.tree match { case Apply(Select(Apply(RefTree(_, nme.StringContextName), _), _), _) => false case Apply(Select(New(RefTree(_, tpnme.implicitNotFound)), _), _) => false - case _ => !isMacroExpansion + case _ => checkMacroExpansion } def maybeWarn(s: String): Unit = { def warn(message: String) = context.warning(lit.pos, s"possible missing interpolator: $message", WarningCategory.LintMissingInterpolator) @@ -6062,8 +6145,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // short-circuit on leading ${} if (!exprs.head.isEmpty && exprs.exists(warnableExpr)) warn("detected an interpolated expression") // "${...}" - } else - suspiciousIdents.find(id => isPlausible(id.substring(1))).foreach(id => warn(s"detected interpolated identifier `$id`")) + } else suspiciousIdents.toList match { + case Nil => + case id :: Nil => if (isPlausible(id.substring(1))) warn(s"detected interpolated identifier `$id`") + case all => if (all.forall(id => isPlausible(id.substring(1)))) warn(all.mkString("detected interpolated identifiers `", "`, `", "`")) + } } lit match { case Literal(Constant(s: String)) if mightBeMissingInterpolation => maybeWarn(s) @@ -6074,7 +6160,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def typedLiteral(tree: Literal) = { if (settings.warnMissingInterpolator) warnMissingInterpolator(tree) - tree setType (if (tree.value.tag == UnitTag) UnitTpe else ConstantType(tree.value)) + tree.setType(if (tree.value.tag == UnitTag) UnitTpe else ConstantType(tree.value)) } def typedSingletonTypeTree(tree: SingletonTypeTree) = { @@ -6289,7 +6375,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case ex: TypeError => tree.clearType() // The only problematic case are (recoverable) cyclic reference errors which can pop up almost anywhere. - typingStack.printTyping(tree, "caught %s: while typing %s".format(ex, tree)) //DEBUG + typingStack.printTyping(tree, s"caught $ex: while typing $tree") reportTypeError(context, tree.pos, ex) setError(tree) case ex: Exception => @@ -6440,7 +6526,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (pt != Kind.Wildcard && pt.typeParams.isEmpty) typedType(tree, mode) // kind is known and it's * else context withinTypeConstructorAllowed typed(tree, NOmode, pt) - def typedHigherKindedType(tree: Tree, mode: Mode): Tree = + def typedHigherKindedType(tree: Tree, @unused mode: Mode): Tree = context withinTypeConstructorAllowed typed(tree) /** Types a type constructor tree used in a new or supertype */ diff --git a/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala b/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala index 95512297b20d..cc5e8fb89e43 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypersTracking.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,7 @@ package scala.tools.nsc package typechecker import Mode._ +import scala.annotation._ trait TypersTracking { self: Analyzer => @@ -116,7 +117,7 @@ trait TypersTracking { show(resetIfEmpty(indented("""\-> """ + s))) typedTree } - def showAdapt(original: Tree, adapted: Tree, pt: Type, context: Context): Unit = { + def showAdapt(original: Tree, adapted: Tree, pt: Type, @unused context: Context): Unit = { if (!noPrintAdapt(original, adapted)) { def tree_s1 = inLightCyan(truncAndOneLine(ptTree(original))) def pt_s = if (pt.isWildcard) "" else s" based on pt $pt" diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 5750385ad835..8123cea99abc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -27,8 +27,8 @@ trait Unapplies extends ast.TreeDSL { import global._ import definitions._ - import CODE.{ CASE => _, _ } - import treeInfo.{ isRepeatedParamType, isByNameParamType } + import CODE.{CASE => _, _} + import treeInfo.{isByNameParamType, isRepeatedParamType} private def unapplyParamName = nme.x_0 private def caseMods = Modifiers(SYNTHETIC | CASE) @@ -98,14 +98,20 @@ trait Unapplies extends ast.TreeDSL { } } - sealed private trait ApplyAccess - private object Default extends ApplyAccess - private object Warn extends ApplyAccess - private object Inherit extends ApplyAccess - private def applyAccess(mods: Modifiers): ApplyAccess = { + private object ApplyAccess { + type Flags = Int + final val Default = 0 + final val Warn = 1 + final val Inherit = 2 + def isWarn(access: Flags): Boolean = access.&(Warn) != 0 + def isInherit(access: Flags): Boolean = access.&(Inherit) != 0 + } + private def applyAccess(mods: Modifiers): ApplyAccess.Flags = { + import ApplyAccess._ val changeModsIn3 = mods.hasFlag(PRIVATE) || (!mods.hasFlag(PROTECTED) && mods.hasAccessBoundary) - if (currentRun.isScala3Cross && changeModsIn3) Inherit - else if (currentRun.isScala3 && changeModsIn3) Warn + if (!changeModsIn3) Default + else if (currentRun.sourceFeatures.caseApplyCopyAccess) Inherit + else if (currentRun.isScala3) Warn else Default } @@ -113,10 +119,10 @@ trait Unapplies extends ast.TreeDSL { */ def caseModuleDef(cdef: ClassDef): ModuleDef = { val params = constrParamss(cdef) - def inheritFromFun = !currentRun.isScala3Cross && !cdef.mods.hasAbstractFlag && cdef.tparams.isEmpty && (params match { + def inheritFromFun = !currentRun.sourceFeatures.caseCompanionFunction && !cdef.mods.hasAbstractFlag && cdef.tparams.isEmpty && (params match { case List(ps) if ps.length <= MaxFunctionArity => true case _ => false - }) && applyAccess(constrMods(cdef)) != Inherit + }) && !ApplyAccess.isInherit(applyAccess(constrMods(cdef))) def createFun = { def primaries = params.head map (_.tpt) gen.scalaFunctionConstr(primaries, toIdent(cdef), abstractFun = true) @@ -163,10 +169,12 @@ trait Unapplies extends ast.TreeDSL { val inheritedMods = constrMods(cdef) val access = applyAccess(inheritedMods) val mods = - if (access == Inherit) (caseMods | (inheritedMods.flags & PRIVATE)).copy(privateWithin = inheritedMods.privateWithin) + if (ApplyAccess.isInherit(access)) (caseMods | (inheritedMods.flags & PRIVATE)).copy(privateWithin = inheritedMods.privateWithin) else caseMods factoryMeth(mods, nme.apply, cdef).tap(m => - if (access == Warn) m.updateAttachment(CaseApplyInheritAccess)) + if (ApplyAccess.isWarn(access)) + m.updateAttachment(CaseApplyInheritAccess) + ) } /** The unapply method corresponding to a case class @@ -257,11 +265,16 @@ trait Unapplies extends ast.TreeDSL { * ClassDef of the case class. */ def caseClassCopyMeth(cdef: ClassDef): Option[DefDef] = { - def isDisallowed(vd: ValDef) = isRepeatedParamType(vd.tpt) || isByNameParamType(vd.tpt) - val classParamss = constrParamss(cdef) - - if (cdef.symbol.hasAbstractFlag || mexists(classParamss)(isDisallowed)) None - else { + val classParamss = constrParamss(cdef) + def copyOK = { + def warn() = if (currentRun.isScala3) runReporting.warning(cdef.namePos, "case `copy` method is allowed to have by-name parameters under Scala 3 (or with -Xsource-features:case-copy-by-name)", Scala3Migration, cdef.symbol) + def isAllowed(vd: ValDef) = { + def checkByName = currentRun.sourceFeatures.caseCopyByName || !isByNameParamType(vd.tpt).tap(if (_) warn()) + !isRepeatedParamType(vd.tpt) && checkByName + } + !cdef.symbol.hasAbstractFlag && mforall(classParamss)(isAllowed) + } + def synthesizeCopy = { def makeCopyParam(vd: ValDef, putDefault: Boolean) = { val rhs = if (putDefault) toIdent(vd) else EmptyTree val flags = PARAM | (vd.mods.flags & IMPLICIT) | (if (putDefault) DEFAULTPARAM else 0) @@ -269,14 +282,12 @@ trait Unapplies extends ast.TreeDSL { val tpt = atPos(vd.pos.focus)(TypeTree() setOriginal vd.tpt) treeCopy.ValDef(vd, Modifiers(flags), vd.name, tpt, rhs) } - val tparams = constrTparamsInvariant(cdef) val paramss = classParamss match { case Nil => Nil case ps :: pss => ps.map(makeCopyParam(_, putDefault = true)) :: mmap(pss)(makeCopyParam(_, putDefault = false)) } - val classTpe = classType(cdef, tparams) val argss = mmap(paramss)(toIdent) val body: Tree = New(classTpe, argss) @@ -285,19 +296,18 @@ trait Unapplies extends ast.TreeDSL { if (currentRun.isScala3) { val inheritedMods = constrMods(cdef) val mods3 = Modifiers(SYNTHETIC | (inheritedMods.flags & AccessFlags), inheritedMods.privateWithin) - if (currentRun.isScala3Cross) - mods3 + if (currentRun.sourceFeatures.caseApplyCopyAccess) mods3 else { if (mods3 != synth) - runReporting.warning(cdef.pos, "access modifiers for `copy` method are copied from the case class constructor", Scala3Migration, cdef.symbol) + runReporting.warning(cdef.namePos, "access modifiers for `copy` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access)", Scala3Migration, cdef.symbol) synth } } else synth - val copyDefDef = atPos(cdef.pos.focus)( + atPos(cdef.pos.focus)( DefDef(copyMods, nme.copy, tparams, paramss, TypeTree(), body) ) - Some(copyDefDef) } + if (copyOK) Some(synthesizeCopy) else None } } diff --git a/src/compiler/scala/tools/nsc/typechecker/splain/SplainData.scala b/src/compiler/scala/tools/nsc/typechecker/splain/SplainData.scala index d00442686f99..73a6a508caec 100644 --- a/src/compiler/scala/tools/nsc/typechecker/splain/SplainData.scala +++ b/src/compiler/scala/tools/nsc/typechecker/splain/SplainData.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/splain/SplainDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/splain/SplainDiagnostics.scala index eeffca7b1016..df1844b2cc26 100644 --- a/src/compiler/scala/tools/nsc/typechecker/splain/SplainDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/splain/SplainDiagnostics.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/splain/SplainErrors.scala b/src/compiler/scala/tools/nsc/typechecker/splain/SplainErrors.scala index 3ed3af43aa6d..a9caa525c607 100644 --- a/src/compiler/scala/tools/nsc/typechecker/splain/SplainErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/splain/SplainErrors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -48,7 +48,7 @@ trait SplainErrors { self: Analyzer with SplainFormatting => def splainPushImplicitSearchFailure(implicitTree: Tree, expectedType: Type, originalError: AbsTypeError): Unit = { def pushImpFailure(fun: Tree, args: List[Tree]): Unit = { fun.tpe match { - case PolyType(tparams, restpe) if tparams.nonEmpty && sameLength(tparams, args) => + case PolyType(tparams, _) if tparams.nonEmpty && sameLength(tparams, args) => splainPushNonconformantBonds(expectedType, implicitTree, mapList(args)(_.tpe), tparams, Some(originalError)) case _ => } diff --git a/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatData.scala b/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatData.scala index 4dae6b1b5e31..c73b9c1f7846 100644 --- a/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatData.scala +++ b/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatData.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatting.scala b/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatting.scala index 24a794952d34..25c341f328fc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatting.scala +++ b/src/compiler/scala/tools/nsc/typechecker/splain/SplainFormatting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala index 21ceaa3a5620..8297bd3ab9ec 100644 --- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 04642c43544a..e61edc3a6725 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index 78cf5341fe0e..0c3d18279a2d 100644 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -91,7 +91,7 @@ object DocStrings { * usecase or the end of the string, as they might include other sections * of their own */ - def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] = { + def tagIndex(str: String, p: Int => Boolean = (_ => true)): List[(Int, Int)] = { var indices = findAll(str, 0) (idx => str(idx) == '@' && p(idx)) indices = mergeUsecaseSections(str, indices) indices = mergeInheritdocSections(str, indices) diff --git a/src/compiler/scala/tools/nsc/util/EditDistance.scala b/src/compiler/scala/tools/nsc/util/EditDistance.scala index 79110e22e279..2f3c71f85db5 100644 --- a/src/compiler/scala/tools/nsc/util/EditDistance.scala +++ b/src/compiler/scala/tools/nsc/util/EditDistance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/Exceptional.scala b/src/compiler/scala/tools/nsc/util/Exceptional.scala index 9cefac378b95..0cb869ec2348 100644 --- a/src/compiler/scala/tools/nsc/util/Exceptional.scala +++ b/src/compiler/scala/tools/nsc/util/Exceptional.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/InterruptReq.scala b/src/compiler/scala/tools/nsc/util/InterruptReq.scala index ddb1f3353c93..c9ccc78fbb80 100644 --- a/src/compiler/scala/tools/nsc/util/InterruptReq.scala +++ b/src/compiler/scala/tools/nsc/util/InterruptReq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/JarFactory.scala b/src/compiler/scala/tools/nsc/util/JarFactory.scala index 4b7e2cec869a..7a662036f727 100644 --- a/src/compiler/scala/tools/nsc/util/JarFactory.scala +++ b/src/compiler/scala/tools/nsc/util/JarFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala index 40987720d72d..cee0e67ee9de 100644 --- a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index 0a0ae1520e57..6f2c1996c096 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/SimpleTracer.scala b/src/compiler/scala/tools/nsc/util/SimpleTracer.scala index 287218657f98..68b1a5b9ccfd 100644 --- a/src/compiler/scala/tools/nsc/util/SimpleTracer.scala +++ b/src/compiler/scala/tools/nsc/util/SimpleTracer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/StackTracing.scala b/src/compiler/scala/tools/nsc/util/StackTracing.scala index 3db8a8ef96bb..65e9f81b344b 100644 --- a/src/compiler/scala/tools/nsc/util/StackTracing.scala +++ b/src/compiler/scala/tools/nsc/util/StackTracing.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/StringUtil.scala b/src/compiler/scala/tools/nsc/util/StringUtil.scala index cbe98088a26e..062a20a58e1a 100644 --- a/src/compiler/scala/tools/nsc/util/StringUtil.scala +++ b/src/compiler/scala/tools/nsc/util/StringUtil.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala index 4b922a87b965..a229b4052434 100644 --- a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala +++ b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index 670f6d461b34..ec0e2e633a9d 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/FastStringInterpolator.scala b/src/compiler/scala/tools/reflect/FastStringInterpolator.scala index 6a19c8911598..7f664aa85b29 100644 --- a/src/compiler/scala/tools/reflect/FastStringInterpolator.scala +++ b/src/compiler/scala/tools/reflect/FastStringInterpolator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,10 @@ package scala.tools package reflect -import nsc.Reporting.WarningCategory.Scala3Migration +import scala.StringContext.{InvalidEscapeException, InvalidUnicodeEscapeException, processEscapes, processUnicode} +import scala.collection.mutable.ListBuffer +import scala.reflect.internal.util.Position +import nsc.Reporting.WarningCategory.{Scala3Migration, WFlagTostringInterpolated} trait FastStringInterpolator extends FormatInterpolator { import c.universe._ @@ -26,51 +29,46 @@ trait FastStringInterpolator extends FormatInterpolator { // rewrite a tree like `scala.StringContext.apply("hello \\n ", " ", "").s("world", Test.this.foo)` // to `"hello \n world ".+(Test.this.foo)` private def interpolated(macroApp: Tree, isRaw: Boolean): Tree = macroApp match { - case Apply(Select(Apply(stringCtx@Select(qualSC, _), parts), _interpol), args) if - stringCtx.symbol == currentRun.runDefinitions.StringContext_apply && - treeInfo.isQualifierSafeToElide(qualSC) && - parts.forall(treeInfo.isLiteralString) && - parts.length == (args.length + 1) => + case Apply(Select(Apply(stringCtx @ Select(qualSC, _), parts), _interpol@_), args) + if stringCtx.symbol == currentRun.runDefinitions.StringContext_apply + && treeInfo.isQualifierSafeToElide(qualSC) + && parts.forall(treeInfo.isLiteralString) + && parts.length == (args.length + 1) => - val treated = - try - parts.mapConserve { - case lit @ Literal(Constant(stringVal: String)) => - def asRaw = { - val processed = StringContext.processUnicode(stringVal) - if (processed != stringVal) { - val pos = { - val diffindex = processed.zip(stringVal).zipWithIndex.collectFirst { - case ((p, o), i) if p != o => i - }.getOrElse(processed.length - 1) - lit.pos.withShift(diffindex) - } - def msg(fate: String) = s"Unicode escapes in raw interpolations are $fate; use literal characters instead" - if (currentRun.isScala3Cross) - stringVal - else if (currentRun.isScala3) { - runReporting.warning(pos, msg("ignored in Scala 3"), Scala3Migration, c.internal.enclosingOwner) - processed - } - else { - runReporting.deprecationWarning(pos, msg("deprecated"), "2.13.2", "", "") - processed - } - } - else stringVal + def adjustedEscPos(p: Position, delta: Int) = { + val start = p.start + delta + Position.range(p.source, start = start, point = start, end = start + 2) + } + val treated = parts.mapConserve { + case lit @ Literal(Constant(stringVal: String)) => + def asRaw = if (currentRun.sourceFeatures.unicodeEscapesRaw) stringVal else { + val processed = processUnicode(stringVal) + if (processed == stringVal) stringVal else { + val pos = { + val diffindex = processed.zip(stringVal).zipWithIndex.collectFirst { + case ((p, o), i) if p != o => i + }.getOrElse(processed.length - 1) + lit.pos.withShift(diffindex) } - val value = - if (isRaw) asRaw - else StringContext.processEscapes(stringVal) - val k = Constant(value) - // To avoid the backlash of backslash, taken literally by Literal, escapes are processed strictly (scala/bug#11196) - treeCopy.Literal(lit, k).setType(ConstantType(k)) - case x => throw new MatchError(x) + def msg(fate: String) = s"Unicode escapes in raw interpolations are $fate; use literal characters instead" + if (currentRun.isScala3) + runReporting.warning(pos, msg("ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw)"), Scala3Migration, c.internal.enclosingOwner) + else + runReporting.deprecationWarning(pos, msg("deprecated"), "2.13.2", "", "") + processed + } } - catch { - case ie: StringContext.InvalidEscapeException => c.abort(parts.head.pos.withShift(ie.index), ie.getMessage) - case iue: StringContext.InvalidUnicodeEscapeException => c.abort(parts.head.pos.withShift(iue.index), iue.getMessage) - } + val value = + try if (isRaw) asRaw else processEscapes(stringVal) + catch { + case ie: InvalidEscapeException => c.abort(adjustedEscPos(lit.pos, ie.index), ie.getMessage) + case iue: InvalidUnicodeEscapeException => c.abort(adjustedEscPos(lit.pos, iue.index), iue.getMessage) + } + val k = Constant(value) + // To avoid the backlash of backslash, taken literally by Literal, escapes are processed strictly (scala/bug#11196) + treeCopy.Literal(lit, k).setType(ConstantType(k)) + case x => throw new MatchError(x) + } if (args.forall(treeInfo.isLiteralString)) { val it1 = treated.iterator @@ -88,7 +86,7 @@ trait FastStringInterpolator extends FormatInterpolator { else concatenate(treated, args) // Fallback -- inline the original implementation of the `s` or `raw` interpolator. - case t@Apply(Select(someStringContext, _interpol), args) => + case Apply(Select(someStringContext, _interpol@_), args) => q"""{ val sc = $someStringContext _root_.scala.StringContext.standardInterpolator( @@ -101,28 +99,32 @@ trait FastStringInterpolator extends FormatInterpolator { def concatenate(parts: List[Tree], args: List[Tree]): Tree = { val argsIndexed = args.toVector - val concatArgs = collection.mutable.ListBuffer[Tree]() + val concatArgs = ListBuffer.empty[Tree] val numLits = parts.length foreachWithIndex(parts.tail) { (lit, i) => val treatedContents = lit.asInstanceOf[Literal].value.stringValue val emptyLit = treatedContents.isEmpty if (i < numLits - 1) { - concatArgs += argsIndexed(i) - if (!emptyLit) concatArgs += lit - } else if (!emptyLit) { - concatArgs += lit + val arg = argsIndexed(i) + if (linting && !(arg.tpe =:= definitions.StringTpe)) + if (arg.tpe.typeSymbol eq definitions.UnitClass) + runReporting.warning(arg.pos, "interpolated Unit value", WFlagTostringInterpolated, c.internal.enclosingOwner) + else if (!definitions.isPrimitiveValueType(arg.tpe)) + runReporting.warning(arg.pos, "interpolation uses toString", WFlagTostringInterpolated, c.internal.enclosingOwner) + concatArgs += arg } + if (!emptyLit) concatArgs += lit } def mkConcat(pos: Position, lhs: Tree, rhs: Tree): Tree = atPos(pos)(gen.mkMethodCall(gen.mkAttributedSelect(lhs, definitions.String_+), rhs :: Nil)).setType(definitions.StringTpe) var result: Tree = parts.head val chunkSize = 32 - if (concatArgs.lengthCompare(chunkSize) <= 0) { + if (concatArgs.lengthCompare(chunkSize) <= 0) concatArgs.foreach { t => result = mkConcat(t.pos, result, t) } - } else { + else concatArgs.toList.grouped(chunkSize).foreach { case group => var chunkResult: Tree = Literal(Constant("")).setType(definitions.StringTpe) @@ -131,7 +133,6 @@ trait FastStringInterpolator extends FormatInterpolator { } result = mkConcat(chunkResult.pos, result, chunkResult) } - } result } diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index a1554d399253..8d5b37fd1c67 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -61,7 +61,7 @@ class FastTrack[MacrosAndAnalyzer <: Macros with Analyzer](val macros: MacrosAnd makeBlackbox( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) }, makeBlackbox( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) }, makeBlackbox( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) }, - makeBlackbox( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }, + makeBlackbox( ApiUniverseReify) { case Applied(_, _ :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }, makeWhitebox( StringContext_f) { case _ => _.interpolateF }, makeWhitebox( StringContext_s) { case _ => _.interpolateS }, makeWhitebox( StringContext_raw) { case _ => _.interpolateRaw }, diff --git a/src/compiler/scala/tools/reflect/FormatInterpolator.scala b/src/compiler/scala/tools/reflect/FormatInterpolator.scala index 614f109eb877..d4c534fbb321 100644 --- a/src/compiler/scala/tools/reflect/FormatInterpolator.scala +++ b/src/compiler/scala/tools/reflect/FormatInterpolator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,11 +12,12 @@ package scala.tools.reflect -import scala.reflect.macros.runtime.Context -import scala.collection.mutable.ListBuffer import scala.PartialFunction.cond -import scala.util.chaining._ +import scala.collection.mutable.ListBuffer +import scala.reflect.macros.runtime.Context +import scala.tools.nsc.Reporting.WarningCategory, WarningCategory.WFlagTostringInterpolated import scala.util.matching.Regex.Match +import scala.util.chaining._ import java.util.Formattable @@ -31,6 +32,14 @@ abstract class FormatInterpolator { import definitions._ import treeInfo.Applied + protected var linting = settings.warnToString.value + + protected final def withoutLinting[A](body: => A): A = { + val linted = linting + linting = false + try body finally linting = linted + } + private def bail(msg: String) = global.abort(msg) def concatenate(parts: List[Tree], args: List[Tree]): Tree @@ -87,8 +96,9 @@ abstract class FormatInterpolator { def argType(argi: Int, types: Type*): Type = { val tpe = argTypes(argi) - types.find(t => argConformsTo(argi, tpe, t)) - .orElse(types.find(t => argConvertsTo(argi, tpe, t))) + types.find(t => t != AnyTpe && argConformsTo(argi, tpe, t)) + .orElse(types.find(t => t != AnyTpe && argConvertsTo(argi, tpe, t))) + .orElse(types.find(t => t == AnyTpe && argConformsTo(argi, tpe, t))) .getOrElse { val msg = "type mismatch" + { val req = raw"required: (.*)".r.unanchored @@ -120,7 +130,7 @@ abstract class FormatInterpolator { // Check the % fields in this part. def loop(remaining: List[Tree], n: Int): Unit = remaining match { - case part0 :: more => + case part0 :: remaining => val part1 = part0 match { case Literal(Constant(x: String)) => x case _ => throw new IllegalArgumentException("internal error: argument parts must be a list of string literals") @@ -130,14 +140,17 @@ abstract class FormatInterpolator { def insertStringConversion(): Unit = { amended += "%s" + part - convert += Conversion(formatPattern.findAllMatchIn("%s").next(), part0.pos, argc) // improve - argType(n-1, AnyTpe) + val cv = Conversion(part0.pos, argc) + cv.accepts(argType(n-1, AnyTpe)) + convert += cv + cv.lintToString(argTypes(n-1)) } def errorLeading(op: Conversion) = op.errorAt(Spec)(s"conversions must follow a splice; ${Conversion.literalHelp}") def accept(op: Conversion): Unit = { if (!op.isLeading) errorLeading(op) op.accepts(argType(n-1, op.acceptableVariants: _*)) amended += part + op.lintToString(argTypes(n-1)) } if (n == 0) amended += part @@ -164,7 +177,7 @@ abstract class FormatInterpolator { else if (!cv.isLiteral && !cv.isIndexed) errorLeading(cv) formatting = true } - loop(more, n = n + 1) + loop(remaining, n = n + 1) case Nil => } loop(parts, n = 0) @@ -178,7 +191,11 @@ abstract class FormatInterpolator { val format = amended.mkString if (actuals.isEmpty && !formatting) constantly(format) else if (!reported && actuals.forall(treeInfo.isLiteralString)) constantly(format.format(actuals.map(_.asInstanceOf[Literal].value.value).toIndexedSeq: _*)) - else if (!formatting) concatenate(amended.map(p => constantly(p.stripPrefix("%s"))).toList, actuals.toList) + else if (!formatting) { + withoutLinting { // already warned + concatenate(amended.map(p => constantly(p.stripPrefix("%s"))).toList, actuals.toList) + } + } else { val scalaPackage = Select(Ident(nme.ROOTPKG), TermName("scala")) val newStringOps = Select( @@ -218,6 +235,7 @@ abstract class FormatInterpolator { case ErrorXn => op(0) case DateTimeXn if op.length > 1 => op(1) case DateTimeXn => '?' + case StringXn if op.isEmpty => 's' // accommodate the default %s case _ => op(0) } @@ -295,13 +313,19 @@ abstract class FormatInterpolator { } case _ => true } + def lintToString(arg: Type): Unit = + if (linting && kind == StringXn && !(arg =:= StringTpe)) + if (arg.typeSymbol eq UnitClass) + warningAt(CC)("interpolated Unit value", WFlagTostringInterpolated) + else if (!definitions.isPrimitiveValueType(arg)) + warningAt(CC)("interpolation uses toString", WFlagTostringInterpolated) // what arg type if any does the conversion accept def acceptableVariants: List[Type] = kind match { case StringXn if hasFlag('#') => FormattableTpe :: Nil case StringXn => AnyTpe :: Nil - case BooleanXn => BooleanTpe :: NullTpe :: Nil + case BooleanXn => BooleanTpe :: NullTpe :: AnyTpe :: Nil // warn if not boolean case HashXn => AnyTpe :: Nil case CharacterXn => CharTpe :: ByteTpe :: ShortTpe :: IntTpe :: Nil case IntegralXn => IntTpe :: LongTpe :: ByteTpe :: ShortTpe :: BigIntTpe :: Nil @@ -331,7 +355,7 @@ abstract class FormatInterpolator { def groupPosAt(g: SpecGroup, i: Int) = pos.withPoint(pos.point + descriptor.offset(g, i)) def errorAt(g: SpecGroup, i: Int = 0)(msg: String) = c.error(groupPosAt(g, i), msg).tap(_ => reported = true) - def warningAt(g: SpecGroup, i: Int = 0)(msg: String) = c.warning(groupPosAt(g, i), msg) + def warningAt(g: SpecGroup, i: Int = 0)(msg: String, cat: WarningCategory = WarningCategory.Other) = c.callsiteTyper.context.warning(groupPosAt(g, i), msg, cat, Nil) } object Conversion { @@ -356,6 +380,9 @@ abstract class FormatInterpolator { case None => new Conversion(m, p, ErrorXn, argc).tap(_.errorAt(Spec)(s"Missing conversion operator in '${m.matched}'; $literalHelp")) } } + // construct a default %s conversion + def apply(p: Position, argc: Int): Conversion = + new Conversion(formatPattern.findAllMatchIn("%").next(), p, StringXn, argc) val literalHelp = "use %% for literal %, %n for newline" } diff --git a/src/compiler/scala/tools/reflect/FrontEnd.scala b/src/compiler/scala/tools/reflect/FrontEnd.scala index b86668d4795e..4bf42f38d039 100644 --- a/src/compiler/scala/tools/reflect/FrontEnd.scala +++ b/src/compiler/scala/tools/reflect/FrontEnd.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala index 5fd6b2d310fb..fe0c552e08de 100644 --- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala +++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/ReflectMain.scala b/src/compiler/scala/tools/reflect/ReflectMain.scala index a290c6bfafc8..659f2344b5f3 100644 --- a/src/compiler/scala/tools/reflect/ReflectMain.scala +++ b/src/compiler/scala/tools/reflect/ReflectMain.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/ReflectSetup.scala b/src/compiler/scala/tools/reflect/ReflectSetup.scala index 8e97a78439f8..6d2b0130f7fb 100644 --- a/src/compiler/scala/tools/reflect/ReflectSetup.scala +++ b/src/compiler/scala/tools/reflect/ReflectSetup.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala index db4c386a9189..501e2170f262 100644 --- a/src/compiler/scala/tools/reflect/StdTags.scala +++ b/src/compiler/scala/tools/reflect/StdTags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala index fa77e7341c4c..8caff3b6d5ae 100644 --- a/src/compiler/scala/tools/reflect/ToolBox.scala +++ b/src/compiler/scala/tools/reflect/ToolBox.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index a5a38edaf257..b7bc8c5597f7 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -200,7 +200,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => transformDuringTyper(tree, TERMmode, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)( (currentTyper, tree) => { trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, printOwners = settings.Yshowsymowners.value, printKinds = settings.Yshowsymkinds.value)) - analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg)) + analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (_, msg) => throw ToolBoxError(msg)) }) private def wrapInPackageAndCompile(packageName: TermName, tree: ImplDef): Symbol = { diff --git a/src/compiler/scala/tools/reflect/WrappedProperties.scala b/src/compiler/scala/tools/reflect/WrappedProperties.scala index 76caefb3c597..022ff46ea3e8 100644 --- a/src/compiler/scala/tools/reflect/WrappedProperties.scala +++ b/src/compiler/scala/tools/reflect/WrappedProperties.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala index a9ee6324a388..1e85a08e19c2 100644 --- a/src/compiler/scala/tools/reflect/package.scala +++ b/src/compiler/scala/tools/reflect/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/AttributeUnpickler.scala b/src/compiler/scala/tools/tasty/AttributeUnpickler.scala index 33add75cca96..265fc89f1cc3 100644 --- a/src/compiler/scala/tools/tasty/AttributeUnpickler.scala +++ b/src/compiler/scala/tools/tasty/AttributeUnpickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/Attributes.scala b/src/compiler/scala/tools/tasty/Attributes.scala index 89ac1e53562f..eb3c3493af49 100644 --- a/src/compiler/scala/tools/tasty/Attributes.scala +++ b/src/compiler/scala/tools/tasty/Attributes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/ErasedTypeRef.scala b/src/compiler/scala/tools/tasty/ErasedTypeRef.scala index b102183350a4..cc8f4690b3f2 100644 --- a/src/compiler/scala/tools/tasty/ErasedTypeRef.scala +++ b/src/compiler/scala/tools/tasty/ErasedTypeRef.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/Signature.scala b/src/compiler/scala/tools/tasty/Signature.scala index e52bb11bb627..e7613ed5cce4 100644 --- a/src/compiler/scala/tools/tasty/Signature.scala +++ b/src/compiler/scala/tools/tasty/Signature.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/TastyFlags.scala b/src/compiler/scala/tools/tasty/TastyFlags.scala index 11ea500345df..b51636c1b7f4 100644 --- a/src/compiler/scala/tools/tasty/TastyFlags.scala +++ b/src/compiler/scala/tools/tasty/TastyFlags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -60,6 +60,7 @@ object TastyFlags { final val ParamAlias = Open.next final val Infix = ParamAlias.next final val Invisible = Infix.next + final val Tracked = Invisible.next def optFlag(cond: Boolean)(flag: TastyFlagSet): TastyFlagSet = if (cond) flag else EmptyTastyFlags @@ -125,6 +126,7 @@ object TastyFlags { if (is(ParamAlias)) sb += "ParamAlias" if (is(Infix)) sb += "Infix" if (is(Invisible)) sb += "Invisible" + if (is(Tracked)) sb += "Tracked" sb.mkString(" | ") } } diff --git a/src/compiler/scala/tools/tasty/TastyFormat.scala b/src/compiler/scala/tools/tasty/TastyFormat.scala index 45fe8e9b1dc4..95092da86fda 100644 --- a/src/compiler/scala/tools/tasty/TastyFormat.scala +++ b/src/compiler/scala/tools/tasty/TastyFormat.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.tasty -// revision: https://github.com/lampepfl/dotty/commit/0938fe5603a17c7c786ac8fc6118a9d5d8b257de +// revision: https://github.com/scala/scala3/commit/24bff2a019afcf0f45ddfd3af6b213e7e228471c object TastyFormat { /** The first four bytes of a TASTy file, followed by four values: @@ -34,9 +34,9 @@ object TastyFormat { /** Natural number. Each increment of the `MinorVersion`, within * a series declared by the `MajorVersion`, breaks forward * compatibility, but remains backwards compatible, with all - * preceeding `MinorVersion`. + * preceding `MinorVersion`. */ - final val MinorVersion: Int = 4 + final val MinorVersion: Int = 6 /** Natural Number. The `ExperimentalVersion` allows for * experimentation with changes to TASTy without committing @@ -222,6 +222,7 @@ object TastyFormat { final val INVISIBLE = 44 final val EMPTYCLAUSE = 45 final val SPLITCLAUSE = 46 + final val TRACKED = 47 // Tree Cat. 2: tag Nat final val firstNatTreeTag = SHAREDterm @@ -261,7 +262,6 @@ object TastyFormat { final val EXPLICITtpt = 103 final val ELIDED = 104 - // Tree Cat. 4: tag Nat AST final val firstNatASTTreeTag = IDENT final val IDENT = 110 @@ -327,14 +327,17 @@ object TastyFormat { final val TYPEREFin = 175 final val SELECTin = 176 final val EXPORT = 177 - // final val ??? = 178 - // final val ??? = 179 + final val QUOTE = 178 + final val SPLICE = 179 final val METHODtype = 180 final val APPLYsigpoly = 181 + final val QUOTEPATTERN = 182 + final val SPLICEPATTERN = 183 final val MATCHtype = 190 final val MATCHtpt = 191 final val MATCHCASEtype = 192 + final val FLEXIBLEtype = 193 final val HOLE = 255 @@ -366,7 +369,7 @@ object TastyFormat { firstNatTreeTag <= tag && tag <= RENAMED || firstASTTreeTag <= tag && tag <= BOUNDED || firstNatASTTreeTag <= tag && tag <= NAMEDARG || - firstLengthTreeTag <= tag && tag <= MATCHCASEtype || + firstLengthTreeTag <= tag && tag <= FLEXIBLEtype || tag == HOLE def isParamTag(tag: Int): Boolean = tag == PARAM || tag == TYPEPARAM @@ -411,7 +414,8 @@ object TastyFormat { | INVISIBLE | ANNOTATION | PRIVATEqualified - | PROTECTEDqualified => true + | PROTECTEDqualified + | TRACKED => true case _ => false } @@ -568,11 +572,16 @@ object TastyFormat { case MATCHCASEtype => "MATCHCASEtype" case MATCHtpt => "MATCHtpt" case PARAMtype => "PARAMtype" + case FLEXIBLEtype => "FLEXIBLEtype" case ANNOTATION => "ANNOTATION" case PRIVATEqualified => "PRIVATEqualified" case PROTECTEDqualified => "PROTECTEDqualified" case EXPLICITtpt => "EXPLICITtpt" case ELIDED => "ELIDED" + case QUOTE => "QUOTE" + case SPLICE => "SPLICE" + case QUOTEPATTERN => "QUOTEPATTERN" + case SPLICEPATTERN => "SPLICEPATTERN" case HOLE => "HOLE" } diff --git a/src/compiler/scala/tools/tasty/TastyHeaderUnpickler.scala b/src/compiler/scala/tools/tasty/TastyHeaderUnpickler.scala index 8552d2206b40..40b20623dc9f 100644 --- a/src/compiler/scala/tools/tasty/TastyHeaderUnpickler.scala +++ b/src/compiler/scala/tools/tasty/TastyHeaderUnpickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/TastyName.scala b/src/compiler/scala/tools/tasty/TastyName.scala index e69e42b33c1c..1b84656078ea 100644 --- a/src/compiler/scala/tools/tasty/TastyName.scala +++ b/src/compiler/scala/tools/tasty/TastyName.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/TastyReader.scala b/src/compiler/scala/tools/tasty/TastyReader.scala index bea539f60e41..1ea12df2dbad 100644 --- a/src/compiler/scala/tools/tasty/TastyReader.scala +++ b/src/compiler/scala/tools/tasty/TastyReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/TastyRefs.scala b/src/compiler/scala/tools/tasty/TastyRefs.scala index d4362eb89345..dc515b9317f7 100644 --- a/src/compiler/scala/tools/tasty/TastyRefs.scala +++ b/src/compiler/scala/tools/tasty/TastyRefs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/tasty/TastyVersion.scala b/src/compiler/scala/tools/tasty/TastyVersion.scala index 192053b81f60..65eb5e2f4a0b 100644 --- a/src/compiler/scala/tools/tasty/TastyVersion.scala +++ b/src/compiler/scala/tools/tasty/TastyVersion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,7 +12,7 @@ package scala.tools.tasty -// sourced from: https://github.com/lampepfl/dotty/blob/release-3.4.0/tasty/src/dotty/tools/tasty/TastyVersion.scala +// sourced from: https://github.com/scala/scala3/blob/release-3.4.0/tasty/src/dotty/tools/tasty/TastyVersion.scala case class TastyVersion private(major: Int, minor: Int, experimental: Int) { def isExperimental: Boolean = experimental > 0 diff --git a/src/compiler/scala/tools/tasty/UnpickleException.scala b/src/compiler/scala/tools/tasty/UnpickleException.scala index cf632d6bdf75..b385c4635065 100644 --- a/src/compiler/scala/tools/tasty/UnpickleException.scala +++ b/src/compiler/scala/tools/tasty/UnpickleException.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala index e37ac5b74884..e1541a4ec44a 100644 --- a/src/compiler/scala/tools/util/PathResolver.scala +++ b/src/compiler/scala/tools/util/PathResolver.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -270,7 +270,7 @@ final class PathResolver(settings: Settings, closeableRegistry: CloseableRegistr sourcesInPath(sourcePath) // 7. The Scala source path. ) - private def jrt: List[ClassPath] = JrtClassPath.apply(settings.releaseValue, settings.unsafe.valueSetByUser, closeableRegistry) + private def jrt: List[ClassPath] = JrtClassPath.apply(settings.releaseValue, settings.systemPathValue, settings.unsafe.valueSetByUser, closeableRegistry) lazy val containers = basis.flatten.distinct @@ -295,12 +295,12 @@ final class PathResolver(settings: Settings, closeableRegistry: CloseableRegistr def result: ClassPath = { val cp = computeResult() if (settings.Ylogcp.value) { - Console print f"Classpath built from ${settings.toConciseString} %n" - Console print s"Defaults: ${PathResolver.Defaults}" - Console print s"Calculated: $Calculated" + Console.print(f"Classpath built from ${settings.toConciseString} %n") + Console.print(s"Defaults: ${PathResolver.Defaults}") + Console.print(s"Calculated: $Calculated") - val xs = (Calculated.basis drop 2).flatten.distinct - Console print (xs mkLines (s"After java boot/extdirs classpath has ${xs.size} entries:", indented = true)) + val xs = Calculated.basis.drop(2).flatten.distinct + Console.print(xs.mkLines(s"After java boot/extdirs classpath has ${xs.size} entries:", indented = true)) } cp } diff --git a/src/compiler/scala/tools/util/SystemExit.scala b/src/compiler/scala/tools/util/SystemExit.scala index ac8259a99776..f74d66da7c30 100644 --- a/src/compiler/scala/tools/util/SystemExit.scala +++ b/src/compiler/scala/tools/util/SystemExit.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/scala/tools/util/VerifyClass.scala b/src/compiler/scala/tools/util/VerifyClass.scala index dae86406a132..2eb59c24ab5d 100644 --- a/src/compiler/scala/tools/util/VerifyClass.scala +++ b/src/compiler/scala/tools/util/VerifyClass.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/templates/tool-unix.tmpl b/src/compiler/templates/tool-unix.tmpl index 31f736f45c86..1a610fd1e5e8 100755 --- a/src/compiler/templates/tool-unix.tmpl +++ b/src/compiler/templates/tool-unix.tmpl @@ -3,7 +3,7 @@ ############################################################################## # Scala (https://www.scala-lang.org) # -# Copyright EPFL and Lightbend, Inc. +# Copyright EPFL and Lightbend, Inc. dba Akka # # Licensed under Apache License 2.0 # (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/compiler/templates/tool-windows.tmpl b/src/compiler/templates/tool-windows.tmpl index cf2c963b2a0a..901e9a1a5c8a 100644 --- a/src/compiler/templates/tool-windows.tmpl +++ b/src/compiler/templates/tool-windows.tmpl @@ -3,7 +3,7 @@ rem ########################################################################## rem # Scala (https://www.scala-lang.org) rem # -rem # Copyright EPFL and Lightbend, Inc. +rem # Copyright EPFL and Lightbend, Inc. dba Akka rem # rem # Licensed under Apache License 2.0 rem # (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/intellij/scala.ipr.SAMPLE b/src/intellij/scala.ipr.SAMPLE index 11bf2dd91baf..fc16122f8e43 100644 --- a/src/intellij/scala.ipr.SAMPLE +++ b/src/intellij/scala.ipr.SAMPLE @@ -14,7 +14,7 @@ - @@ -229,11 +229,10 @@ - - - + + @@ -243,18 +242,16 @@ - - - + + - - - + + @@ -263,11 +260,10 @@ - - - + + @@ -284,11 +280,10 @@ - - - + + @@ -296,25 +291,23 @@ - + - - - + + - - - + + @@ -348,7 +341,6 @@ - @@ -366,8 +358,7 @@ - - + @@ -446,10 +437,9 @@ - - - + + @@ -457,9 +447,8 @@ - - - + + @@ -467,9 +456,8 @@ - - - + + @@ -480,8 +468,7 @@ - - + @@ -494,14 +481,12 @@ - - - - + + - + @@ -511,11 +496,10 @@ - - - + + @@ -524,9 +508,8 @@ - - - + + diff --git a/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala index 2a38319e11bd..a988528b013d 100644 --- a/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/ContextTrees.scala b/src/interactive/scala/tools/nsc/interactive/ContextTrees.scala index f22af8ce6046..43fa50776aec 100644 --- a/src/interactive/scala/tools/nsc/interactive/ContextTrees.scala +++ b/src/interactive/scala/tools/nsc/interactive/ContextTrees.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 36f368f67066..1daf9b72960f 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -21,7 +21,6 @@ import scala.collection.mutable import scala.collection.mutable.{HashSet, LinkedHashMap} import scala.jdk.javaapi.CollectionConverters import scala.language.implicitConversions -import scala.reflect.internal.Chars.isIdentifierStart import scala.reflect.internal.util.SourceFile import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.reporters.Reporter @@ -51,6 +50,7 @@ trait InteractiveAnalyzer extends Analyzer { override def newNamer(context: Context): InteractiveNamer = new Namer(context) with InteractiveNamer trait InteractiveTyper extends Typer { + override def isInteractive = true override def canAdaptConstantTypeToLiteral = false override def canTranslateEmptyListToNil = false override def missingSelectErrorTree(tree: Tree, qual: Tree, name: Name): Tree = tree match { @@ -403,8 +403,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") case unit: RichCompilationUnit => unit.isParsed case _ => true }) - if (isPastNamer) super.openPackageModule(pkgClass, force = true) - else analyzer.packageObjects.deferredOpen.add(pkgClass) + super.openPackageModule(pkgClass, force = isPastNamer) } // ----------------- Polling --------------------------------------- @@ -1010,7 +1009,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") def add(sym: Symbol, pre: Type, implicitlyAdded: Boolean)(toMember: (Symbol, Type) => M): Unit = { if ((sym.isGetter || sym.isSetter) && sym.accessed != NoSymbol) { add(sym.accessed, pre, implicitlyAdded)(toMember) - } else if (!sym.name.decodedName.containsName("$") && !sym.isError && !sym.isArtifact && sym.hasRawInfo) { + } else if (!sym.isError && !sym.isArtifact && sym.hasRawInfo && !sym.isDefaultGetter && !sym.isMixinConstructor) { val symtpe = pre.memberType(sym) onTypeError ErrorType matching(sym, symtpe, this(sym.name)) match { case Some(m) => @@ -1190,7 +1189,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") results.filter { (member: Member) => val symbol = member.sym def isStable = member.tpe.isStable || member.sym.isStable || member.sym.getterIn(member.sym.owner).isStable - def isJunk = !symbol.exists || symbol.name.isEmpty || !isIdentifierStart(member.sym.name.charAt(0)) // e.g. + def isJunk = !symbol.exists || symbol.name.isEmpty || symbol.encodedName.charAt(0) == '<' // e.g. def nameTypeOk: Boolean = { forImport || // Completing an import: keep terms and types. symbol.name.isTermName == name.isTermName || // Keep names of the same type @@ -1201,7 +1200,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") matcher(member.aliasInfo.map(_.sym.name).getOrElse(NoSymbol.name)) && !forImport && symbol.name.isTermName == name.isTermName } - !isJunk && member.accessible && !symbol.isConstructor && (name.isEmpty || (matcher(member.sym.name) || aliasTypeOk) + !isJunk && member.accessible && (name.isEmpty || (matcher(member.sym.name) || aliasTypeOk) && nameTypeOk) } @@ -1269,20 +1268,16 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") typeCompletions(imp, qual, selector.namePos, selector.name) } case sel@Select(qual, name) => - val qualPos = qual.pos - val effectiveQualEnd = if (qualPos.isRange) qualPos.end else qualPos.point - 1 - def fallback = { - effectiveQualEnd + 2 - } - val source = pos.source - - val nameStart: Int = (focus1.pos.end - 1 to effectiveQualEnd by -1).find(p => - source.identFrom(source.position(p)).exists(_.length == 0) - ).map(_ + 1).getOrElse(fallback) + val rawNameStart: Int = sel.pos.point + val hasBackTick = pos.source.content.lift(rawNameStart).contains('`') + val nameStart = if (hasBackTick) rawNameStart + 1 else rawNameStart typeCompletions(sel, qual, nameStart, name) - case Ident(name) => + case ident@Ident(name) => val allMembers = scopeMembers(pos) - val positionDelta: Int = pos.start - focus1.pos.start + val rawNameStart: Int = ident.pos.point + val hasBackTick = pos.source.content.lift(rawNameStart).contains('`') + val nameStart = if (hasBackTick) rawNameStart + 1 else rawNameStart + val positionDelta: Int = pos.start - nameStart val subName = name.subName(0, positionDelta) CompletionResult.ScopeMembers(positionDelta, scopeMemberFlatten(allMembers), subName, forImport = false) case _ => diff --git a/src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala b/src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala index 1bbc308cd567..159fdf536fd2 100644 --- a/src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala +++ b/src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/Lexer.scala b/src/interactive/scala/tools/nsc/interactive/Lexer.scala index 5c787da107a1..f1ac87b6ce6c 100644 --- a/src/interactive/scala/tools/nsc/interactive/Lexer.scala +++ b/src/interactive/scala/tools/nsc/interactive/Lexer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/Main.scala b/src/interactive/scala/tools/nsc/interactive/Main.scala index 9d05766e7a1b..555e80a3cc18 100644 --- a/src/interactive/scala/tools/nsc/interactive/Main.scala +++ b/src/interactive/scala/tools/nsc/interactive/Main.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/Pickler.scala b/src/interactive/scala/tools/nsc/interactive/Pickler.scala index 1bbf35e50696..cfd6094e56a1 100644 --- a/src/interactive/scala/tools/nsc/interactive/Pickler.scala +++ b/src/interactive/scala/tools/nsc/interactive/Pickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -212,7 +212,7 @@ object Pickler { /** Same as `p ~ q` */ - def seqPickler[T, U](p: Pickler[T], q: => Pickler[U]) = new Pickler[T ~ U] { + def seqPickler[T, U](p: Pickler[T], q: => Pickler[U]): Pickler[T ~ U] = new Pickler[T ~ U] { lazy val qq = q def pickle(wr: Writer, x: T ~ U) = { p.pickle(wr, x.fst) @@ -226,7 +226,7 @@ object Pickler { /** Same as `p | q` */ - def eitherPickler[T, U <: T, V <: T](p: CondPickler[U], q: => CondPickler[V]) = + def eitherPickler[T, U <: T, V <: T](p: CondPickler[U], q: => CondPickler[V]): CondPickler[T] = new CondPickler[T](x => p.canPickle(x) || q.canPickle(x)) { lazy val qq = q override def tryPickle(wr: Writer, x: Any): Boolean = diff --git a/src/interactive/scala/tools/nsc/interactive/Picklers.scala b/src/interactive/scala/tools/nsc/interactive/Picklers.scala index 6862fd098e52..779552a760a8 100644 --- a/src/interactive/scala/tools/nsc/interactive/Picklers.scala +++ b/src/interactive/scala/tools/nsc/interactive/Picklers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala b/src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala index 1096e726c77d..47d42e8d79b3 100644 --- a/src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala +++ b/src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/PrettyWriter.scala b/src/interactive/scala/tools/nsc/interactive/PrettyWriter.scala index ee0166ffdeaf..b93ad752c9e9 100644 --- a/src/interactive/scala/tools/nsc/interactive/PrettyWriter.scala +++ b/src/interactive/scala/tools/nsc/interactive/PrettyWriter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/REPL.scala b/src/interactive/scala/tools/nsc/interactive/REPL.scala index 19d8d166f6da..d1ef21c3e235 100644 --- a/src/interactive/scala/tools/nsc/interactive/REPL.scala +++ b/src/interactive/scala/tools/nsc/interactive/REPL.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/RangePositions.scala b/src/interactive/scala/tools/nsc/interactive/RangePositions.scala index 2686ab337947..f0052def43a8 100644 --- a/src/interactive/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/interactive/scala/tools/nsc/interactive/RangePositions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/Replayer.scala b/src/interactive/scala/tools/nsc/interactive/Replayer.scala index 3f5a30f78a64..fcba21ca7f56 100644 --- a/src/interactive/scala/tools/nsc/interactive/Replayer.scala +++ b/src/interactive/scala/tools/nsc/interactive/Replayer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/Response.scala b/src/interactive/scala/tools/nsc/interactive/Response.scala index 5df96f440ea5..fc09c87ae1d9 100644 --- a/src/interactive/scala/tools/nsc/interactive/Response.scala +++ b/src/interactive/scala/tools/nsc/interactive/Response.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala b/src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala index 2018213be929..21a1457623e9 100644 --- a/src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala +++ b/src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala index e05bb50fba75..6d31a7c869ab 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -86,9 +86,10 @@ abstract class InteractiveTest loadSources() runDefaultTests() } - }.linesIterator.map(normalize).foreach(println) + }.linesIterator.filterNot(filterOutLines).map(normalize).foreach(println) } + protected def filterOutLines(line: String) = false protected def normalize(s: String) = s /** Load all sources before executing the test. */ diff --git a/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala index 640dfd74440e..6b01262615e5 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/Tester.scala b/src/interactive/scala/tools/nsc/interactive/tests/Tester.scala index 762fe9f173ec..3942994333b4 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/Tester.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/Tester.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala index 827545a08404..662b158aee7e 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala index e1f201533148..b7ae411be9be 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala index a389da1ec44d..7b5041225c11 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala index f06bd2553a93..ff21713b8122 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala index 3d4be0e5bac8..75100c838f2d 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala index b44e275ba53f..e0e583b597c4 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala index c92d220ae270..69aae26aecaa 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala index abff3bf97869..066d55951cd8 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala index 2ed17bbc8051..f82b5ea53304 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala index b0626afa60dc..480fcb6a08f2 100644 --- a/src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library-aux/scala/Any.scala b/src/library-aux/scala/Any.scala index d514aea60a2f..bfef6f23cb4b 100644 --- a/src/library-aux/scala/Any.scala +++ b/src/library-aux/scala/Any.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,7 +15,6 @@ package scala /** Class `Any` is the root of the Scala class hierarchy. Every class in a Scala * execution environment inherits directly or indirectly from this class. * - * Starting with Scala 2.10 it is possible to directly extend `Any` using ''universal traits''. * A ''universal trait'' is a trait that extends `Any`, only has `def`s as members, and does no initialization. * * The main use case for universal traits is to allow basic inheritance of methods for [[scala.AnyVal value classes]]. @@ -129,7 +128,7 @@ abstract class Any { * will return true for any value of `x`. * * This is exactly equivalent to the type pattern `_: T0` - * + * * @note due to the unexpectedness of `List(1, 2, 3).isInstanceOf[List[String]]` returning true and * `x.isInstanceOf[A]` where `A` is a type parameter or abstract member returning true, * these forms issue a warning. @@ -138,15 +137,36 @@ abstract class Any { */ final def isInstanceOf[T0]: Boolean = sys.error("isInstanceOf") - /** Cast the receiver object to be of type `T0`. - * - * Note that the success of a cast at runtime is modulo Scala's erasure semantics. - * Therefore the expression `1.asInstanceOf[String]` will throw a `ClassCastException` at - * runtime, while the expression `List(1).asInstanceOf[List[String]]` will not. - * In the latter example, because the type argument is erased as part of compilation it is - * not possible to check whether the contents of the list are of the requested type. - * - * @throws ClassCastException if the receiver object is not an instance of the erasure of type `T0`. + /** Forces the compiler to treat the receiver object as having type `T0`, + * even though doing so may violate type safety. + * + * This method is useful when you believe you have type information the compiler doesn't, + * and it also isn't possible to check the type at runtime. + * In such situations, skipping type safety is the only option. + * + * It is platform dependent whether `asInstanceOf` has any effect at runtime. + * It might do a runtime type test on the erasure of `T0`, + * insert a conversion (such as boxing/unboxing), fill in a default value, or do nothing at all. + * + * In particular, `asInstanceOf` is not a type test. It does **not** mean: + * {{{ + * this match { + * case x: T0 => x + * case _ => throw ClassCastException("...") + * }}} + * Use pattern matching or [[isInstanceOf]] for type testing instead. + * + * Situations where `asInstanceOf` is useful: + * - when flow analysis fails to deduce `T0` automatically + * - when down-casting a type parameter or an abstract type member (which cannot be checked at runtime due to type erasure) + * If there is any doubt and you are able to type test instead, you should do so. + * + * Be careful of using `asInstanceOf` when `T0` is a primitive type. + * When `T0` is primitive, `asInstanceOf` may insert a conversion instead of a type test. + * If your intent is to convert, use a `toT` method (`x.toChar`, `x.toByte`, etc.). + * + * @throws ClassCastException if the receiver is not an instance of the erasure of `T0`, + * if that can be checked on this platform * @return the receiver object. */ final def asInstanceOf[T0]: T0 = sys.error("asInstanceOf") diff --git a/src/library-aux/scala/AnyRef.scala b/src/library-aux/scala/AnyRef.scala index c2be72a5ac27..d0d87d35c40b 100644 --- a/src/library-aux/scala/AnyRef.scala +++ b/src/library-aux/scala/AnyRef.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library-aux/scala/Nothing.scala b/src/library-aux/scala/Nothing.scala index d52353e3f314..b2f905fe0f39 100644 --- a/src/library-aux/scala/Nothing.scala +++ b/src/library-aux/scala/Nothing.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library-aux/scala/Null.scala b/src/library-aux/scala/Null.scala index 8d40134fa554..1bbf78ebdfd7 100644 --- a/src/library-aux/scala/Null.scala +++ b/src/library-aux/scala/Null.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library-aux/scala/Singleton.scala b/src/library-aux/scala/Singleton.scala index 3855eddfe0fb..5f444937b020 100644 --- a/src/library-aux/scala/Singleton.scala +++ b/src/library-aux/scala/Singleton.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala index 018c388e9228..79be48d642be 100644 --- a/src/library/scala/AnyVal.scala +++ b/src/library/scala/AnyVal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -29,9 +29,8 @@ package scala * - The ''integer types'' include the subrange types as well as [[scala.Int]] and [[scala.Long]]. * - The ''floating point types'' are [[scala.Float]] and [[scala.Double]]. * - * Prior to Scala 2.10, `AnyVal` was a sealed trait. Beginning with Scala 2.10, - * however, it is possible to define a subclass of `AnyVal` called a ''user-defined value class'' - * which is treated specially by the compiler. Properly-defined user value classes provide a way + * A subclass of `AnyVal` is called a ''user-defined value class'' + * and is treated specially by the compiler. Properly-defined user value classes provide a way * to improve performance on user-defined types by avoiding object allocation at runtime, and by * replacing virtual method invocations with static method invocations. * diff --git a/src/library/scala/AnyValCompanion.scala b/src/library/scala/AnyValCompanion.scala index 968422915d9b..2bb8584f8bac 100644 --- a/src/library/scala/AnyValCompanion.scala +++ b/src/library/scala/AnyValCompanion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/App.scala b/src/library/scala/App.scala index 3813ddace43c..896cf8d9b22e 100644 --- a/src/library/scala/App.scala +++ b/src/library/scala/App.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 6544548efdec..02af1837e1b7 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -54,7 +54,7 @@ object Array { /** * Returns a new [[scala.collection.mutable.ArrayBuilder]]. */ - def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T](t) + def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T](using t) /** Build an array from the iterable collection. * @@ -106,7 +106,9 @@ object Array { */ def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int): Unit = { val srcClass = src.getClass - if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) + val destClass = dest.getClass + if (srcClass.isArray && ((destClass eq srcClass) || + (destClass.isArray && !srcClass.getComponentType.isPrimitive && !destClass.getComponentType.isPrimitive))) java.lang.System.arraycopy(src, srcPos, dest, destPos, length) else slowcopy(src, srcPos, dest, destPos, length) @@ -122,16 +124,16 @@ object Array { * @see `java.util.Arrays#copyOf` */ def copyOf[A](original: Array[A], newLength: Int): Array[A] = ((original: @unchecked) match { - case x: Array[BoxedUnit] => newUnitArray(newLength).asInstanceOf[Array[A]] - case x: Array[AnyRef] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Int] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Double] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Long] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Float] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Char] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Byte] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Short] => java.util.Arrays.copyOf(x, newLength) - case x: Array[Boolean] => java.util.Arrays.copyOf(x, newLength) + case original: Array[BoxedUnit] => newUnitArray(newLength).asInstanceOf[Array[A]] + case original: Array[AnyRef] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Int] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Double] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Long] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Float] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Char] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Byte] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Short] => java.util.Arrays.copyOf(original, newLength) + case original: Array[Boolean] => java.util.Arrays.copyOf(original, newLength) }).asInstanceOf[Array[A]] /** Copy one array to another, truncating or padding with default values (if diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala index a208f863346f..ea8a2e37cda9 100644 --- a/src/library/scala/Boolean.scala +++ b/src/library/scala/Boolean.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala index f8f9af10083b..1f32d4d0bca1 100644 --- a/src/library/scala/Byte.scala +++ b/src/library/scala/Byte.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala index 6a5ecc1f55b3..52871422a39e 100644 --- a/src/library/scala/Char.scala +++ b/src/library/scala/Char.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Console.scala b/src/library/scala/Console.scala index 9232cc2fb995..82e5ac10413e 100644 --- a/src/library/scala/Console.scala +++ b/src/library/scala/Console.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/DelayedInit.scala b/src/library/scala/DelayedInit.scala index 1a4c350209d4..924d405d6c9d 100644 --- a/src/library/scala/DelayedInit.scala +++ b/src/library/scala/DelayedInit.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala index 724d3dee3755..84d9f31daa90 100644 --- a/src/library/scala/Double.scala +++ b/src/library/scala/Double.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/DummyImplicit.scala b/src/library/scala/DummyImplicit.scala index 23e7572b5ab7..07e7acfc6ebb 100644 --- a/src/library/scala/DummyImplicit.scala +++ b/src/library/scala/DummyImplicit.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Dynamic.scala b/src/library/scala/Dynamic.scala index 1fa6403cf028..f80df3e49b7d 100644 --- a/src/library/scala/Dynamic.scala +++ b/src/library/scala/Dynamic.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -30,7 +30,7 @@ package scala * foo.arr(10) ~~> foo.applyDynamic("arr")(10) * }}} * - * As of Scala 2.10, defining direct or indirect subclasses of this trait + * Defining direct or indirect subclasses of this trait * is only possible if the language feature `dynamics` is enabled. */ trait Dynamic extends Any diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 831ad8682fcc..bf61198f7d3b 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Equals.scala b/src/library/scala/Equals.scala index 03c4a90dd54e..0c35742a6746 100644 --- a/src/library/scala/Equals.scala +++ b/src/library/scala/Equals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index 4170a8a6600a..c63620ed8d53 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function.scala b/src/library/scala/Function.scala index e8b5b59af359..be612752552e 100644 --- a/src/library/scala/Function.scala +++ b/src/library/scala/Function.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index 18ad3252fa76..0cdea05ebc05 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index 5fb525756e19..10d366303ab2 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function10.scala b/src/library/scala/Function10.scala index cc01749a15fa..59192bf8ee7d 100644 --- a/src/library/scala/Function10.scala +++ b/src/library/scala/Function10.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function11.scala b/src/library/scala/Function11.scala index 33e6276c8c31..10b1509bf369 100644 --- a/src/library/scala/Function11.scala +++ b/src/library/scala/Function11.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function12.scala b/src/library/scala/Function12.scala index f872a2f19d35..08d962583108 100644 --- a/src/library/scala/Function12.scala +++ b/src/library/scala/Function12.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function13.scala b/src/library/scala/Function13.scala index ec5a5a4171ea..971368c1d467 100644 --- a/src/library/scala/Function13.scala +++ b/src/library/scala/Function13.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function14.scala b/src/library/scala/Function14.scala index 2d780e0b4f12..c0b72feef42c 100644 --- a/src/library/scala/Function14.scala +++ b/src/library/scala/Function14.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function15.scala b/src/library/scala/Function15.scala index 606546d3e06d..67c7e1dc470a 100644 --- a/src/library/scala/Function15.scala +++ b/src/library/scala/Function15.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function16.scala b/src/library/scala/Function16.scala index a3779e5a6f7f..8ea8dec9b117 100644 --- a/src/library/scala/Function16.scala +++ b/src/library/scala/Function16.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function17.scala b/src/library/scala/Function17.scala index ffe752aced8c..bc157115963d 100644 --- a/src/library/scala/Function17.scala +++ b/src/library/scala/Function17.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function18.scala b/src/library/scala/Function18.scala index 6d900a2aab6c..d8ff8db313c6 100644 --- a/src/library/scala/Function18.scala +++ b/src/library/scala/Function18.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function19.scala b/src/library/scala/Function19.scala index 821f591a388e..9d79b5c2d7c1 100644 --- a/src/library/scala/Function19.scala +++ b/src/library/scala/Function19.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index 8641b232d135..f30d57e49344 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function20.scala b/src/library/scala/Function20.scala index 988548f2eb84..1ed5e55a1616 100644 --- a/src/library/scala/Function20.scala +++ b/src/library/scala/Function20.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function21.scala b/src/library/scala/Function21.scala index db38182dad8f..4c81489ec323 100644 --- a/src/library/scala/Function21.scala +++ b/src/library/scala/Function21.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function22.scala b/src/library/scala/Function22.scala index 8baafdd0579a..c3911f34c08e 100644 --- a/src/library/scala/Function22.scala +++ b/src/library/scala/Function22.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function3.scala b/src/library/scala/Function3.scala index 0b3cccb4ea30..77c1a8f38541 100644 --- a/src/library/scala/Function3.scala +++ b/src/library/scala/Function3.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function4.scala b/src/library/scala/Function4.scala index 0c8e64314b08..f68164cf2727 100644 --- a/src/library/scala/Function4.scala +++ b/src/library/scala/Function4.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function5.scala b/src/library/scala/Function5.scala index a90dfe28e110..b5c347f5ee30 100644 --- a/src/library/scala/Function5.scala +++ b/src/library/scala/Function5.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function6.scala b/src/library/scala/Function6.scala index ae42ce2be7db..784a51f61e59 100644 --- a/src/library/scala/Function6.scala +++ b/src/library/scala/Function6.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function7.scala b/src/library/scala/Function7.scala index 5bbdf6bda38b..07c90bfd91d3 100644 --- a/src/library/scala/Function7.scala +++ b/src/library/scala/Function7.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function8.scala b/src/library/scala/Function8.scala index 6c1019dc5964..27ee36b2de90 100644 --- a/src/library/scala/Function8.scala +++ b/src/library/scala/Function8.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Function9.scala b/src/library/scala/Function9.scala index aa0fcd0aeb3b..5bf1a5b16565 100644 --- a/src/library/scala/Function9.scala +++ b/src/library/scala/Function9.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index 5015a789c336..003bd502a730 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala index 0d3967fb28f1..09bd35c64677 100644 --- a/src/library/scala/Long.scala +++ b/src/library/scala/Long.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/MatchError.scala b/src/library/scala/MatchError.scala index bc94f2cbabdb..39fa11e817f0 100644 --- a/src/library/scala/MatchError.scala +++ b/src/library/scala/MatchError.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/NotImplementedError.scala b/src/library/scala/NotImplementedError.scala index b4448fece11a..22361b78b85b 100644 --- a/src/library/scala/NotImplementedError.scala +++ b/src/library/scala/NotImplementedError.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 16b22cc47ef3..514bf50607ff 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -55,18 +55,18 @@ object Option { * `foreach`: * * {{{ - * val name: Option[String] = request getParameter "name" - * val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase } - * println(upper getOrElse "") + * val name: Option[String] = request.getParameter("name") + * val upper = name.map(_.trim).filter(_.length != 0).map(_.toUpperCase) + * println(upper.getOrElse("")) * }}} * * Note that this is equivalent to {{{ * val upper = for { - * name <- request getParameter "name" + * name <- request.getParameter("name") * trimmed <- Some(name.trim) * upper <- Some(trimmed.toUpperCase) if trimmed.length != 0 * } yield upper - * println(upper getOrElse "") + * println(upper.getOrElse("")) * }}} * * Because of how for comprehension works, if $none is returned @@ -99,7 +99,7 @@ object Option { * - [[toList]] — Unary list of optional value, otherwise the empty list * * A less-idiomatic way to use $option values is via pattern matching: {{{ - * val nameMaybe = request getParameter "name" + * val nameMaybe = request.getParameter("name") * nameMaybe match { * case Some(name) => * println(name.trim.toUppercase) @@ -254,7 +254,7 @@ sealed abstract class Option[+A] extends IterableOnce[A] with Product with Seria * }}} * This is also equivalent to: * {{{ - * option map f getOrElse ifEmpty + * option.map(f).getOrElse(ifEmpty) * }}} * @param ifEmpty the expression to evaluate if empty. * @param f the function to apply if nonempty. diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 5ab1bf9fe2c8..5150f52ef7e3 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -35,48 +35,59 @@ import scala.annotation.nowarn * which is expected to be more efficient than calling both `isDefinedAt` * and `apply`. * - * The main distinction between `PartialFunction` and [[scala.Function1]] is - * that the user of a `PartialFunction` may choose to do something different - * with input that is declared to be outside its domain. For example: + * Note that `isDefinedAt` may itself throw an exception while evaluating pattern guards + * or other parts of the `PartialFunction`. The same caveat holds for `applyOrElse`. * * {{{ * val sample = 1 to 10 * def isEven(n: Int) = n % 2 == 0 + * * val eveningNews: PartialFunction[Int, String] = { * case x if isEven(x) => s"\$x is even" * } * - * // The method collect is described as "filter + map" + * // The method "collect" is described as "filter + map" * // because it uses a PartialFunction to select elements * // to which the function is applied. * val evenNumbers = sample.collect(eveningNews) * + * // It's more usual to write the PartialFunction as a block of case clauses + * // called an "anonymous pattern-matching function". Since the collect method + * // expects a PartialFunction, one is synthesized from the case clauses. + * def evenly = sample.collect { case x if isEven(x) => s"\$x is even" } + * + * // A method that takes a Function will get one, using the same syntax. + * // Note that all cases are supplied since Function has no `isDefinedAt`. + * def evened = sample.map { case odd if !isEven(odd) => odd + 1 case even => even } + * }}} + * + * The main distinction between `PartialFunction` and [[scala.Function1]] is + * that the client of a `PartialFunction` can perform an alternative computation + * with input that is reported to be outside the domain of the function. + * + * For example: + * + * {{{ * val oddlyEnough: PartialFunction[Int, String] = { * case x if !isEven(x) => s"\$x is odd" * } * * // The method orElse allows chaining another PartialFunction * // to handle input outside the declared domain. - * val numbers = sample.map(eveningNews orElse oddlyEnough) + * val numbers = sample.map(eveningNews.orElse(oddlyEnough)) * - * // same as + * // The same computation but with a function literal that calls applyOrElse + * // with oddlyEnough as fallback, which it can do because a PartialFunction is a Function. * val numbers = sample.map(n => eveningNews.applyOrElse(n, oddlyEnough)) + * }}} * - * val half: PartialFunction[Int, Int] = { - * case x if isEven(x) => x / 2 - * } - * - * // Calculating the domain of a composition can be expensive. - * val oddByHalf = half.andThen(oddlyEnough) - * - * // Invokes `half.apply` on even elements! - * val oddBalls = sample.filter(oddByHalf.isDefinedAt) - * - * // Better than filter(oddByHalf.isDefinedAt).map(oddByHalf) - * val oddBalls = sample.collect(oddByHalf) + * As a convenience, function literals can also be adapted into partial functions + * when needed. If the body of the function is a match expression, then the cases + * are used to synthesize the PartialFunction as already shown. * - * // Providing "default" values. - * val oddsAndEnds = sample.map(n => oddByHalf.applyOrElse(n, (i: Int) => s"[\$i]")) + * {{{ + * // The partial function isDefinedAt inputs resulting in the Success case. + * val inputs = List("1", "two", "3").collect(x => Try(x.toInt) match { case Success(i) => i }) * }}} * * @note Optional [[Function]]s, [[PartialFunction]]s and extractor objects @@ -86,7 +97,7 @@ import scala.annotation.nowarn * | :---: | --- | --- | --- | * | from a [[PartialFunction]] | [[Predef.identity]] | [[lift]] | [[Predef.identity]] | * | from optional [[Function]] | [[Function1.UnliftOps#unlift]] or [[Function.unlift]] | [[Predef.identity]] | [[Function1.UnliftOps#unlift]] | - * | from an extractor | `{ case extractor(x) => x }` | `extractor.unapply _` | [[Predef.identity]] | + * | from an extractor | `{ case extractor(x) => x }` | `extractor.unapply(_)` | [[Predef.identity]] | *   * * @define applyOrElseOrElse Note that calling [[isDefinedAt]] on the resulting partial function diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 6eb4e4b11266..26dbc568a9ab 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product.scala b/src/library/scala/Product.scala index 96a2277d736e..c0fa80a95ef5 100644 --- a/src/library/scala/Product.scala +++ b/src/library/scala/Product.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala index ce2e66c3cdb0..912f4dc8f0d8 100644 --- a/src/library/scala/Product1.scala +++ b/src/library/scala/Product1.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product10.scala b/src/library/scala/Product10.scala index 21f51a755a1e..8ab742e3458f 100644 --- a/src/library/scala/Product10.scala +++ b/src/library/scala/Product10.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product11.scala b/src/library/scala/Product11.scala index ae0955667dff..c970235fc693 100644 --- a/src/library/scala/Product11.scala +++ b/src/library/scala/Product11.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product12.scala b/src/library/scala/Product12.scala index b1e3f1f8975a..2823288e430b 100644 --- a/src/library/scala/Product12.scala +++ b/src/library/scala/Product12.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product13.scala b/src/library/scala/Product13.scala index 1c936b9b65d0..25e804081407 100644 --- a/src/library/scala/Product13.scala +++ b/src/library/scala/Product13.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product14.scala b/src/library/scala/Product14.scala index 20590fb43071..76afd49e1856 100644 --- a/src/library/scala/Product14.scala +++ b/src/library/scala/Product14.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product15.scala b/src/library/scala/Product15.scala index ff3828dadd17..dd6e49a33eba 100644 --- a/src/library/scala/Product15.scala +++ b/src/library/scala/Product15.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product16.scala b/src/library/scala/Product16.scala index c4020ebcd4ed..900ccdcab195 100644 --- a/src/library/scala/Product16.scala +++ b/src/library/scala/Product16.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product17.scala b/src/library/scala/Product17.scala index d5686bee10d9..4e6636f2e5d1 100644 --- a/src/library/scala/Product17.scala +++ b/src/library/scala/Product17.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product18.scala b/src/library/scala/Product18.scala index 9022959e3ced..4a68f49f5623 100644 --- a/src/library/scala/Product18.scala +++ b/src/library/scala/Product18.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product19.scala b/src/library/scala/Product19.scala index e6e51c3d21a8..fdc4c232742d 100644 --- a/src/library/scala/Product19.scala +++ b/src/library/scala/Product19.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala index 3e0b70d0eef1..2498e9727b7f 100644 --- a/src/library/scala/Product2.scala +++ b/src/library/scala/Product2.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product20.scala b/src/library/scala/Product20.scala index f87ab550e13e..206dc1e375cc 100644 --- a/src/library/scala/Product20.scala +++ b/src/library/scala/Product20.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product21.scala b/src/library/scala/Product21.scala index c80692711a27..0cbb44068fc8 100644 --- a/src/library/scala/Product21.scala +++ b/src/library/scala/Product21.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product22.scala b/src/library/scala/Product22.scala index 4010a397ecde..df6963c03843 100644 --- a/src/library/scala/Product22.scala +++ b/src/library/scala/Product22.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala index e1be1f55f084..48de4b6e7d20 100644 --- a/src/library/scala/Product3.scala +++ b/src/library/scala/Product3.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala index 2204672af6f3..7b34b570f1f0 100644 --- a/src/library/scala/Product4.scala +++ b/src/library/scala/Product4.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala index f0b2662fc741..769e2f0b22d3 100644 --- a/src/library/scala/Product5.scala +++ b/src/library/scala/Product5.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala index 39075858dd76..aff1fbb92e46 100644 --- a/src/library/scala/Product6.scala +++ b/src/library/scala/Product6.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala index fe230647b661..7aef56fc53a6 100644 --- a/src/library/scala/Product7.scala +++ b/src/library/scala/Product7.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala index e36fcc7323a1..f8604b887358 100644 --- a/src/library/scala/Product8.scala +++ b/src/library/scala/Product8.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala index 9f6bed7861a1..6731142a015b 100644 --- a/src/library/scala/Product9.scala +++ b/src/library/scala/Product9.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Proxy.scala b/src/library/scala/Proxy.scala index 7a798cf5a3c8..8da03133e3cd 100644 --- a/src/library/scala/Proxy.scala +++ b/src/library/scala/Proxy.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/SerialVersionUID.scala b/src/library/scala/SerialVersionUID.scala index 7a0b08f6fa23..0c85b2591247 100644 --- a/src/library/scala/SerialVersionUID.scala +++ b/src/library/scala/SerialVersionUID.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala index 45b9a4c5eb2c..4a56d71d0733 100644 --- a/src/library/scala/Short.scala +++ b/src/library/scala/Short.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Specializable.scala b/src/library/scala/Specializable.scala index c4b0f1265ddf..54fb59dba83e 100644 --- a/src/library/scala/Specializable.scala +++ b/src/library/scala/Specializable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 604aebb15ba6..ec5c49a2349e 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala index c388bde42a98..36a99c5e4e6e 100644 --- a/src/library/scala/Symbol.scala +++ b/src/library/scala/Symbol.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple1.scala b/src/library/scala/Tuple1.scala index d94aad6d7a0c..6af3d3582b14 100644 --- a/src/library/scala/Tuple1.scala +++ b/src/library/scala/Tuple1.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple10.scala b/src/library/scala/Tuple10.scala index 0135dc93de03..63fa78016769 100644 --- a/src/library/scala/Tuple10.scala +++ b/src/library/scala/Tuple10.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple11.scala b/src/library/scala/Tuple11.scala index 5d187938dcf8..3cdf35e84b8c 100644 --- a/src/library/scala/Tuple11.scala +++ b/src/library/scala/Tuple11.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple12.scala b/src/library/scala/Tuple12.scala index 5a523a08e364..b27538f446c2 100644 --- a/src/library/scala/Tuple12.scala +++ b/src/library/scala/Tuple12.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple13.scala b/src/library/scala/Tuple13.scala index e1292f110985..84f2f3cecc28 100644 --- a/src/library/scala/Tuple13.scala +++ b/src/library/scala/Tuple13.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple14.scala b/src/library/scala/Tuple14.scala index 8ab32a8d56d4..08cd54c0cb82 100644 --- a/src/library/scala/Tuple14.scala +++ b/src/library/scala/Tuple14.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple15.scala b/src/library/scala/Tuple15.scala index 216929f99f40..b4a932352092 100644 --- a/src/library/scala/Tuple15.scala +++ b/src/library/scala/Tuple15.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple16.scala b/src/library/scala/Tuple16.scala index 7ca15b997b60..417fa3aff002 100644 --- a/src/library/scala/Tuple16.scala +++ b/src/library/scala/Tuple16.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple17.scala b/src/library/scala/Tuple17.scala index b0f8e72b8d7c..e7d63a81d1e9 100644 --- a/src/library/scala/Tuple17.scala +++ b/src/library/scala/Tuple17.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple18.scala b/src/library/scala/Tuple18.scala index bb99c0acf687..86875130951a 100644 --- a/src/library/scala/Tuple18.scala +++ b/src/library/scala/Tuple18.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple19.scala b/src/library/scala/Tuple19.scala index edbe42af0621..e3826ddd3073 100644 --- a/src/library/scala/Tuple19.scala +++ b/src/library/scala/Tuple19.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 0da4e01f08b2..3429ed7dea62 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple20.scala b/src/library/scala/Tuple20.scala index e03a514c3a11..1d4826b94841 100644 --- a/src/library/scala/Tuple20.scala +++ b/src/library/scala/Tuple20.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple21.scala b/src/library/scala/Tuple21.scala index c253aae00186..01503f0e9362 100644 --- a/src/library/scala/Tuple21.scala +++ b/src/library/scala/Tuple21.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple22.scala b/src/library/scala/Tuple22.scala index 4a771c28764d..3f84e75a5dc6 100644 --- a/src/library/scala/Tuple22.scala +++ b/src/library/scala/Tuple22.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index 414c2abe859c..b053d9c4c6b2 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple4.scala b/src/library/scala/Tuple4.scala index 8ee3db9eb4c7..29970f510398 100644 --- a/src/library/scala/Tuple4.scala +++ b/src/library/scala/Tuple4.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple5.scala b/src/library/scala/Tuple5.scala index 6597bd692303..b6dbd2ea6cd4 100644 --- a/src/library/scala/Tuple5.scala +++ b/src/library/scala/Tuple5.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple6.scala b/src/library/scala/Tuple6.scala index 1955a93ec39a..834d81a43e84 100644 --- a/src/library/scala/Tuple6.scala +++ b/src/library/scala/Tuple6.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple7.scala b/src/library/scala/Tuple7.scala index d3b6cb63ebd5..d6e86752addd 100644 --- a/src/library/scala/Tuple7.scala +++ b/src/library/scala/Tuple7.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple8.scala b/src/library/scala/Tuple8.scala index 3a854344b3f9..035d44e5330e 100644 --- a/src/library/scala/Tuple8.scala +++ b/src/library/scala/Tuple8.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Tuple9.scala b/src/library/scala/Tuple9.scala index a1d24a3623a2..50869e2c9b22 100644 --- a/src/library/scala/Tuple9.scala +++ b/src/library/scala/Tuple9.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/UninitializedError.scala b/src/library/scala/UninitializedError.scala index c55fd0cea9f9..84332c9a9d3e 100644 --- a/src/library/scala/UninitializedError.scala +++ b/src/library/scala/UninitializedError.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/UninitializedFieldError.scala b/src/library/scala/UninitializedFieldError.scala index 7ca2d02f83b6..d516abb68936 100644 --- a/src/library/scala/UninitializedFieldError.scala +++ b/src/library/scala/UninitializedFieldError.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala index 013677bd999a..66fde8c72038 100644 --- a/src/library/scala/Unit.scala +++ b/src/library/scala/Unit.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ValueOf.scala b/src/library/scala/ValueOf.scala index e30c86a1272d..30d5f7ff40c7 100644 --- a/src/library/scala/ValueOf.scala +++ b/src/library/scala/ValueOf.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/Annotation.scala b/src/library/scala/annotation/Annotation.scala index d0c25abf5da7..a78842cbf1c4 100644 --- a/src/library/scala/annotation/Annotation.scala +++ b/src/library/scala/annotation/Annotation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/ClassfileAnnotation.scala b/src/library/scala/annotation/ClassfileAnnotation.scala index 1f6317427b5e..be3c98b6130a 100644 --- a/src/library/scala/annotation/ClassfileAnnotation.scala +++ b/src/library/scala/annotation/ClassfileAnnotation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/ConstantAnnotation.scala b/src/library/scala/annotation/ConstantAnnotation.scala index 70336311527e..b9a933371cc8 100644 --- a/src/library/scala/annotation/ConstantAnnotation.scala +++ b/src/library/scala/annotation/ConstantAnnotation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/StaticAnnotation.scala b/src/library/scala/annotation/StaticAnnotation.scala index 24438c04b5d1..dc0136db70af 100644 --- a/src/library/scala/annotation/StaticAnnotation.scala +++ b/src/library/scala/annotation/StaticAnnotation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/TypeConstraint.scala b/src/library/scala/annotation/TypeConstraint.scala index 8ee7f8e0a2cc..b9b5a62aa3c9 100644 --- a/src/library/scala/annotation/TypeConstraint.scala +++ b/src/library/scala/annotation/TypeConstraint.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/compileTimeOnly.scala b/src/library/scala/annotation/compileTimeOnly.scala index 9e742badf931..e2eb7560b8bf 100644 --- a/src/library/scala/annotation/compileTimeOnly.scala +++ b/src/library/scala/annotation/compileTimeOnly.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/elidable.scala b/src/library/scala/annotation/elidable.scala index f2028bfd02fb..e15f0de8d9f1 100644 --- a/src/library/scala/annotation/elidable.scala +++ b/src/library/scala/annotation/elidable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/implicitAmbiguous.scala b/src/library/scala/annotation/implicitAmbiguous.scala index 87788588c5af..5520c945fef2 100644 --- a/src/library/scala/annotation/implicitAmbiguous.scala +++ b/src/library/scala/annotation/implicitAmbiguous.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/implicitNotFound.scala b/src/library/scala/annotation/implicitNotFound.scala index 9eba5c2c9f3a..55a9179a394f 100644 --- a/src/library/scala/annotation/implicitNotFound.scala +++ b/src/library/scala/annotation/implicitNotFound.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/beanGetter.scala b/src/library/scala/annotation/meta/beanGetter.scala index 3d45ade30e69..58d37bfb1cde 100644 --- a/src/library/scala/annotation/meta/beanGetter.scala +++ b/src/library/scala/annotation/meta/beanGetter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/beanSetter.scala b/src/library/scala/annotation/meta/beanSetter.scala index 04483bd1759d..670c67259fa8 100644 --- a/src/library/scala/annotation/meta/beanSetter.scala +++ b/src/library/scala/annotation/meta/beanSetter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/companionClass.scala b/src/library/scala/annotation/meta/companionClass.scala index abff9ccb5d3a..0a7b072b521d 100644 --- a/src/library/scala/annotation/meta/companionClass.scala +++ b/src/library/scala/annotation/meta/companionClass.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/companionMethod.scala b/src/library/scala/annotation/meta/companionMethod.scala index 44eecd2cf541..2e0080a1d61f 100644 --- a/src/library/scala/annotation/meta/companionMethod.scala +++ b/src/library/scala/annotation/meta/companionMethod.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/companionObject.scala b/src/library/scala/annotation/meta/companionObject.scala index d447c87389c4..dc817b138707 100644 --- a/src/library/scala/annotation/meta/companionObject.scala +++ b/src/library/scala/annotation/meta/companionObject.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/defaultArg.scala b/src/library/scala/annotation/meta/defaultArg.scala new file mode 100644 index 000000000000..4964bcb683dc --- /dev/null +++ b/src/library/scala/annotation/meta/defaultArg.scala @@ -0,0 +1,30 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.annotation +package meta + +/** + * This internal meta annotation is used by the compiler to support default annotation arguments. + * + * For an annotation definition `class ann(x: Int = defaultExpr) extends Annotation`, the compiler adds + * `@defaultArg(defaultExpr)` to the parameter `x`. This causes the syntax tree of `defaultExpr` to be + * stored in the classfile. + * + * When using a default annotation argument, the compiler can recover the syntax tree and insert it in the + * `AnnotationInfo`. + * + * For details, see `scala.reflect.internal.AnnotationInfos.AnnotationInfo`. + */ +@meta.param class defaultArg(arg: Any) extends StaticAnnotation { + def this() = this(null) +} diff --git a/src/library/scala/annotation/meta/field.scala b/src/library/scala/annotation/meta/field.scala index 267037e8d9f7..ccd64a0179f7 100644 --- a/src/library/scala/annotation/meta/field.scala +++ b/src/library/scala/annotation/meta/field.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/getter.scala b/src/library/scala/annotation/meta/getter.scala index 36d8a76763b5..acbc7989c901 100644 --- a/src/library/scala/annotation/meta/getter.scala +++ b/src/library/scala/annotation/meta/getter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/languageFeature.scala b/src/library/scala/annotation/meta/languageFeature.scala index 6b68f76338cb..f2d9c7890d47 100644 --- a/src/library/scala/annotation/meta/languageFeature.scala +++ b/src/library/scala/annotation/meta/languageFeature.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/package.scala b/src/library/scala/annotation/meta/package.scala index 7d09a8785517..ab315e412e07 100644 --- a/src/library/scala/annotation/meta/package.scala +++ b/src/library/scala/annotation/meta/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/param.scala b/src/library/scala/annotation/meta/param.scala index 5d4ebf5c8221..8c69a3b644b1 100644 --- a/src/library/scala/annotation/meta/param.scala +++ b/src/library/scala/annotation/meta/param.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/setter.scala b/src/library/scala/annotation/meta/setter.scala index fae59b5a48a7..b37979bec597 100644 --- a/src/library/scala/annotation/meta/setter.scala +++ b/src/library/scala/annotation/meta/setter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/meta/superArg.scala b/src/library/scala/annotation/meta/superArg.scala new file mode 100644 index 000000000000..181db2651f4e --- /dev/null +++ b/src/library/scala/annotation/meta/superArg.scala @@ -0,0 +1,34 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.annotation +package meta + +/** + * This internal annotation encodes arguments passed to annotation superclasses. Example: + * + * {{{ + * class a(x: Int) extends Annotation + * class b extends a(42) // the compiler adds `@superArg("x", 42)` to class b + * }}} + */ +class superArg(p: String, v: Any) extends StaticAnnotation + +/** + * This internal annotation encodes arguments passed to annotation superclasses. Example: + * + * {{{ + * class a(x: Int) extends Annotation + * class b(y: Int) extends a(y) // the compiler adds `@superFwdArg("x", "y")` to class b + * }}} + */ +class superFwdArg(p: String, n: String) extends StaticAnnotation diff --git a/src/library/scala/annotation/migration.scala b/src/library/scala/annotation/migration.scala index 37b2a9edfda0..81ef78dbd367 100644 --- a/src/library/scala/annotation/migration.scala +++ b/src/library/scala/annotation/migration.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/nowarn.scala b/src/library/scala/annotation/nowarn.scala index 2fb6383fe7e7..a083af4544ed 100644 --- a/src/library/scala/annotation/nowarn.scala +++ b/src/library/scala/annotation/nowarn.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,8 +14,11 @@ package scala.annotation /** An annotation for local warning suppression. * - * The optional `value` parameter allows selectively silencing messages, see `scalac -Wconf:help` - * for help. Examples: + * The optional `value` parameter allows selectively silencing messages. See `-Wconf:help` for help + * writing a message filter expression, or use `@nowarn("verbose")` / `@nowarn("v")` to display message + * filters applicable to a specific warning. + * + * Examples: * * {{{ * def f = { @@ -23,6 +26,9 @@ package scala.annotation * 2 * } * + * // show the warning, plus the applicable @nowarn / Wconf filters ("cat=other-pure-statement", ...) + * @nowarn("v") def f = { 1; 2 } + * * @nowarn def f = { 1; deprecated() } // don't warn * * @nowarn("msg=pure expression does nothing") diff --git a/src/library/scala/annotation/showAsInfix.scala b/src/library/scala/annotation/showAsInfix.scala index b2477ddc4ad7..9c4ecbe2eea1 100644 --- a/src/library/scala/annotation/showAsInfix.scala +++ b/src/library/scala/annotation/showAsInfix.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/strictfp.scala b/src/library/scala/annotation/strictfp.scala index dbc68b79769c..40e297fc4d97 100644 --- a/src/library/scala/annotation/strictfp.scala +++ b/src/library/scala/annotation/strictfp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/switch.scala b/src/library/scala/annotation/switch.scala index 1a8d5b902e7a..f4af17741fe6 100644 --- a/src/library/scala/annotation/switch.scala +++ b/src/library/scala/annotation/switch.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/tailrec.scala b/src/library/scala/annotation/tailrec.scala index da22e142482d..7b3f80dbf66f 100644 --- a/src/library/scala/annotation/tailrec.scala +++ b/src/library/scala/annotation/tailrec.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/unchecked/uncheckedStable.scala b/src/library/scala/annotation/unchecked/uncheckedStable.scala index cc05088cb934..12a18d635fe4 100644 --- a/src/library/scala/annotation/unchecked/uncheckedStable.scala +++ b/src/library/scala/annotation/unchecked/uncheckedStable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/unchecked/uncheckedVariance.scala b/src/library/scala/annotation/unchecked/uncheckedVariance.scala index b506b4ba5cc7..60f06ad95f7d 100644 --- a/src/library/scala/annotation/unchecked/uncheckedVariance.scala +++ b/src/library/scala/annotation/unchecked/uncheckedVariance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/unspecialized.scala b/src/library/scala/annotation/unspecialized.scala index a02f80385bca..c0f668a75298 100644 --- a/src/library/scala/annotation/unspecialized.scala +++ b/src/library/scala/annotation/unspecialized.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/unused.scala b/src/library/scala/annotation/unused.scala index 68f01e883346..270286864822 100644 --- a/src/library/scala/annotation/unused.scala +++ b/src/library/scala/annotation/unused.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/annotation/varargs.scala b/src/library/scala/annotation/varargs.scala index 1b8357732e59..68d1080a53f8 100644 --- a/src/library/scala/annotation/varargs.scala +++ b/src/library/scala/annotation/varargs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/beans/BeanProperty.scala b/src/library/scala/beans/BeanProperty.scala index c836c574576c..7b2ef0c9d516 100644 --- a/src/library/scala/beans/BeanProperty.scala +++ b/src/library/scala/beans/BeanProperty.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -27,6 +27,11 @@ import scala.annotation.meta.{beanGetter, beanSetter, field} * }}} * For fields of type `Boolean`, if you need a getter named `isStatus`, * use the `scala.beans.BooleanBeanProperty` annotation instead. + * + * In Scala 2, the added methods are visible from both Scala and Java. + * + * In Scala 3, that has changed. The added methods are only visible from + * Java (including via Java reflection). */ @field @beanGetter @beanSetter @deprecatedInheritance("Scheduled for being final in the future", "2.13.0") diff --git a/src/library/scala/beans/BooleanBeanProperty.scala b/src/library/scala/beans/BooleanBeanProperty.scala index 714c33257871..72d253df2f8b 100644 --- a/src/library/scala/beans/BooleanBeanProperty.scala +++ b/src/library/scala/beans/BooleanBeanProperty.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/ArrayOps.scala b/src/library/scala/collection/ArrayOps.scala index a18072a88f8b..08758e2ab46a 100644 --- a/src/library/scala/collection/ArrayOps.scala +++ b/src/library/scala/collection/ArrayOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -44,6 +44,7 @@ import scala.Predef.{ // unimport all array-related implicit conversions to avoi _ } import scala.collection.Stepper.EfficientSplit +import scala.collection.generic.CommonErrors import scala.collection.immutable.Range import scala.collection.mutable.ArrayBuilder import scala.math.Ordering @@ -589,7 +590,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { val len = xs.length def boxed = if(len < ArrayOps.MaxStableSortLength) { val a = xs.clone() - Sorting.stableSort(a)(ord.asInstanceOf[Ordering[A]]) + Sorting.stableSort(a)(using ord.asInstanceOf[Ordering[A]]) a } else { val a = Array.copyAs[AnyRef](xs, len)(ClassTag.AnyRef) @@ -1299,7 +1300,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { val bb = new ArrayBuilder.ofRef[Array[B]]()(ClassTag[Array[B]](aClass)) if (xs.length == 0) bb.result() else { - def mkRowBuilder() = ArrayBuilder.make[B](ClassTag[B](aClass.getComponentType)) + def mkRowBuilder() = ArrayBuilder.make[B](using ClassTag[B](aClass.getComponentType)) val bs = new ArrayOps(asArray(xs(0))).map((x: B) => mkRowBuilder()) for (xs <- this) { var i = 0 @@ -1545,7 +1546,8 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * @throws IndexOutOfBoundsException if `index` does not satisfy `0 <= index < length`. */ def updated[B >: A : ClassTag](index: Int, elem: B): Array[B] = { - if(index < 0 || index >= xs.length) throw new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${xs.length-1})") + if(index < 0 || index >= xs.length) + throw CommonErrors.indexOutOfBounds(index = index, max = xs.length-1) val dest = toArray[B] dest(index) = elem dest diff --git a/src/library/scala/collection/BitSet.scala b/src/library/scala/collection/BitSet.scala index e8ca89806455..a2da58ea3b9b 100644 --- a/src/library/scala/collection/BitSet.scala +++ b/src/library/scala/collection/BitSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/BufferedIterator.scala b/src/library/scala/collection/BufferedIterator.scala index bc35ee0a25da..b5a7f9658422 100644 --- a/src/library/scala/collection/BufferedIterator.scala +++ b/src/library/scala/collection/BufferedIterator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/BuildFrom.scala b/src/library/scala/collection/BuildFrom.scala index bc9c49d9493c..0530e4445bd5 100644 --- a/src/library/scala/collection/BuildFrom.scala +++ b/src/library/scala/collection/BuildFrom.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/DefaultMap.scala b/src/library/scala/collection/DefaultMap.scala index cbc61d8c0268..ca7d2a67f757 100644 --- a/src/library/scala/collection/DefaultMap.scala +++ b/src/library/scala/collection/DefaultMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/Factory.scala b/src/library/scala/collection/Factory.scala index 838dcf72f673..4a05e6ce23bd 100644 --- a/src/library/scala/collection/Factory.scala +++ b/src/library/scala/collection/Factory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -90,7 +90,7 @@ trait IterableFactory[+CC[_]] extends Serializable { */ def from[A](source: IterableOnce[A]): CC[A] - /** An empty collection + /** An empty $coll * @tparam A the type of the ${coll}'s elements */ def empty[A]: CC[A] @@ -146,10 +146,10 @@ trait IterableFactory[+CC[_]] extends Serializable { def newBuilder[A]: Builder[A, CC[A]] /** Produces a $coll containing the results of some element computation a number of times. - * @param n the number of elements contained in the $coll. - * @param elem the element computation - * @return A $coll that contains the results of `n` evaluations of `elem`. - */ + * @param n the number of elements contained in the $coll. + * @param elem the element computation + * @return A $coll that contains the results of `n` evaluations of `elem`. + */ def fill[A](n: Int)(elem: => A): CC[A] = from(new View.Fill(n)(elem)) /** Produces a two-dimensional $coll containing the results of some element computation a number of times. @@ -667,16 +667,16 @@ object ClassTagIterableFactory { * sound depending on the use of the `ClassTag` by the collection implementation. */ @SerialVersionUID(3L) class AnyIterableDelegate[CC[_]](delegate: ClassTagIterableFactory[CC]) extends IterableFactory[CC] { - def empty[A]: CC[A] = delegate.empty(ClassTag.Any).asInstanceOf[CC[A]] - def from[A](it: IterableOnce[A]): CC[A] = delegate.from[Any](it)(ClassTag.Any).asInstanceOf[CC[A]] - def newBuilder[A]: Builder[A, CC[A]] = delegate.newBuilder(ClassTag.Any).asInstanceOf[Builder[A, CC[A]]] - override def apply[A](elems: A*): CC[A] = delegate.apply[Any](elems: _*)(ClassTag.Any).asInstanceOf[CC[A]] - override def iterate[A](start: A, len: Int)(f: A => A): CC[A] = delegate.iterate[A](start, len)(f)(ClassTag.Any.asInstanceOf[ClassTag[A]]) - override def unfold[A, S](init: S)(f: S => Option[(A, S)]): CC[A] = delegate.unfold[A, S](init)(f)(ClassTag.Any.asInstanceOf[ClassTag[A]]) - override def range[A](start: A, end: A)(implicit i: Integral[A]): CC[A] = delegate.range[A](start, end)(i, ClassTag.Any.asInstanceOf[ClassTag[A]]) - override def range[A](start: A, end: A, step: A)(implicit i: Integral[A]): CC[A] = delegate.range[A](start, end, step)(i, ClassTag.Any.asInstanceOf[ClassTag[A]]) - override def fill[A](n: Int)(elem: => A): CC[A] = delegate.fill[Any](n)(elem)(ClassTag.Any).asInstanceOf[CC[A]] - override def tabulate[A](n: Int)(f: Int => A): CC[A] = delegate.tabulate[Any](n)(f)(ClassTag.Any).asInstanceOf[CC[A]] + def empty[A]: CC[A] = delegate.empty(using ClassTag.Any).asInstanceOf[CC[A]] + def from[A](it: IterableOnce[A]): CC[A] = delegate.from[Any](it)(using ClassTag.Any).asInstanceOf[CC[A]] + def newBuilder[A]: Builder[A, CC[A]] = delegate.newBuilder(using ClassTag.Any).asInstanceOf[Builder[A, CC[A]]] + override def apply[A](elems: A*): CC[A] = delegate.apply[Any](elems: _*)(using ClassTag.Any).asInstanceOf[CC[A]] + override def iterate[A](start: A, len: Int)(f: A => A): CC[A] = delegate.iterate[A](start, len)(f)(using ClassTag.Any.asInstanceOf[ClassTag[A]]) + override def unfold[A, S](init: S)(f: S => Option[(A, S)]): CC[A] = delegate.unfold[A, S](init)(f)(using ClassTag.Any.asInstanceOf[ClassTag[A]]) + override def range[A](start: A, end: A)(implicit i: Integral[A]): CC[A] = delegate.range[A](start, end)(using i, ClassTag.Any.asInstanceOf[ClassTag[A]]) + override def range[A](start: A, end: A, step: A)(implicit i: Integral[A]): CC[A] = delegate.range[A](start, end, step)(using i, ClassTag.Any.asInstanceOf[ClassTag[A]]) + override def fill[A](n: Int)(elem: => A): CC[A] = delegate.fill[Any](n)(elem)(using ClassTag.Any).asInstanceOf[CC[A]] + override def tabulate[A](n: Int)(f: Int => A): CC[A] = delegate.tabulate[Any](n)(f)(using ClassTag.Any).asInstanceOf[CC[A]] } } diff --git a/src/library/scala/collection/Hashing.scala b/src/library/scala/collection/Hashing.scala index 4e1fd872b8b5..7d3702d26e43 100644 --- a/src/library/scala/collection/Hashing.scala +++ b/src/library/scala/collection/Hashing.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/IndexedSeq.scala b/src/library/scala/collection/IndexedSeq.scala index c26e771004d8..3735755041a3 100644 --- a/src/library/scala/collection/IndexedSeq.scala +++ b/src/library/scala/collection/IndexedSeq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -91,6 +91,11 @@ trait IndexedSeqOps[+A, +CC[_], +C] extends Any with SeqOps[A, CC, C] { self => override def slice(from: Int, until: Int): C = fromSpecific(new IndexedSeqView.Slice(this, from, until)) + override def sliding(size: Int, step: Int): Iterator[C] = { + require(size >= 1 && step >= 1, f"size=$size%d and step=$step%d, but both must be positive") + new IndexedSeqSlidingIterator[A, CC, C](this, size, step) + } + override def head: A = if (!isEmpty) apply(0) else throw new NoSuchElementException(s"head of empty ${ @@ -145,3 +150,26 @@ trait IndexedSeqOps[+A, +CC[_], +C] extends Any with SeqOps[A, CC, C] { self => } } } + +/** A fast sliding iterator for IndexedSeqs which uses the underlying `slice` operation. */ +private final class IndexedSeqSlidingIterator[A, CC[_], C](s: IndexedSeqOps[A, CC, C], size: Int, step: Int) + extends AbstractIterator[C] { + + private[this] val len = s.length + private[this] var pos = 0 + private def chklen: Boolean = len == s.length || { + throw new java.util.ConcurrentModificationException("collection size changed during iteration") + false + } + + def hasNext: Boolean = chklen && pos < len + + def next(): C = if (!chklen || !hasNext) Iterator.empty.next() else { + val end = { val x = pos + size; if (x < 0 || x > len) len else x } // (pos.toLong + size).min(len).toInt + val slice = s.slice(pos, end) + pos = + if (end >= len) len + else { val x = pos + step; if (x < 0 || x > len) len else x } // (pos.toLong + step).min(len).toInt + slice + } +} diff --git a/src/library/scala/collection/IndexedSeqView.scala b/src/library/scala/collection/IndexedSeqView.scala index 737f032d2060..4fd99c1080af 100644 --- a/src/library/scala/collection/IndexedSeqView.scala +++ b/src/library/scala/collection/IndexedSeqView.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/Iterable.scala b/src/library/scala/collection/Iterable.scala index 77b6c0b83cb6..304a87402f79 100644 --- a/src/library/scala/collection/Iterable.scala +++ b/src/library/scala/collection/Iterable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -127,7 +127,7 @@ trait Iterable[+A] extends IterableOnce[A] * @define willNotTerminateInf * * Note: will not terminate for infinite-sized collections. - * @define undefinedorder + * @define undefinedorder * The order in which operations are performed on elements is unspecified * and may be nondeterministic. */ @@ -140,9 +140,9 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable def toIterable: Iterable[A] /** Converts this $coll to an unspecified Iterable. Will return - * the same collection if this instance is already Iterable. - * @return An Iterable containing all elements of this $coll. - */ + * the same collection if this instance is already Iterable. + * @return An Iterable containing all elements of this $coll. + */ @deprecated("toTraversable is internal and will be made protected; its name is similar to `toList` or `toSeq`, but it doesn't copy non-immutable collections", "2.13.0") final def toTraversable: Traversable[A] = toIterable @@ -208,24 +208,24 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable */ protected def newSpecificBuilder: Builder[A @uncheckedVariance, C] - /** The empty iterable of the same type as this iterable. + /** The empty $coll. * - * @return an empty iterable of type `C`. + * @return an empty iterable of type $Coll. */ def empty: C = fromSpecific(Nil) /** Selects the first element of this $coll. - * $orderDependent - * @return the first element of this $coll. - * @throws NoSuchElementException if the $coll is empty. - */ + * $orderDependent + * @return the first element of this $coll. + * @throws NoSuchElementException if the $coll is empty. + */ def head: A = iterator.next() /** Optionally selects the first element. - * $orderDependent - * @return the first element of this $coll if it is nonempty, - * `None` if it is empty. - */ + * $orderDependent + * @return the first element of this $coll if it is nonempty, + * `None` if it is empty. + */ def headOption: Option[A] = { val it = iterator if (it.hasNext) Some(it.next()) else None @@ -244,32 +244,32 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable } /** Optionally selects the last element. - * $orderDependent - * @return the last element of this $coll$ if it is nonempty, - * `None` if it is empty. - */ + * $orderDependent + * @return the last element of this $coll if it is nonempty, + * `None` if it is empty. + */ def lastOption: Option[A] = if (isEmpty) None else Some(last) /** A view over the elements of this collection. */ def view: View[A] = View.fromIteratorProvider(() => iterator) /** Compares the size of this $coll to a test value. - * - * @param otherSize the test value that gets compared with the size. - * @return A value `x` where - * {{{ - * x < 0 if this.size < otherSize - * x == 0 if this.size == otherSize - * x > 0 if this.size > otherSize - * }}} - * - * The method as implemented here does not call `size` directly; its running time - * is `O(size min otherSize)` instead of `O(size)`. The method should be overridden - * if computing `size` is cheap and `knownSize` returns `-1`. - * - * @see [[sizeIs]] - */ - def sizeCompare(otherSize: Int): Int = { + * + * @param otherSize the test value that gets compared with the size. + * @return A value `x` where + * {{{ + * x < 0 if this.size < otherSize + * x == 0 if this.size == otherSize + * x > 0 if this.size > otherSize + * }}} + * + * The method as implemented here does not call `size` directly; its running time + * is `O(size min otherSize)` instead of `O(size)`. The method should be overridden + * if computing `size` is cheap and `knownSize` returns `-1`. + * + * @see [[sizeIs]] + */ + def sizeCompare(otherSize: Int): Int = if (otherSize < 0) 1 else { val known = knownSize @@ -285,7 +285,6 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable i - otherSize } } - } /** Returns a value class containing operations for comparing the size of this $coll to a test value. * @@ -304,19 +303,19 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable @inline final def sizeIs: IterableOps.SizeCompareOps = new IterableOps.SizeCompareOps(this) /** Compares the size of this $coll to the size of another `Iterable`. - * - * @param that the `Iterable` whose size is compared with this $coll's size. - * @return A value `x` where - * {{{ - * x < 0 if this.size < that.size - * x == 0 if this.size == that.size - * x > 0 if this.size > that.size - * }}} - * - * The method as implemented here does not call `size` directly; its running time - * is `O(this.size min that.size)` instead of `O(this.size + that.size)`. - * The method should be overridden if computing `size` is cheap and `knownSize` returns `-1`. - */ + * + * @param that the `Iterable` whose size is compared with this $coll's size. + * @return A value `x` where + * {{{ + * x < 0 if this.size < that.size + * x == 0 if this.size == that.size + * x > 0 if this.size > that.size + * }}} + * + * The method as implemented here does not call `size` directly; its running time + * is `O(this.size min that.size)` instead of `O(this.size + that.size)`. + * The method should be overridden if computing `size` is cheap and `knownSize` returns `-1`. + */ def sizeCompare(that: Iterable[_]): Int = { val thatKnownSize = that.knownSize @@ -345,39 +344,39 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable def view(from: Int, until: Int): View[A] = view.slice(from, until) /** Transposes this $coll of iterable collections into - * a $coll of ${coll}s. - * - * The resulting collection's type will be guided by the - * static type of $coll. For example: - * - * {{{ - * val xs = List( - * Set(1, 2, 3), - * Set(4, 5, 6)).transpose - * // xs == List( - * // List(1, 4), - * // List(2, 5), - * // List(3, 6)) - * - * val ys = Vector( - * List(1, 2, 3), - * List(4, 5, 6)).transpose - * // ys == Vector( - * // Vector(1, 4), - * // Vector(2, 5), - * // Vector(3, 6)) - * }}} - * - * $willForceEvaluation - * - * @tparam B the type of the elements of each iterable collection. - * @param asIterable an implicit conversion which asserts that the - * element type of this $coll is an `Iterable`. - * @return a two-dimensional $coll of ${coll}s which has as ''n''th row - * the ''n''th column of this $coll. - * @throws IllegalArgumentException if all collections in this $coll - * are not of the same size. - */ + * a $coll of ${coll}s. + * + * The resulting collection's type will be guided by the + * static type of $coll. For example: + * + * {{{ + * val xs = List( + * Set(1, 2, 3), + * Set(4, 5, 6)).transpose + * // xs == List( + * // List(1, 4), + * // List(2, 5), + * // List(3, 6)) + * + * val ys = Vector( + * List(1, 2, 3), + * List(4, 5, 6)).transpose + * // ys == Vector( + * // Vector(1, 4), + * // Vector(2, 5), + * // Vector(3, 6)) + * }}} + * + * $willForceEvaluation + * + * @tparam B the type of the elements of each iterable collection. + * @param asIterable an implicit conversion which asserts that the + * element type of this $coll is an `Iterable`. + * @return a two-dimensional $coll of ${coll}s which has as ''n''th row + * the ''n''th column of this $coll. + * @throws IllegalArgumentException if all collections in this $coll + * are not of the same size. + */ def transpose[B](implicit asIterable: A => /*<: Either[A1, A2]): (CC[A1], CC[A2]) = { @@ -717,32 +716,34 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable (iterableFactory.from(left), iterableFactory.from(right)) } - /** Returns a new $coll containing the elements from the left hand operand followed by the elements from the - * right hand operand. The element type of the $coll is the most specific superclass encompassing - * the element types of the two operands. - * - * @param suffix the iterable to append. - * @tparam B the element type of the returned collection. - * @return a new $coll which contains all elements - * of this $coll followed by all elements of `suffix`. - */ - def concat[B >: A](suffix: IterableOnce[B]): CC[B] = iterableFactory.from(suffix match { - case xs: Iterable[B] => new View.Concat(this, xs) - case xs => iterator ++ suffix.iterator - }) + /** Returns a new $ccoll containing the elements from the left hand operand followed by the elements from the + * right hand operand. The element type of the $ccoll is the most specific superclass encompassing + * the element types of the two operands. + * + * @param suffix the iterable to append. + * @tparam B the element type of the returned collection. + * @return a new $coll which contains all elements + * of this $coll followed by all elements of `suffix`. + */ + def concat[B >: A](suffix: IterableOnce[B]): CC[B] = iterableFactory.from { + suffix match { + case suffix: Iterable[B] => new View.Concat(this, suffix) + case suffix => iterator ++ suffix.iterator + } + } /** Alias for `concat` */ - @`inline` final def ++ [B >: A](suffix: IterableOnce[B]): CC[B] = concat(suffix) + @inline final def ++ [B >: A](suffix: IterableOnce[B]): CC[B] = concat(suffix) - /** Returns a $coll formed from this $coll and another iterable collection - * by combining corresponding elements in pairs. - * If one of the two collections is longer than the other, its remaining elements are ignored. - * - * @param that The iterable providing the second half of each result pair - * @tparam B the type of the second half of the returned pairs - * @return a new $coll containing pairs consisting of corresponding elements of this $coll and `that`. - * The length of the returned collection is the minimum of the lengths of this $coll and `that`. - */ + /** Returns a $ccoll formed from this $coll and another iterable collection + * by combining corresponding elements in pairs. + * If one of the two collections is longer than the other, its remaining elements are ignored. + * + * @param that The iterable providing the second half of each result pair + * @tparam B the type of the second half of the returned pairs + * @return a new $ccoll containing pairs consisting of corresponding elements of this $coll and `that`. + * The length of the returned collection is the minimum of the lengths of this $coll and `that`. + */ def zip[B](that: IterableOnce[B]): CC[(A @uncheckedVariance, B)] = iterableFactory.from(that match { // sound bcs of VarianceNote case that: Iterable[B] => new View.Zip(this, that) case _ => iterator.zip(that) @@ -758,7 +759,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable * @param that the iterable providing the second half of each result pair * @param thisElem the element to be used to fill up the result if this $coll is shorter than `that`. * @param thatElem the element to be used to fill up the result if `that` is shorter than this $coll. - * @return a new collection of type `That` containing pairs consisting of + * @return a new $coll containing pairs consisting of * corresponding elements of this $coll and `that`. The length * of the returned collection is the maximum of the lengths of this $coll and `that`. * If this $coll is shorter than `that`, `thisElem` values are used to pad the result. @@ -862,7 +863,7 @@ object IterableOps { /** Operations for comparing the size of a collection to a test value. * * These operations are implemented in terms of - * [[scala.collection.IterableOps.sizeCompare(Int) `sizeCompare(Int)`]]. + * [[scala.collection.IterableOps!.sizeCompare(Int):Int* `sizeCompare(Int)`]] */ final class SizeCompareOps private[collection](val it: IterableOps[_, AnyConstr, _]) extends AnyVal { /** Tests if the size of the collection is less than some value. */ @@ -982,9 +983,9 @@ trait SortedSetFactoryDefaults[+A, +WithFilterCC[x] <: IterableOps[x, WithFilterCC, WithFilterCC[x]] with Set[x]] extends SortedSetOps[A @uncheckedVariance, CC, CC[A @uncheckedVariance]] { self: IterableOps[A, WithFilterCC, _] => - override protected def fromSpecific(coll: IterableOnce[A @uncheckedVariance]): CC[A @uncheckedVariance] = sortedIterableFactory.from(coll)(ordering) - override protected def newSpecificBuilder: mutable.Builder[A @uncheckedVariance, CC[A @uncheckedVariance]] = sortedIterableFactory.newBuilder[A](ordering) - override def empty: CC[A @uncheckedVariance] = sortedIterableFactory.empty(ordering) + override protected def fromSpecific(coll: IterableOnce[A @uncheckedVariance]): CC[A @uncheckedVariance] = sortedIterableFactory.from(coll)(using ordering) + override protected def newSpecificBuilder: mutable.Builder[A @uncheckedVariance, CC[A @uncheckedVariance]] = sortedIterableFactory.newBuilder[A](using ordering) + override def empty: CC[A @uncheckedVariance] = sortedIterableFactory.empty(using ordering) override def withFilter(p: A => Boolean): SortedSetOps.WithFilter[A, WithFilterCC, CC] = new SortedSetOps.WithFilter[A, WithFilterCC, CC](this, p) @@ -1036,9 +1037,9 @@ trait SortedMapFactoryDefaults[K, +V, +UnsortedCC[x, y] <: Map[x, y]] extends SortedMapOps[K, V, CC, CC[K, V @uncheckedVariance]] with MapOps[K, V, UnsortedCC, CC[K, V @uncheckedVariance]] { self: IterableOps[(K, V), WithFilterCC, _] => - override def empty: CC[K, V @uncheckedVariance] = sortedMapFactory.empty(ordering) - override protected def fromSpecific(coll: IterableOnce[(K, V @uncheckedVariance)]): CC[K, V @uncheckedVariance] = sortedMapFactory.from(coll)(ordering) - override protected def newSpecificBuilder: mutable.Builder[(K, V @uncheckedVariance), CC[K, V @uncheckedVariance]] = sortedMapFactory.newBuilder[K, V](ordering) + override def empty: CC[K, V @uncheckedVariance] = sortedMapFactory.empty(using ordering) + override protected def fromSpecific(coll: IterableOnce[(K, V @uncheckedVariance)]): CC[K, V @uncheckedVariance] = sortedMapFactory.from(coll)(using ordering) + override protected def newSpecificBuilder: mutable.Builder[(K, V @uncheckedVariance), CC[K, V @uncheckedVariance]] = sortedMapFactory.newBuilder[K, V](using ordering) override def withFilter(p: ((K, V)) => Boolean): collection.SortedMapOps.WithFilter[K, V, WithFilterCC, UnsortedCC, CC] = new collection.SortedMapOps.WithFilter[K, V, WithFilterCC, UnsortedCC, CC](this, p) diff --git a/src/library/scala/collection/IterableOnce.scala b/src/library/scala/collection/IterableOnce.scala index 724b5fd7cd9c..71bac9ca0052 100644 --- a/src/library/scala/collection/IterableOnce.scala +++ b/src/library/scala/collection/IterableOnce.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -40,6 +40,7 @@ import scala.runtime.{AbstractFunction1, AbstractFunction2} * without inheriting unwanted implementations. * * @define coll collection + * @define ccoll $coll */ trait IterableOnce[+A] extends Any { @@ -318,8 +319,6 @@ object IterableOnce { * The order of applications of the operator is unspecified and may be nondeterministic. * @define exactlyOnce * Each element appears exactly once in the computation. - * @define coll collection - * */ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => /////////////////////////////////////////////////////////////// Abstract methods that must be implemented @@ -436,54 +435,55 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => * @return a $coll containing the elements greater than or equal to * index `from` extending up to (but not including) index `until` * of this $coll. + * @example + * `List('a', 'b', 'c', 'd', 'e').slice(1, 3) == List('b', 'c')` */ def slice(from: Int, until: Int): C - /** Builds a new $coll by applying a function to all elements of this $coll. + /** Builds a new $ccoll by applying a function to all elements of this $coll. * * @param f the function to apply to each element. - * @tparam B the element type of the returned $coll. - * @return a new $coll resulting from applying the given function + * @tparam B the element type of the returned $ccoll. + * @return a new $ccoll resulting from applying the given function * `f` to each element of this $coll and collecting the results. */ def map[B](f: A => B): CC[B] - /** Builds a new $coll by applying a function to all elements of this $coll + /** Builds a new $ccoll by applying a function to all elements of this $coll * and using the elements of the resulting collections. * * For example: * * {{{ - * def getWords(lines: Seq[String]): Seq[String] = lines flatMap (line => line split "\\W+") + * def getWords(lines: Seq[String]): Seq[String] = lines.flatMap(line => line.split("\\W+")) * }}} * - * The type of the resulting collection is guided by the static type of $coll. This might + * The type of the resulting collection is guided by the static type of this $coll. This might * cause unexpected results sometimes. For example: * * {{{ * // lettersOf will return a Seq[Char] of likely repeated letters, instead of a Set - * def lettersOf(words: Seq[String]) = words flatMap (word => word.toSet) + * def lettersOf(words: Seq[String]) = words.flatMap(word => word.toSet) * * // lettersOf will return a Set[Char], not a Seq - * def lettersOf(words: Seq[String]) = words.toSet flatMap ((word: String) => word.toSeq) + * def lettersOf(words: Seq[String]) = words.toSet.flatMap(word => word.toSeq) * * // xs will be an Iterable[Int] - * val xs = Map("a" -> List(11,111), "b" -> List(22,222)).flatMap(_._2) + * val xs = Map("a" -> List(11, 111), "b" -> List(22, 222)).flatMap(_._2) * * // ys will be a Map[Int, Int] - * val ys = Map("a" -> List(1 -> 11,1 -> 111), "b" -> List(2 -> 22,2 -> 222)).flatMap(_._2) + * val ys = Map("a" -> List(1 -> 11, 1 -> 111), "b" -> List(2 -> 22, 2 -> 222)).flatMap(_._2) * }}} * * @param f the function to apply to each element. * @tparam B the element type of the returned collection. - * @return a new $coll resulting from applying the given collection-valued function + * @return a new $ccoll resulting from applying the given collection-valued function * `f` to each element of this $coll and concatenating the results. */ def flatMap[B](f: A => IterableOnce[B]): CC[B] - /** Converts this $coll of iterable collections into - * a $coll formed by the elements of these iterable - * collections. + /** Given that the elements of this collection are themselves iterable collections, + * converts this $coll into a $ccoll comprising the elements of these iterable collections. * * The resulting collection's type will be guided by the * type of $coll. For example: @@ -505,16 +505,16 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => * @tparam B the type of the elements of each iterable collection. * @param asIterable an implicit conversion which asserts that the element * type of this $coll is an `Iterable`. - * @return a new $coll resulting from concatenating all element ${coll}s. + * @return a new $ccoll resulting from concatenating all element collections. */ def flatten[B](implicit asIterable: A => IterableOnce[B]): CC[B] - /** Builds a new $coll by applying a partial function to all elements of this $coll + /** Builds a new $ccoll by applying a partial function to all elements of this $coll * on which the function is defined. * * @param pf the partial function which filters and maps the $coll. * @tparam B the element type of the returned $coll. - * @return a new $coll resulting from applying the given partial function + * @return a new $ccoll resulting from applying the given partial function * `pf` to each element on which it is defined and collecting the results. * The order of the elements is preserved. */ @@ -522,7 +522,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => /** Zips this $coll with its indices. * - * @return A new $coll containing pairs consisting of all elements of this $coll paired with their index. + * @return A new $ccoll containing pairs consisting of all elements of this $coll paired with their index. * Indices start at `0`. * @example * `List("a", "b", "c").zipWithIndex == List(("a", 0), ("b", 1), ("c", 2))` @@ -533,7 +533,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => * * Note: `c span p` is equivalent to (but possibly more efficient than) * `(c takeWhile p, c dropWhile p)`, provided the evaluation of the - * predicate `p` does not cause any side-effects. + * predicate `p` does not cause any side effects. * $orderDependent * * @param p the test predicate @@ -1243,7 +1243,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => * @param pf the partial function * @return an option value containing pf applied to the first * value for which it is defined, or `None` if none exists. - * @example `Seq("a", 1, 5L).collectFirst({ case x: Int => x*10 }) = Some(10)` + * @example `Seq("a", 1, 5L).collectFirst { case x: Int => x*10 } = Some(10)` */ def collectFirst[B](pf: PartialFunction[A, B]): Option[B] = { // Presumably the fastest way to get in and out of a partial function is for a sentinel function to return itself @@ -1372,7 +1372,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] => if (it.hasNext) { jsb.append(it.next()) while (it.hasNext) { - jsb.append(sep) + if (sep.length != 0) jsb.append(sep) jsb.append(it.next()) } } diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 3fe18e948f53..7c288bf58e9f 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -413,7 +413,17 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite @deprecated("Call scanRight on an Iterable instead.", "2.13.0") def scanRight[B](z: B)(op: (A, B) => B): Iterator[B] = ArrayBuffer.from(this).scanRight(z)(op).iterator - + + /** Finds index of the first element satisfying some predicate after or at some start index. + * + * $mayNotTerminateInf + * + * @param p the predicate used to test elements. + * @param from the start index + * @return the index `>= from` of the first element of this $coll that satisfies the predicate `p`, + * or `-1`, if none exists. + * @note Reuse: $consumesIterator + */ def indexWhere(p: A => Boolean, from: Int = 0): Int = { var i = math.max(from, 0) val dropped = drop(from) @@ -834,17 +844,14 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite * @param that the collection to compare * @tparam B the type of the elements of collection `that`. * @return `true` if both collections contain equal elements in the same order, `false` otherwise. - * - * @inheritdoc */ def sameElements[B >: A](that: IterableOnce[B]): Boolean = { val those = that.iterator - while (hasNext && those.hasNext) - if (next() != those.next()) - return false - // At that point we know that *at least one* iterator has no next element - // If *both* of them have no elements then the collections are the same - hasNext == those.hasNext + while (hasNext) { + if (!those.hasNext) return false + if (next() != those.next()) return false + } + !those.hasNext } /** Creates two new iterators that both iterate over the same elements @@ -1257,12 +1264,15 @@ object Iterator extends IterableFactory[Iterator] { else if (until <= lo) 0 // empty else if (unbounded) until - lo // now finite else adjustedBound min (until - lo) // keep lesser bound + val sum = dropping + lo if (rest == 0) empty + else if (sum < 0) { + dropping = Int.MaxValue + remaining = 0 + this.concat(new SliceIterator(underlying, start = sum - Int.MaxValue, limit = rest)) + } else { - dropping = { - val sum = dropping + lo - if (sum < 0) Int.MaxValue else sum - } + dropping = sum remaining = rest this } diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala index 569e4e8c60a7..7a803a685d3e 100644 --- a/src/library/scala/collection/JavaConverters.scala +++ b/src/library/scala/collection/JavaConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/LazyZipOps.scala b/src/library/scala/collection/LazyZipOps.scala index 011f62d2380d..a7a72ce882a8 100644 --- a/src/library/scala/collection/LazyZipOps.scala +++ b/src/library/scala/collection/LazyZipOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/LinearSeq.scala b/src/library/scala/collection/LinearSeq.scala index 449d58c866e3..965edecdadc7 100644 --- a/src/library/scala/collection/LinearSeq.scala +++ b/src/library/scala/collection/LinearSeq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala index 2f0ff0a34066..1b88058d3197 100644 --- a/src/library/scala/collection/Map.scala +++ b/src/library/scala/collection/Map.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/MapView.scala b/src/library/scala/collection/MapView.scala index 233509ed0df1..39742c434c41 100644 --- a/src/library/scala/collection/MapView.scala +++ b/src/library/scala/collection/MapView.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/Searching.scala b/src/library/scala/collection/Searching.scala index 874a06449aa9..8b8132870287 100644 --- a/src/library/scala/collection/Searching.scala +++ b/src/library/scala/collection/Searching.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/Seq.scala b/src/library/scala/collection/Seq.scala index 4ec1f89cd6f1..753d51b6a51d 100644 --- a/src/library/scala/collection/Seq.scala +++ b/src/library/scala/collection/Seq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -180,11 +180,11 @@ trait SeqOps[+A, +CC[_], +C] extends Any def appendedAll[B >: A](suffix: IterableOnce[B]): CC[B] = super.concat(suffix) /** Alias for `appendedAll`. */ - @`inline` final def :++ [B >: A](suffix: IterableOnce[B]): CC[B] = appendedAll(suffix) + @inline final def :++ [B >: A](suffix: IterableOnce[B]): CC[B] = appendedAll(suffix) // Make `concat` an alias for `appendedAll` so that it benefits from performance // overrides of this method - @`inline` final override def concat[B >: A](suffix: IterableOnce[B]): CC[B] = appendedAll(suffix) + @inline final override def concat[B >: A](suffix: IterableOnce[B]): CC[B] = appendedAll(suffix) /** Produces a new sequence which contains all elements of this $coll and also all elements of * a given sequence. `xs union ys` is equivalent to `xs ++ ys`. @@ -286,7 +286,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any * @param len the target length * @param elem the padding value * @tparam B the element type of the returned $coll. - * @return a new $coll consisting of + * @return a new $ccoll consisting of * all elements of this $coll followed by the minimal number of occurrences of `elem` so * that the resulting collection has a length of at least `len`. */ @@ -843,16 +843,23 @@ trait SeqOps[+A, +CC[_], +C] extends Any override def isEmpty: Boolean = lengthCompare(0) == 0 - /** Tests whether the elements of this collection are the same (and in the same order) - * as those of `that`. - */ + /** Checks whether corresponding elements of the given iterable collection + * compare equal (with respect to `==`) to elements of this $coll. + * + * @param that the collection to compare + * @tparam B the type of the elements of collection `that`. + * @return `true` if both collections contain equal elements in the same order, `false` otherwise. + */ def sameElements[B >: A](that: IterableOnce[B]): Boolean = { val thisKnownSize = knownSize - val knownSizeDifference = thisKnownSize != -1 && { + if (thisKnownSize != -1) { val thatKnownSize = that.knownSize - thatKnownSize != -1 && thisKnownSize != thatKnownSize + if (thatKnownSize != -1) { + if (thisKnownSize != thatKnownSize) return false + if (thisKnownSize == 0) return true + } } - !knownSizeDifference && iterator.sameElements(that) + iterator.sameElements(that) } /** Tests whether every element of this $coll relates to the @@ -878,7 +885,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any * * @param that the sequence of elements to remove * @return a new $coll which contains all elements of this $coll - * except some of occurrences of elements that also appear in `that`. + * except some of the occurrences of elements that also appear in `that`. * If an element value `x` appears * ''n'' times in `that`, then the first ''n'' occurrences of `x` will not form * part of the result, but any following occurrences will. diff --git a/src/library/scala/collection/SeqMap.scala b/src/library/scala/collection/SeqMap.scala index 05bf126aba02..f2b65dfbfb6f 100644 --- a/src/library/scala/collection/SeqMap.scala +++ b/src/library/scala/collection/SeqMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/SeqView.scala b/src/library/scala/collection/SeqView.scala index cddd39b9fddc..a45797892220 100644 --- a/src/library/scala/collection/SeqView.scala +++ b/src/library/scala/collection/SeqView.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,7 @@ package scala package collection import scala.annotation.nowarn +import scala.collection.generic.CommonErrors trait SeqView[+A] extends SeqOps[A, View, View[A]] with View[A] { @@ -95,7 +96,10 @@ object SeqView { def apply(idx: Int): A = if (idx < n) { underlying(idx) } else { - throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${if (underlying.knownSize >= 0) knownSize - 1 else "unknown"})") + throw ( + if (underlying.knownSize >= 0) CommonErrors.indexOutOfBounds(index = idx, max = knownSize - 1) + else CommonErrors.indexOutOfBounds(index = idx) + ) } def length: Int = underlying.length min normN } diff --git a/src/library/scala/collection/Set.scala b/src/library/scala/collection/Set.scala index 0ea1e5689473..bce5974ed5db 100644 --- a/src/library/scala/collection/Set.scala +++ b/src/library/scala/collection/Set.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -210,9 +210,7 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]] @deprecated("Use &- with an explicit collection argument instead of - with varargs", "2.13.0") def - (elem1: A, elem2: A, elems: A*): C = diff(elems.toSet + elem1 + elem2) - /** Creates a new $coll by adding all elements contained in another collection to this $coll, omitting duplicates. - * - * This method takes a collection of elements and adds all elements, omitting duplicates, into $coll. + /** Creates a new $ccoll by adding all elements contained in another collection to this $coll, omitting duplicates. * * Example: * {{{ diff --git a/src/library/scala/collection/SortedMap.scala b/src/library/scala/collection/SortedMap.scala index 03ab0bb0dadc..d2ccb9e38aa9 100644 --- a/src/library/scala/collection/SortedMap.scala +++ b/src/library/scala/collection/SortedMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -179,16 +179,16 @@ trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], override def concat[V2 >: V](suffix: IterableOnce[(K, V2)]): CC[K, V2] = sortedMapFactory.from(suffix match { case it: Iterable[(K, V2)] => new View.Concat(this, it) case _ => iterator.concat(suffix.iterator) - })(ordering) + })(using ordering) /** Alias for `concat` */ @`inline` override final def ++ [V2 >: V](xs: IterableOnce[(K, V2)]): CC[K, V2] = concat(xs) @deprecated("Consider requiring an immutable Map or fall back to Map.concat", "2.13.0") - override def + [V1 >: V](kv: (K, V1)): CC[K, V1] = sortedMapFactory.from(new View.Appended(this, kv))(ordering) + override def + [V1 >: V](kv: (K, V1)): CC[K, V1] = sortedMapFactory.from(new View.Appended(this, kv))(using ordering) @deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0") - override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] = sortedMapFactory.from(new View.Concat(new View.Appended(new View.Appended(this, elem1), elem2), elems))(ordering) + override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] = sortedMapFactory.from(new View.Concat(new View.Appended(new View.Appended(this, elem1), elem2), elems))(using ordering) } object SortedMapOps { diff --git a/src/library/scala/collection/SortedOps.scala b/src/library/scala/collection/SortedOps.scala index 64e6376be042..bd034fbf14d6 100644 --- a/src/library/scala/collection/SortedOps.scala +++ b/src/library/scala/collection/SortedOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/SortedSet.scala b/src/library/scala/collection/SortedSet.scala index c98ca9ae5523..37c28c260000 100644 --- a/src/library/scala/collection/SortedSet.scala +++ b/src/library/scala/collection/SortedSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -57,6 +57,7 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]] */ def sortedIterableFactory: SortedIterableFactory[CC] + /** Widens the type of this set to its unsorted counterpart. */ def unsorted: Set[A] /** diff --git a/src/library/scala/collection/Stepper.scala b/src/library/scala/collection/Stepper.scala index 0eeb8a44cb72..f1355e8182c3 100644 --- a/src/library/scala/collection/Stepper.scala +++ b/src/library/scala/collection/Stepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StepperShape.scala b/src/library/scala/collection/StepperShape.scala index 6712073b09e4..db8c00b47992 100644 --- a/src/library/scala/collection/StepperShape.scala +++ b/src/library/scala/collection/StepperShape.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StrictOptimizedIterableOps.scala b/src/library/scala/collection/StrictOptimizedIterableOps.scala index a09766cfa912..3260c1bc262e 100644 --- a/src/library/scala/collection/StrictOptimizedIterableOps.scala +++ b/src/library/scala/collection/StrictOptimizedIterableOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StrictOptimizedMapOps.scala b/src/library/scala/collection/StrictOptimizedMapOps.scala index 1f5791bbb718..a87ba3ee9e20 100644 --- a/src/library/scala/collection/StrictOptimizedMapOps.scala +++ b/src/library/scala/collection/StrictOptimizedMapOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StrictOptimizedSeqOps.scala b/src/library/scala/collection/StrictOptimizedSeqOps.scala index 2eef55132610..a131498d8b28 100644 --- a/src/library/scala/collection/StrictOptimizedSeqOps.scala +++ b/src/library/scala/collection/StrictOptimizedSeqOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StrictOptimizedSetOps.scala b/src/library/scala/collection/StrictOptimizedSetOps.scala index 356bd2883578..39e585324f45 100644 --- a/src/library/scala/collection/StrictOptimizedSetOps.scala +++ b/src/library/scala/collection/StrictOptimizedSetOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StrictOptimizedSortedMapOps.scala b/src/library/scala/collection/StrictOptimizedSortedMapOps.scala index 1beaf1662abe..8317913c6d1b 100644 --- a/src/library/scala/collection/StrictOptimizedSortedMapOps.scala +++ b/src/library/scala/collection/StrictOptimizedSortedMapOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -33,7 +33,7 @@ trait StrictOptimizedSortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOp strictOptimizedFlatMap(sortedMapFactory.newBuilder, f) override def concat[V2 >: V](xs: IterableOnce[(K, V2)]): CC[K, V2] = - strictOptimizedConcat(xs, sortedMapFactory.newBuilder(ordering)) + strictOptimizedConcat(xs, sortedMapFactory.newBuilder(using ordering)) override def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] = strictOptimizedCollect(sortedMapFactory.newBuilder, pf) diff --git a/src/library/scala/collection/StrictOptimizedSortedSetOps.scala b/src/library/scala/collection/StrictOptimizedSortedSetOps.scala index ded7deabccca..c01b0d8466f3 100644 --- a/src/library/scala/collection/StrictOptimizedSortedSetOps.scala +++ b/src/library/scala/collection/StrictOptimizedSortedSetOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/StringOps.scala b/src/library/scala/collection/StringOps.scala index 943125075d5a..f641c792156a 100644 --- a/src/library/scala/collection/StringOps.scala +++ b/src/library/scala/collection/StringOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -26,9 +26,7 @@ import scala.util.matching.Regex object StringOps { // just statics for companion class. private final val LF = 0x0A - private final val FF = 0x0C private final val CR = 0x0D - private final val SU = 0x1A private class StringIterator(private[this] val s: String) extends AbstractIterator[Char] { private[this] var pos = 0 @@ -180,14 +178,14 @@ object StringOps { final class StringOps(private val s: String) extends AnyVal { import StringOps._ - @`inline` def view: StringView = new StringView(s) + @inline def view: StringView = new StringView(s) - @`inline` def size: Int = s.length + @inline def size: Int = s.length - @`inline` def knownSize: Int = s.length + @inline def knownSize: Int = s.length /** Get the char at the specified index. */ - @`inline` def apply(i: Int): Char = s.charAt(i) + @inline def apply(i: Int): Char = s.charAt(i) def sizeCompare(otherSize: Int): Int = Integer.compare(s.length, otherSize) @@ -344,13 +342,13 @@ final class StringOps(private val s: String) extends AnyVal { * @return a new string which contains all chars * of this string followed by all chars of `suffix`. */ - @`inline` def concat(suffix: String): String = s + suffix + @inline def concat(suffix: String): String = s + suffix /** Alias for `concat` */ - @`inline` def ++[B >: Char](suffix: Iterable[B]): immutable.IndexedSeq[B] = concat(suffix) + @inline def ++[B >: Char](suffix: Iterable[B]): immutable.IndexedSeq[B] = concat(suffix) /** Alias for `concat` */ - @`inline` def ++(suffix: IterableOnce[Char]): String = concat(suffix) + @inline def ++(suffix: IterableOnce[Char]): String = concat(suffix) /** Alias for `concat` */ def ++(xs: String): String = concat(xs) @@ -412,14 +410,14 @@ final class StringOps(private val s: String) extends AnyVal { } /** Alias for `prepended` */ - @`inline` def +: [B >: Char] (elem: B): immutable.IndexedSeq[B] = prepended(elem) + @inline def +: [B >: Char] (elem: B): immutable.IndexedSeq[B] = prepended(elem) /** A copy of the string with an char prepended */ def prepended(c: Char): String = new JStringBuilder(s.length + 1).append(c).append(s).toString /** Alias for `prepended` */ - @`inline` def +: (c: Char): String = prepended(c) + @inline def +: (c: Char): String = prepended(c) /** A copy of the string with all elements from a collection prepended */ def prependedAll[B >: Char](prefix: IterableOnce[B]): immutable.IndexedSeq[B] = { @@ -432,13 +430,13 @@ final class StringOps(private val s: String) extends AnyVal { } /** Alias for `prependedAll` */ - @`inline` def ++: [B >: Char] (prefix: IterableOnce[B]): immutable.IndexedSeq[B] = prependedAll(prefix) + @inline def ++: [B >: Char] (prefix: IterableOnce[B]): immutable.IndexedSeq[B] = prependedAll(prefix) /** A copy of the string with another string prepended */ def prependedAll(prefix: String): String = prefix + s /** Alias for `prependedAll` */ - @`inline` def ++: (prefix: String): String = prependedAll(prefix) + @inline def ++: (prefix: String): String = prependedAll(prefix) /** A copy of the string with an element appended */ def appended[B >: Char](elem: B): immutable.IndexedSeq[B] = { @@ -450,28 +448,28 @@ final class StringOps(private val s: String) extends AnyVal { } /** Alias for `appended` */ - @`inline` def :+ [B >: Char](elem: B): immutable.IndexedSeq[B] = appended(elem) + @inline def :+ [B >: Char](elem: B): immutable.IndexedSeq[B] = appended(elem) /** A copy of the string with an element appended */ def appended(c: Char): String = new JStringBuilder(s.length + 1).append(s).append(c).toString /** Alias for `appended` */ - @`inline` def :+ (c: Char): String = appended(c) + @inline def :+ (c: Char): String = appended(c) /** A copy of the string with all elements from a collection appended */ - @`inline` def appendedAll[B >: Char](suffix: IterableOnce[B]): immutable.IndexedSeq[B] = + @inline def appendedAll[B >: Char](suffix: IterableOnce[B]): immutable.IndexedSeq[B] = concat(suffix) /** Alias for `appendedAll` */ - @`inline` def :++ [B >: Char](suffix: IterableOnce[B]): immutable.IndexedSeq[B] = + @inline def :++ [B >: Char](suffix: IterableOnce[B]): immutable.IndexedSeq[B] = concat(suffix) /** A copy of the string with another string appended */ - @`inline` def appendedAll(suffix: String): String = s + suffix + @inline def appendedAll(suffix: String): String = s + suffix /** Alias for `appendedAll` */ - @`inline` def :++ (suffix: String): String = s + suffix + @inline def :++ (suffix: String): String = s + suffix /** Produces a new collection where a slice of characters in this string is replaced by another collection. * @@ -488,7 +486,7 @@ final class StringOps(private val s: String) extends AnyVal { */ def patch[B >: Char](from: Int, other: IterableOnce[B], replaced: Int): immutable.IndexedSeq[B] = { val len = s.length - @`inline` def slc(off: Int, length: Int): WrappedString = + @inline def slc(off: Int, length: Int): WrappedString = new WrappedString(s.substring(off, off+length)) val b = immutable.IndexedSeq.newBuilder[B] val k = other.knownSize @@ -645,8 +643,8 @@ final class StringOps(private val s: String) extends AnyVal { // Note: String.repeat is added in JDK 11. /** Return the current string concatenated `n` times. - */ - def *(n: Int): String = { + */ + def *(n: Int): String = if (n <= 0) { "" } else { @@ -658,10 +656,9 @@ final class StringOps(private val s: String) extends AnyVal { } sb.toString } - } - @`inline` private[this] def isLineBreak(c: Char) = c == CR || c == LF - @`inline` private[this] def isLineBreak2(c0: Char, c: Char) = c0 == CR && c == LF + @inline private def isLineBreak(c: Char) = c == CR || c == LF + @inline private def isLineBreak2(c0: Char, c: Char) = c0 == CR && c == LF /** Strip the trailing line separator from this string if there is one. * The line separator is taken as `"\n"`, `"\r"`, or `"\r\n"`. @@ -698,7 +695,7 @@ final class StringOps(private val s: String) extends AnyVal { private[this] val len = s.length private[this] var index = 0 - @`inline` private def done = index >= len + @inline private def done = index >= len private def advance(): String = { val start = index while (!done && !isLineBreak(apply(index))) index += 1 @@ -1118,7 +1115,7 @@ final class StringOps(private val s: String) extends AnyVal { * @return The result of applying `op` to `z` and all chars in this string, * going left to right. Returns `z` if this string is empty. */ - @`inline` def fold[A1 >: Char](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op) + @inline def fold[A1 >: Char](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op) /** Selects the first char of this string. * @return the first char of this string. @@ -1158,19 +1155,19 @@ final class StringOps(private val s: String) extends AnyVal { /** Stepper can be used with Java 8 Streams. This method is equivalent to a call to * [[charStepper]]. See also [[codePointStepper]]. */ - @`inline` def stepper: IntStepper with EfficientSplit = charStepper + @inline def stepper: IntStepper with EfficientSplit = charStepper /** Steps over characters in this string. Values are packed in `Int` for efficiency * and compatibility with Java 8 Streams which have an efficient specialization for `Int`. */ - @`inline` def charStepper: IntStepper with EfficientSplit = new CharStringStepper(s, 0, s.length) + @inline def charStepper: IntStepper with EfficientSplit = new CharStringStepper(s, 0, s.length) /** Steps over code points in this string. */ - @`inline` def codePointStepper: IntStepper with EfficientSplit = new CodePointStringStepper(s, 0, s.length) + @inline def codePointStepper: IntStepper with EfficientSplit = new CodePointStringStepper(s, 0, s.length) /** Tests whether the string is not empty. */ - @`inline` def nonEmpty: Boolean = !s.isEmpty + @inline def nonEmpty: Boolean = !s.isEmpty /** Returns new sequence with elements in reversed order. * @note $unicodeunaware @@ -1201,14 +1198,16 @@ final class StringOps(private val s: String) extends AnyVal { def withFilter(p: Char => Boolean): StringOps.WithFilter = new StringOps.WithFilter(p, s) /** The rest of the string without its first char. - * @note $unicodeunaware - */ - def tail: String = slice(1, s.length) + * @throws UnsupportedOperationException if the string is empty. + * @note $unicodeunaware + */ + def tail: String = if(s.isEmpty) throw new UnsupportedOperationException("tail of empty String") else slice(1, s.length) /** The initial part of the string without its last char. - * @note $unicodeunaware - */ - def init: String = slice(0, s.length-1) + * @throws UnsupportedOperationException if the string is empty. + * @note $unicodeunaware + */ + def init: String = if(s.isEmpty) throw new UnsupportedOperationException("init of empty String") else slice(0, s.length-1) /** A string containing the first `n` chars of this string. * @note $unicodeunaware @@ -1266,7 +1265,7 @@ final class StringOps(private val s: String) extends AnyVal { } /** Selects all chars of this string which do not satisfy a predicate. */ - @`inline` def filterNot(pred: Char => Boolean): String = filter(c => !pred(c)) + @inline def filterNot(pred: Char => Boolean): String = filter(c => !pred(c)) /** Copy chars of this string to an array. * Fills the given array `xs` starting at index 0. @@ -1275,7 +1274,7 @@ final class StringOps(private val s: String) extends AnyVal { * * @param xs the array to fill. */ - @`inline` def copyToArray(xs: Array[Char]): Int = + @inline def copyToArray(xs: Array[Char]): Int = copyToArray(xs, 0, Int.MaxValue) /** Copy chars of this string to an array. @@ -1286,7 +1285,7 @@ final class StringOps(private val s: String) extends AnyVal { * @param xs the array to fill. * @param start the starting index. */ - @`inline` def copyToArray(xs: Array[Char], start: Int): Int = + @inline def copyToArray(xs: Array[Char], start: Int): Int = copyToArray(xs, start, Int.MaxValue) /** Copy chars of this string to an array. diff --git a/src/library/scala/collection/StringParsers.scala b/src/library/scala/collection/StringParsers.scala index 07148f04f9b0..36108dc539da 100644 --- a/src/library/scala/collection/StringParsers.scala +++ b/src/library/scala/collection/StringParsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/View.scala b/src/library/scala/collection/View.scala index 87849744a5dc..f304b8931f14 100644 --- a/src/library/scala/collection/View.scala +++ b/src/library/scala/collection/View.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/WithFilter.scala b/src/library/scala/collection/WithFilter.scala index 4699abbef5a7..7a68275336ff 100644 --- a/src/library/scala/collection/WithFilter.scala +++ b/src/library/scala/collection/WithFilter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/BasicNode.java b/src/library/scala/collection/concurrent/BasicNode.java index c6ec91e4fde8..b6a628d1295e 100644 --- a/src/library/scala/collection/concurrent/BasicNode.java +++ b/src/library/scala/collection/concurrent/BasicNode.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/CNodeBase.java b/src/library/scala/collection/concurrent/CNodeBase.java index ddffa365234e..4033c12af449 100644 --- a/src/library/scala/collection/concurrent/CNodeBase.java +++ b/src/library/scala/collection/concurrent/CNodeBase.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/Gen.java b/src/library/scala/collection/concurrent/Gen.java index 07af2983f32d..548c1892321f 100644 --- a/src/library/scala/collection/concurrent/Gen.java +++ b/src/library/scala/collection/concurrent/Gen.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/INodeBase.java b/src/library/scala/collection/concurrent/INodeBase.java index dfb99806594f..b16265c68ea3 100644 --- a/src/library/scala/collection/concurrent/INodeBase.java +++ b/src/library/scala/collection/concurrent/INodeBase.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/MainNode.java b/src/library/scala/collection/concurrent/MainNode.java index f7f022974e9e..1bfc11594ec9 100644 --- a/src/library/scala/collection/concurrent/MainNode.java +++ b/src/library/scala/collection/concurrent/MainNode.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/Map.scala b/src/library/scala/collection/concurrent/Map.scala index bff9bf2ecbc9..291f85513b58 100644 --- a/src/library/scala/collection/concurrent/Map.scala +++ b/src/library/scala/collection/concurrent/Map.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala index b06baa0f474c..ddc5379f1f25 100644 --- a/src/library/scala/collection/concurrent/TrieMap.scala +++ b/src/library/scala/collection/concurrent/TrieMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/AsJavaConverters.scala b/src/library/scala/collection/convert/AsJavaConverters.scala index 3d155337aa93..2fc73da64fe7 100644 --- a/src/library/scala/collection/convert/AsJavaConverters.scala +++ b/src/library/scala/collection/convert/AsJavaConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/AsJavaExtensions.scala b/src/library/scala/collection/convert/AsJavaExtensions.scala index 16b15c513a17..d356a419325d 100644 --- a/src/library/scala/collection/convert/AsJavaExtensions.scala +++ b/src/library/scala/collection/convert/AsJavaExtensions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/AsScalaConverters.scala b/src/library/scala/collection/convert/AsScalaConverters.scala index 30a28ae38147..e1055c60b36e 100644 --- a/src/library/scala/collection/convert/AsScalaConverters.scala +++ b/src/library/scala/collection/convert/AsScalaConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/AsScalaExtensions.scala b/src/library/scala/collection/convert/AsScalaExtensions.scala index 39347dde903b..ef08f4505fe1 100644 --- a/src/library/scala/collection/convert/AsScalaExtensions.scala +++ b/src/library/scala/collection/convert/AsScalaExtensions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/ImplicitConversions.scala b/src/library/scala/collection/convert/ImplicitConversions.scala index 05d63f9fdeee..6492c60d6d9e 100644 --- a/src/library/scala/collection/convert/ImplicitConversions.scala +++ b/src/library/scala/collection/convert/ImplicitConversions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/JavaCollectionWrappers.scala b/src/library/scala/collection/convert/JavaCollectionWrappers.scala index b41bd50d4f35..f79adff98e23 100644 --- a/src/library/scala/collection/convert/JavaCollectionWrappers.scala +++ b/src/library/scala/collection/convert/JavaCollectionWrappers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/StreamExtensions.scala b/src/library/scala/collection/convert/StreamExtensions.scala index cdeea62fb5ed..90b8bcb9031d 100644 --- a/src/library/scala/collection/convert/StreamExtensions.scala +++ b/src/library/scala/collection/convert/StreamExtensions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/ArrayStepper.scala b/src/library/scala/collection/convert/impl/ArrayStepper.scala index 845ecb4a606d..4e8408bca99a 100644 --- a/src/library/scala/collection/convert/impl/ArrayStepper.scala +++ b/src/library/scala/collection/convert/impl/ArrayStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/BinaryTreeStepper.scala b/src/library/scala/collection/convert/impl/BinaryTreeStepper.scala index 7c795aea5391..d15977eced17 100644 --- a/src/library/scala/collection/convert/impl/BinaryTreeStepper.scala +++ b/src/library/scala/collection/convert/impl/BinaryTreeStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/BitSetStepper.scala b/src/library/scala/collection/convert/impl/BitSetStepper.scala index 574e7fd50f1c..905afaaf4a0d 100644 --- a/src/library/scala/collection/convert/impl/BitSetStepper.scala +++ b/src/library/scala/collection/convert/impl/BitSetStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/ChampStepper.scala b/src/library/scala/collection/convert/impl/ChampStepper.scala index 466e6c440f45..ddf7c34dc65a 100644 --- a/src/library/scala/collection/convert/impl/ChampStepper.scala +++ b/src/library/scala/collection/convert/impl/ChampStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/InOrderStepperBase.scala b/src/library/scala/collection/convert/impl/InOrderStepperBase.scala index 2d1f88d02930..476b5c882177 100644 --- a/src/library/scala/collection/convert/impl/InOrderStepperBase.scala +++ b/src/library/scala/collection/convert/impl/InOrderStepperBase.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/IndexedSeqStepper.scala b/src/library/scala/collection/convert/impl/IndexedSeqStepper.scala index 136ac8d2dcc3..aa8fbe307278 100644 --- a/src/library/scala/collection/convert/impl/IndexedSeqStepper.scala +++ b/src/library/scala/collection/convert/impl/IndexedSeqStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/IndexedStepperBase.scala b/src/library/scala/collection/convert/impl/IndexedStepperBase.scala index 4670ccc56bfc..d2094dd30da6 100644 --- a/src/library/scala/collection/convert/impl/IndexedStepperBase.scala +++ b/src/library/scala/collection/convert/impl/IndexedStepperBase.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/IteratorStepper.scala b/src/library/scala/collection/convert/impl/IteratorStepper.scala index 68b318c04c9c..8fac29cf96ae 100644 --- a/src/library/scala/collection/convert/impl/IteratorStepper.scala +++ b/src/library/scala/collection/convert/impl/IteratorStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/NumericRangeStepper.scala b/src/library/scala/collection/convert/impl/NumericRangeStepper.scala index 89e17bbf467c..3a03f8fabf63 100644 --- a/src/library/scala/collection/convert/impl/NumericRangeStepper.scala +++ b/src/library/scala/collection/convert/impl/NumericRangeStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/RangeStepper.scala b/src/library/scala/collection/convert/impl/RangeStepper.scala index 282ddb4aa2ad..46f803151704 100644 --- a/src/library/scala/collection/convert/impl/RangeStepper.scala +++ b/src/library/scala/collection/convert/impl/RangeStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/StringStepper.scala b/src/library/scala/collection/convert/impl/StringStepper.scala index 8990f462b4fd..e8c4d7073c43 100644 --- a/src/library/scala/collection/convert/impl/StringStepper.scala +++ b/src/library/scala/collection/convert/impl/StringStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/TableStepper.scala b/src/library/scala/collection/convert/impl/TableStepper.scala index cac041a5237b..2c144e4fae8f 100644 --- a/src/library/scala/collection/convert/impl/TableStepper.scala +++ b/src/library/scala/collection/convert/impl/TableStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/convert/impl/VectorStepper.scala b/src/library/scala/collection/convert/impl/VectorStepper.scala index 332ec65d85fd..ca0d45330a70 100644 --- a/src/library/scala/collection/convert/impl/VectorStepper.scala +++ b/src/library/scala/collection/convert/impl/VectorStepper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/generic/BitOperations.scala b/src/library/scala/collection/generic/BitOperations.scala index 4c64dec9dc1f..4464b4935d07 100644 --- a/src/library/scala/collection/generic/BitOperations.scala +++ b/src/library/scala/collection/generic/BitOperations.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/generic/CommonErrors.scala b/src/library/scala/collection/generic/CommonErrors.scala new file mode 100644 index 000000000000..e9f863643d27 --- /dev/null +++ b/src/library/scala/collection/generic/CommonErrors.scala @@ -0,0 +1,29 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.collection +package generic + + +/** Some precomputed common errors to reduce the generated code size. + */ +private[collection] object CommonErrors { + /** IndexOutOfBounds exception with a known max index */ + @noinline + def indexOutOfBounds(index: Int, max: Int): IndexOutOfBoundsException = + new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${max})") + + /** IndexOutOfBounds exception with an unknown max index. */ + @noinline + def indexOutOfBounds(index: Int): IndexOutOfBoundsException = + new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max unknown)") +} diff --git a/src/library/scala/collection/generic/DefaultSerializationProxy.scala b/src/library/scala/collection/generic/DefaultSerializationProxy.scala index 69b4b3d96e61..2e584eaa427d 100644 --- a/src/library/scala/collection/generic/DefaultSerializationProxy.scala +++ b/src/library/scala/collection/generic/DefaultSerializationProxy.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -77,9 +77,9 @@ private[collection] case object SerializeEnd trait DefaultSerializable extends Serializable { this: scala.collection.Iterable[_] => protected[this] def writeReplace(): AnyRef = { val f: Factory[Any, Any] = this match { - case it: scala.collection.SortedMap[_, _] => it.sortedMapFactory.sortedMapFactory[Any, Any](it.ordering.asInstanceOf[Ordering[Any]]).asInstanceOf[Factory[Any, Any]] + case it: scala.collection.SortedMap[_, _] => it.sortedMapFactory.sortedMapFactory[Any, Any](using it.ordering.asInstanceOf[Ordering[Any]]).asInstanceOf[Factory[Any, Any]] case it: scala.collection.Map[_, _] => it.mapFactory.mapFactory[Any, Any].asInstanceOf[Factory[Any, Any]] - case it: scala.collection.SortedSet[_] => it.sortedIterableFactory.evidenceIterableFactory[Any](it.ordering.asInstanceOf[Ordering[Any]]) + case it: scala.collection.SortedSet[_] => it.sortedIterableFactory.evidenceIterableFactory[Any](using it.ordering.asInstanceOf[Ordering[Any]]) case it => it.iterableFactory.iterableFactory } new DefaultSerializationProxy(f, this) diff --git a/src/library/scala/collection/generic/IsIterable.scala b/src/library/scala/collection/generic/IsIterable.scala index bf2eab6bb2a6..2260f0f2aacb 100644 --- a/src/library/scala/collection/generic/IsIterable.scala +++ b/src/library/scala/collection/generic/IsIterable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/generic/IsIterableOnce.scala b/src/library/scala/collection/generic/IsIterableOnce.scala index 7d7293037bd4..82f0ec8b7332 100644 --- a/src/library/scala/collection/generic/IsIterableOnce.scala +++ b/src/library/scala/collection/generic/IsIterableOnce.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/generic/IsMap.scala b/src/library/scala/collection/generic/IsMap.scala index 19f75cf7bced..6178b2f2b7ca 100644 --- a/src/library/scala/collection/generic/IsMap.scala +++ b/src/library/scala/collection/generic/IsMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -75,6 +75,7 @@ object IsMap { } // AnyRefMap has stricter bounds than the ones used by the mapOpsIsMap definition + @deprecated("AnyRefMap is deprecated", "2.13.16") implicit def anyRefMapIsMap[K0 <: AnyRef, V0]: IsMap[mutable.AnyRefMap[K0, V0]] { type K = K0; type V = V0; type C = mutable.AnyRefMap[K0, V0] } = new IsMap[mutable.AnyRefMap[K0, V0]] { type K = K0 diff --git a/src/library/scala/collection/generic/IsSeq.scala b/src/library/scala/collection/generic/IsSeq.scala index 69ea27d087d1..73d0cc9762d6 100644 --- a/src/library/scala/collection/generic/IsSeq.scala +++ b/src/library/scala/collection/generic/IsSeq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/generic/Subtractable.scala b/src/library/scala/collection/generic/Subtractable.scala index 223997f4e972..f8af03581aad 100644 --- a/src/library/scala/collection/generic/Subtractable.scala +++ b/src/library/scala/collection/generic/Subtractable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/generic/package.scala b/src/library/scala/collection/generic/package.scala index 0c16aa04dc98..5aaf90547384 100644 --- a/src/library/scala/collection/generic/package.scala +++ b/src/library/scala/collection/generic/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/ArraySeq.scala b/src/library/scala/collection/immutable/ArraySeq.scala index b006db25ce82..eafe9baa719f 100644 --- a/src/library/scala/collection/immutable/ArraySeq.scala +++ b/src/library/scala/collection/immutable/ArraySeq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala index 1b15b029ed91..a9b5837ff566 100644 --- a/src/library/scala/collection/immutable/BitSet.scala +++ b/src/library/scala/collection/immutable/BitSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/ChampCommon.scala b/src/library/scala/collection/immutable/ChampCommon.scala index 2f6e8e7d45df..7b3e3949a126 100644 --- a/src/library/scala/collection/immutable/ChampCommon.scala +++ b/src/library/scala/collection/immutable/ChampCommon.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 08fb4f894d08..e9257f1948fc 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -144,7 +144,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: rootNode.getOrElse(key, keyUnimprovedHash, keyHash, 0, default) } - @`inline` private[this] def newHashMapOrThis[V1 >: V](newRootNode: BitmapIndexedMapNode[K, V1]): HashMap[K, V1] = + @inline private[this] def newHashMapOrThis[V1 >: V](newRootNode: BitmapIndexedMapNode[K, V1]): HashMap[K, V1] = if (newRootNode eq rootNode) this else new HashMap(newRootNode) def updated[V1 >: V](key: K, value: V1): HashMap[K, V1] = { @@ -167,7 +167,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: else { val newNode = rootNode.concat(hm.rootNode, 0) if (newNode eq hm.rootNode) hm - else newHashMapOrThis(rootNode.concat(hm.rootNode, 0)) + else newHashMapOrThis(newNode) } case hm: mutable.HashMap[K @unchecked, V @unchecked] => val iter = hm.nodeIterator @@ -271,7 +271,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: override def foreachEntry[U](f: (K, V) => U): Unit = rootNode.foreachEntry(f) /** Applies a function to each key, value, and **original** hash value in this Map */ - @`inline` private[collection] def foreachWithHash(f: (K, V, Int) => Unit): Unit = rootNode.foreachWithHash(f) + @inline private[collection] def foreachWithHash(f: (K, V, Int) => Unit): Unit = rootNode.foreachWithHash(f) override def equals(that: Any): Boolean = that match { @@ -1310,7 +1310,7 @@ private final class BitmapIndexedMapNode[K, +V]( } } case _: HashCollisionMapNode[_, _] => - throw new Exception("Cannot merge BitmapIndexedMapNode with HashCollisionMapNode") + throw new RuntimeException("Cannot merge BitmapIndexedMapNode with HashCollisionMapNode") } override def equals(that: Any): Boolean = @@ -1326,7 +1326,7 @@ private final class BitmapIndexedMapNode[K, +V]( case _ => false } - @`inline` private def deepContentEquality(a1: Array[Any], a2: Array[Any], length: Int): Boolean = { + @inline private def deepContentEquality(a1: Array[Any], a2: Array[Any], length: Int): Boolean = { if (a1 eq a2) true else { @@ -2061,7 +2061,7 @@ private final class HashCollisionMapNode[K, +V ]( i += 1 } case _: BitmapIndexedMapNode[K, V1] => - throw new Exception("Cannot merge HashCollisionMapNode with BitmapIndexedMapNode") + throw new RuntimeException("Cannot merge HashCollisionMapNode with BitmapIndexedMapNode") } diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index aa202b61ff03..3c72236a5395 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/IntMap.scala b/src/library/scala/collection/immutable/IntMap.scala index f421bd6ddf20..1aa1a6108d0c 100644 --- a/src/library/scala/collection/immutable/IntMap.scala +++ b/src/library/scala/collection/immutable/IntMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/Iterable.scala b/src/library/scala/collection/immutable/Iterable.scala index d4199ab3ab14..a38c60ed8cc2 100644 --- a/src/library/scala/collection/immutable/Iterable.scala +++ b/src/library/scala/collection/immutable/Iterable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/LazyList.scala b/src/library/scala/collection/immutable/LazyList.scala index b6af234150e2..72425cf7045a 100644 --- a/src/library/scala/collection/immutable/LazyList.scala +++ b/src/library/scala/collection/immutable/LazyList.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -28,35 +28,49 @@ import scala.runtime.Statics * * Elements are memoized; that is, the value of each element is computed at most once. * - * Elements are computed in-order and are never skipped. In other words, - * accessing the tail causes the head to be computed first. + * Elements are computed in order and are never skipped. + * As a consequence, accessing the tail causes the head to be computed first. * * How lazy is a `LazyList`? When you have a value of type `LazyList`, you - * don't know yet whether the list is empty or not. If you learn that it is non-empty, - * then you also know that the head has been computed. But the tail is itself - * a `LazyList`, whose emptiness-or-not might remain undetermined. + * don't know yet whether the list is empty. + * We say that it is lazy in its head. + * If you have tested that it is non-empty, + * then you also know that the head has been computed. + * + * It is also lazy in its tail, which is also a `LazyList`. + * You don't know whether the tail is empty until it is "forced", which is to say, + * until an element of the tail is computed. + * + * These important properties of `LazyList` depend on its construction using `#::` (or `#:::`). + * That operator is analogous to the "cons" of a strict `List`, `::`. + * It is "right-associative", so that the collection goes on the "right", + * and the element on the left of the operator is prepended to the collection. + * However, unlike the cons of a strict `List`, `#::` is lazy in its parameter, + * which is the element prepended to the left, and also lazy in its right-hand side, + * which is the `LazyList` being prepended to. + * (That is accomplished by implicitly wrapping the `LazyList`, as shown in the Scaladoc.) + * + * Other combinators from the collections API do not preserve this laziness. + * In particular, `++`, or `concat`, is "eager" or "strict" in its parameter + * and should not be used to compose `LazyList`s. * * A `LazyList` may be infinite. For example, `LazyList.from(0)` contains - * all of the natural numbers 0, 1, 2, and so on. For infinite sequences, + * all of the natural numbers `0`, `1`, `2`, ... For infinite sequences, * some methods (such as `count`, `sum`, `max` or `min`) will not terminate. * - * Here is an example: + * Here is an example showing the Fibonacci sequence, + * which may be evaluated to an arbitrary number of elements: * * {{{ * import scala.math.BigInt * object Main extends App { * val fibs: LazyList[BigInt] = - * BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map{ n => n._1 + n._2 } - * fibs.take(5).foreach(println) + * BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map(n => n._1 + n._2) + * println { + * fibs.take(5).mkString(", ") + * } * } - * - * // prints - * // - * // 0 - * // 1 - * // 1 - * // 2 - * // 3 + * // prints: 0, 1, 1, 2, 3 * }}} * * To illustrate, let's add some output to the definition `fibs`, so we @@ -64,13 +78,12 @@ import scala.runtime.Statics * * {{{ * import scala.math.BigInt + * import scala.util.chaining._ * object Main extends App { * val fibs: LazyList[BigInt] = * BigInt(0) #:: BigInt(1) #:: - * fibs.zip(fibs.tail).map{ n => - * println(s"Adding \${n._1} and \${n._2}") - * n._1 + n._2 - * } + * fibs.zip(fibs.tail).map(n => (n._1 + n._2) + * .tap(sum => println(s"Adding ${n._1} and ${n._2} => $sum"))) * fibs.take(5).foreach(println) * fibs.take(6).foreach(println) * } @@ -79,11 +92,11 @@ import scala.runtime.Statics * // * // 0 * // 1 - * // Adding 0 and 1 + * // Adding 0 and 1 => 1 * // 1 - * // Adding 1 and 1 + * // Adding 1 and 1 => 2 * // 2 - * // Adding 1 and 2 + * // Adding 1 and 2 => 3 * // 3 * * // And then prints @@ -93,35 +106,28 @@ import scala.runtime.Statics * // 1 * // 2 * // 3 - * // Adding 2 and 3 + * // Adding 2 and 3 => 5 * // 5 * }}} * - * Note that the definition of `fibs` uses `val` not `def`. The memoization of the - * `LazyList` requires us to have somewhere to store the information and a `val` - * allows us to do that. - * - * Further remarks about the semantics of `LazyList`: + * Note that the definition of `fibs` uses `val` not `def`. + * Memoization of the `LazyList` requires us to retain a reference to the computed values. * - * - Though the `LazyList` changes as it is accessed, this does not - * contradict its immutability. Once the values are memoized they do - * not change. Values that have yet to be memoized still "exist", they - * simply haven't been computed yet. + * `LazyList` is considered an immutable data structure, even though its elements are computed on demand. + * Once the values are memoized they do not change. + * Moreover, the `LazyList` itself is defined once and references to it are interchangeable. + * Values that have yet to be memoized still "exist"; they simply haven't been computed yet. * - * - One must be cautious of memoization; it can eat up memory if you're not - * careful. That's because memoization of the `LazyList` creates a structure much like - * [[scala.collection.immutable.List]]. As long as something is holding on to - * the head, the head holds on to the tail, and so on recursively. - * If, on the other hand, there is nothing holding on to the head (e.g. if we used - * `def` to define the `LazyList`) then once it is no longer being used directly, - * it disappears. + * Memoization can be a source of memory leaks and must be used with caution. + * It avoids recomputing elements of the list, but if a reference to the head + * is retained unintentionally, then all elements will be retained. * - * - Note that some operations, including [[drop]], [[dropWhile]], - * [[flatMap]] or [[collect]] may process a large number of intermediate - * elements before returning. + * The caveat that all elements are computed in order means + * that some operations, such as [[drop]], [[dropWhile]], [[flatMap]] or [[collect]], + * may process a large number of intermediate elements before returning. * - * Here's another example. Let's start with the natural numbers and iterate - * over them. + * Here's an example that illustrates these behaviors. + * Let's begin with an iteration of the natural numbers. * * {{{ * // We'll start with a silly iteration @@ -144,10 +150,10 @@ import scala.runtime.Statics * val it1 = lazylist1.iterator * loop("Iterator1: ", it1.next(), it1) * - * // We can redefine this LazyList such that all we have is the Iterator left - * // and allow the LazyList to be garbage collected as required. Using a def - * // to provide the LazyList ensures that no val is holding onto the head as - * // is the case with lazylist1 + * // We can redefine this LazyList such that we retain only a reference to its Iterator. + * // That allows the LazyList to be garbage collected. + * // Using `def` to produce the LazyList in a method ensures + * // that no val is holding onto the head, as with lazylist1. * def lazylist2: LazyList[Int] = { * def loop(v: Int): LazyList[Int] = v #:: loop(v + 1) * loop(0) @@ -166,7 +172,7 @@ import scala.runtime.Statics * loop("Iterator3: ", it3.next(), it3) * }}} * - * - In the `fibs` example earlier, the fact that `tail` works at all is of interest. + * In the `fibs` example earlier, the fact that `tail` works at all is of interest. * `fibs` has an initial `(0, 1, LazyList(...))`, so `tail` is deterministic. * If we defined `fibs` such that only `0` were concretely known, then the act * of determining `tail` would require the evaluation of `tail`, so the @@ -190,19 +196,18 @@ import scala.runtime.Statics * } * }}} * - * The head, the tail and whether the list is empty or not can be initially unknown. + * The head, the tail and whether the list is empty is initially unknown. * Once any of those are evaluated, they are all known, though if the tail is - * built with `#::` or `#:::`, it's content still isn't evaluated. Instead, evaluating - * the tails content is deferred until the tails empty status, head or tail is + * built with `#::` or `#:::`, its content still isn't evaluated. Instead, evaluating + * the tail's content is deferred until the tail's empty status, head or tail is * evaluated. * - * Delaying the evaluation of whether a LazyList is empty or not until it's needed + * Delaying the evaluation of whether a LazyList is empty until it's needed * allows LazyList to not eagerly evaluate any elements on a call to `filter`. * - * Only when it's further evaluated (which may be never!) any of the elements gets - * forced. + * Only when it's further evaluated (which may be never!) do any of the elements get forced. * - * for example: + * For example: * * {{{ * def tailWithSideEffect: LazyList[Nothing] = { @@ -218,10 +223,31 @@ import scala.runtime.Statics * filtered.isEmpty // prints "getting empty LazyList" * }}} * + * ---- + * + * You may sometimes encounter an exception like the following: + * + * {{{ + * java.lang.RuntimeException: "LazyList evaluation depends on its own result (self-reference); see docs for more info + * }}} + * + * This exception occurs when a `LazyList` is attempting to derive its next element + * from itself, and is attempting to read the element currently being evaluated. + * As a trivial example: + * + * {{{ + * lazy val a: LazyList[Int] = 1 #:: 2 #:: a.filter(_ > 2) + * }}} + * + * When attempting to evaluate the third element of `a`, it will skip the first two + * elements and read the third, but that element is already being evaluated. This is + * often caused by a subtle logic error; in this case, using `>=` in the `filter` + * would fix the error. + * * @tparam A the type of the elements contained in this lazy list. * * @see [[https://docs.scala-lang.org/overviews/collections-2.13/concrete-immutable-collection-classes.html#lazylists "Scala's Collection Library overview"]] - * section on `LazyLists` for more information. + * section on `LazyLists` for a summary. * @define Coll `LazyList` * @define coll lazy list * @define orderDependent @@ -236,8 +262,8 @@ import scala.runtime.Statics * on the result (e.g. calling `head` or `tail`, or checking if it is empty). * @define evaluatesAllElements This method evaluates all elements of the collection. */ -@SerialVersionUID(3L) -final class LazyList[+A] private(private[this] var lazyState: () => LazyList.State[A]) +@SerialVersionUID(4L) +final class LazyList[+A] private (lazyState: AnyRef /* EmptyMarker.type | () => LazyList[A] */) extends AbstractSeq[A] with LinearSeq[A] with LinearSeqOps[A, LazyList, LazyList[A]] @@ -245,28 +271,72 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta with Serializable { import LazyList._ - @volatile private[this] var stateEvaluated: Boolean = false - @inline private def stateDefined: Boolean = stateEvaluated - private[this] var midEvaluation = false + // kount() // LazyListTest.countAlloc + + private def this(head: A, tail: LazyList[A]) = { + this(LazyList.EmptyMarker) + _head = head + _tail = tail + } - private lazy val state: State[A] = { - // if it's already mid-evaluation, we're stuck in an infinite - // self-referential loop (also it's empty) - if (midEvaluation) { - throw new RuntimeException("self-referential LazyList or a derivation thereof has no more elements") + // used to synchronize lazy state evaluation + // after initialization (`_head ne Uninitialized`) + // - `null` if this is an empty lazy list + // - `head: A` otherwise (can be `null`, `_tail == null` is used to test emptiness) + @volatile private[this] var _head: Any /* Uninitialized | A */ = + if (lazyState eq EmptyMarker) null else Uninitialized + + // when `_head eq Uninitialized` + // - `lazySate: () => LazyList[A]` + // - MidEvaluation while evaluating lazyState + // when `_head ne Uninitialized` + // - `null` if this is an empty lazy list + // - `tail: LazyList[A]` otherwise + private[this] var _tail: AnyRef /* () => LazyList[A] | MidEvaluation.type | LazyList[A] */ = + if (lazyState eq EmptyMarker) null else lazyState + + private def rawHead: Any = _head + private def rawTail: AnyRef = _tail + + @inline private def isEvaluated: Boolean = _head.asInstanceOf[AnyRef] ne Uninitialized + + private def initState(): Unit = synchronized { + if (!isEvaluated) { + // if it's already mid-evaluation, we're stuck in an infinite + // self-referential loop (also it's empty) + if (_tail eq MidEvaluation) + throw new RuntimeException( + "LazyList evaluation depends on its own result (self-reference); see docs for more info") + + val fun = _tail.asInstanceOf[() => LazyList[A]] + _tail = MidEvaluation + val l = + // `fun` returns a LazyList that represents the state (head/tail) of `this`. We call `l.evaluated` to ensure + // `l` is initialized, to prevent races when reading `rawTail` / `rawHead` below. + // Often, lazy lists are created with `newLL(eagerCons(...))` so `l` is already initialized, but `newLL` also + // accepts non-evaluated lazy lists. + try fun().evaluated + // restore `fun` in finally so we can try again later if an exception was thrown (similar to lazy val) + finally _tail = fun + _tail = l.rawTail + _head = l.rawHead } - midEvaluation = true - val res = try lazyState() finally midEvaluation = false - // if we set it to `true` before evaluating, we may infinite loop - // if something expects `state` to already be evaluated - stateEvaluated = true - lazyState = null // allow GC - res } + @tailrec private def evaluated: LazyList[A] = + if (isEvaluated) { + if (_tail == null) Empty + else this + } else { + initState() + evaluated + } + override def iterableFactory: SeqFactory[LazyList] = LazyList - override def isEmpty: Boolean = state eq State.Empty + // NOTE: `evaluated; this eq Empty` would be wrong. Deserialization of `Empty` creates a new + // instance with `null` fields, but the `evaluated` method always returns the canonical `Empty`. + @inline override def isEmpty: Boolean = evaluated eq Empty /** @inheritdoc * @@ -274,12 +344,18 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta */ override def knownSize: Int = if (knownIsEmpty) 0 else -1 - override def head: A = state.head + override def head: A = + // inlined `isEmpty` to make it clear that `rawHead` below is initialized + if (evaluated eq Empty) throw new NoSuchElementException("head of empty lazy list") + else rawHead.asInstanceOf[A] - override def tail: LazyList[A] = state.tail + override def tail: LazyList[A] = + // inlined `isEmpty` to make it clear that `rawTail` below is initialized + if (evaluated eq Empty) throw new UnsupportedOperationException("tail of empty lazy list") + else rawTail.asInstanceOf[LazyList[A]] - @inline private[this] def knownIsEmpty: Boolean = stateEvaluated && (isEmpty: @inline) - @inline private def knownNonEmpty: Boolean = stateEvaluated && !(isEmpty: @inline) + @inline private[this] def knownIsEmpty: Boolean = isEvaluated && isEmpty + @inline private def knownNonEmpty: Boolean = isEvaluated && !isEmpty /** Evaluates all undefined elements of the lazy list. * @@ -358,9 +434,9 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta if (isEmpty) z else tail.foldLeft(op(z, head))(op) - // State.Empty doesn't use the SerializationProxy + // LazyList.Empty doesn't use the SerializationProxy protected[this] def writeReplace(): AnyRef = - if (knownNonEmpty) new LazyList.SerializationProxy[A](this) else this + if (knownNonEmpty) new SerializationProxy[A](this) else this override protected[this] def className = "LazyList" @@ -376,11 +452,11 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta def lazyAppendedAll[B >: A](suffix: => collection.IterableOnce[B]): LazyList[B] = newLL { if (isEmpty) suffix match { - case lazyList: LazyList[B] => lazyList.state // don't recompute the LazyList - case coll if coll.knownSize == 0 => State.Empty - case coll => stateFromIterator(coll.iterator) + case lazyList: LazyList[B] => lazyList // don't recompute the LazyList + case coll if coll.knownSize == 0 => Empty + case coll => eagerHeadFromIterator(coll.iterator) } - else sCons(head, tail lazyAppendedAll suffix) + else eagerCons(head, tail lazyAppendedAll suffix) } /** @inheritdoc @@ -400,7 +476,7 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $appendStackSafety */ override def appended[B >: A](elem: B): LazyList[B] = - if (knownIsEmpty) newLL(sCons(elem, LazyList.empty)) + if (knownIsEmpty) eagerCons(elem, Empty) else lazyAppendedAll(Iterator.single(elem)) /** @inheritdoc @@ -408,15 +484,15 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def scanLeft[B](z: B)(op: (B, A) => B): LazyList[B] = - if (knownIsEmpty) newLL(sCons(z, LazyList.empty)) - else newLL(scanLeftState(z)(op)) + if (knownIsEmpty) eagerCons(z, Empty) + else scanLeftImpl(z)(op) - private def scanLeftState[B](z: B)(op: (B, A) => B): State[B] = - sCons( + private def scanLeftImpl[B](z: B)(op: (B, A) => B): LazyList[B] = + eagerCons( z, newLL { - if (isEmpty) State.Empty - else tail.scanLeftState(op(z, head))(op) + if (isEmpty) Empty + else tail.scanLeftImpl(op(z, head))(op) } ) @@ -428,10 +504,10 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * @return The accumulated value from successive applications of `f`. */ override def reduceLeft[B >: A](f: (B, A) => B): B = { - if (this.isEmpty) throw new UnsupportedOperationException("empty.reduceLeft") + if (isEmpty) throw new UnsupportedOperationException("empty.reduceLeft") else { - var reducedRes: B = this.head - var left: LazyList[A] = this.tail + var reducedRes: B = head + var left: LazyList[A] = tail while (!left.isEmpty) { reducedRes = f(reducedRes, left.head) left = left.tail @@ -460,16 +536,16 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def filter(pred: A => Boolean): LazyList[A] = - if (knownIsEmpty) LazyList.empty - else LazyList.filterImpl(this, pred, isFlipped = false) + if (knownIsEmpty) Empty + else filterImpl(this, pred, isFlipped = false) /** @inheritdoc * * $preservesLaziness */ override def filterNot(pred: A => Boolean): LazyList[A] = - if (knownIsEmpty) LazyList.empty - else LazyList.filterImpl(this, pred, isFlipped = true) + if (knownIsEmpty) Empty + else filterImpl(this, pred, isFlipped = true) /** A `collection.WithFilter` which allows GC of the head of lazy list during processing. * @@ -486,7 +562,7 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * * $preservesLaziness */ - override def prepended[B >: A](elem: B): LazyList[B] = newLL(sCons(elem, this)) + override def prepended[B >: A](elem: B): LazyList[B] = eagerCons(elem, this) /** @inheritdoc * @@ -495,15 +571,15 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta override def prependedAll[B >: A](prefix: collection.IterableOnce[B]): LazyList[B] = if (knownIsEmpty) LazyList.from(prefix) else if (prefix.knownSize == 0) this - else newLL(stateFromIteratorConcatSuffix(prefix.iterator)(state)) + else newLL(eagerHeadPrependIterator(prefix.iterator)(this)) /** @inheritdoc * * $preservesLaziness */ override def map[B](f: A => B): LazyList[B] = - if (knownIsEmpty) LazyList.empty - else (mapImpl(f): @inline) + if (knownIsEmpty) Empty + else mapImpl(f) /** @inheritdoc * @@ -513,8 +589,8 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta private def mapImpl[B](f: A => B): LazyList[B] = newLL { - if (isEmpty) State.Empty - else sCons(f(head), tail.mapImpl(f)) + if (isEmpty) Empty + else eagerCons(f(head), tail.mapImpl(f)) } /** @inheritdoc @@ -522,8 +598,8 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def collect[B](pf: PartialFunction[A, B]): LazyList[B] = - if (knownIsEmpty) LazyList.empty - else LazyList.collectImpl(this, pf) + if (knownIsEmpty) Empty + else collectImpl(this, pf) /** @inheritdoc * @@ -534,7 +610,7 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta override def collectFirst[B](pf: PartialFunction[A, B]): Option[B] = if (isEmpty) None else { - val res = pf.applyOrElse(head, LazyList.anyToMarker.asInstanceOf[A => B]) + val res = pf.applyOrElse(head, anyToMarker.asInstanceOf[A => B]) if (res.asInstanceOf[AnyRef] eq Statics.pfMarker) tail.collectFirst(pf) else Some(res) } @@ -560,8 +636,8 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta // optimisations are not for speed, but for functionality // see tickets #153, #498, #2147, and corresponding tests in run/ (as well as run/stream_flatmap_odds.scala) override def flatMap[B](f: A => IterableOnce[B]): LazyList[B] = - if (knownIsEmpty) LazyList.empty - else LazyList.flatMapImpl(this, f) + if (knownIsEmpty) Empty + else flatMapImpl(this, f) /** @inheritdoc * @@ -574,12 +650,12 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def zip[B](that: collection.IterableOnce[B]): LazyList[(A, B)] = - if (this.knownIsEmpty || that.knownSize == 0) LazyList.empty - else newLL(zipState(that.iterator)) + if (knownIsEmpty || that.knownSize == 0) Empty + else newLL(eagerHeadZipImpl(that.iterator)) - private def zipState[B](it: Iterator[B]): State[(A, B)] = - if (this.isEmpty || !it.hasNext) State.Empty - else sCons((head, it.next()), newLL { tail zipState it }) + private def eagerHeadZipImpl[B](it: Iterator[B]): LazyList[(A, B)] = + if (isEmpty || !it.hasNext) Empty + else eagerCons((head, it.next()), newLL { tail eagerHeadZipImpl it }) /** @inheritdoc * @@ -592,22 +668,22 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def zipAll[A1 >: A, B](that: collection.Iterable[B], thisElem: A1, thatElem: B): LazyList[(A1, B)] = { - if (this.knownIsEmpty) { - if (that.knownSize == 0) LazyList.empty + if (knownIsEmpty) { + if (that.knownSize == 0) Empty else LazyList.continually(thisElem) zip that } else { if (that.knownSize == 0) zip(LazyList.continually(thatElem)) - else newLL(zipAllState(that.iterator, thisElem, thatElem)) + else newLL(eagerHeadZipAllImpl(that.iterator, thisElem, thatElem)) } } - private def zipAllState[A1 >: A, B](it: Iterator[B], thisElem: A1, thatElem: B): State[(A1, B)] = { + private def eagerHeadZipAllImpl[A1 >: A, B](it: Iterator[B], thisElem: A1, thatElem: B): LazyList[(A1, B)] = { if (it.hasNext) { - if (this.isEmpty) sCons((thisElem, it.next()), newLL { LazyList.continually(thisElem) zipState it }) - else sCons((this.head, it.next()), newLL { this.tail.zipAllState(it, thisElem, thatElem) }) + if (isEmpty) eagerCons((thisElem, it.next()), newLL { LazyList.continually(thisElem) eagerHeadZipImpl it }) + else eagerCons((head, it.next()), newLL { tail.eagerHeadZipAllImpl(it, thisElem, thatElem) }) } else { - if (this.isEmpty) State.Empty - else sCons((this.head, thatElem), this.tail zip LazyList.continually(thatElem)) + if (isEmpty) Empty + else eagerCons((head, thatElem), tail zip LazyList.continually(thatElem)) } } @@ -620,7 +696,7 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * only evaluated individually as needed. */ // just in case it can be meaningfully overridden at some point - override def lazyZip[B](that: collection.Iterable[B]): LazyZip2[A, B, LazyList.this.type] = + override def lazyZip[B](that: collection.Iterable[B]): LazyZip2[A, B, this.type] = super.lazyZip(that) /** @inheritdoc @@ -644,8 +720,8 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta */ override def drop(n: Int): LazyList[A] = if (n <= 0) this - else if (knownIsEmpty) LazyList.empty - else LazyList.dropImpl(this, n) + else if (knownIsEmpty) Empty + else dropImpl(this, n) /** @inheritdoc * @@ -653,8 +729,8 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * Additionally, it preserves laziness for all elements after the predicate returns `false`. */ override def dropWhile(p: A => Boolean): LazyList[A] = - if (knownIsEmpty) LazyList.empty - else LazyList.dropWhileImpl(this, p) + if (knownIsEmpty) Empty + else dropWhileImpl(this, p) /** @inheritdoc * @@ -662,7 +738,7 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta */ override def dropRight(n: Int): LazyList[A] = { if (n <= 0) this - else if (knownIsEmpty) LazyList.empty + else if (knownIsEmpty) Empty else newLL { var scout = this var remaining = n @@ -671,27 +747,27 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta remaining -= 1 scout = scout.tail } - dropRightState(scout) + eagerHeadDropRightImpl(scout) } } - private def dropRightState(scout: LazyList[_]): State[A] = - if (scout.isEmpty) State.Empty - else sCons(head, newLL(tail.dropRightState(scout.tail))) + private def eagerHeadDropRightImpl(scout: LazyList[_]): LazyList[A] = + if (scout.isEmpty) Empty + else eagerCons(head, newLL(tail.eagerHeadDropRightImpl(scout.tail))) /** @inheritdoc * * $preservesLaziness */ override def take(n: Int): LazyList[A] = - if (knownIsEmpty) LazyList.empty - else (takeImpl(n): @inline) + if (knownIsEmpty) Empty + else takeImpl(n) private def takeImpl(n: Int): LazyList[A] = { - if (n <= 0) LazyList.empty + if (n <= 0) Empty else newLL { - if (isEmpty) State.Empty - else sCons(head, tail.takeImpl(n - 1)) + if (isEmpty) Empty + else eagerCons(head, tail.takeImpl(n - 1)) } } @@ -700,13 +776,13 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def takeWhile(p: A => Boolean): LazyList[A] = - if (knownIsEmpty) LazyList.empty - else (takeWhileImpl(p): @inline) + if (knownIsEmpty) Empty + else takeWhileImpl(p) private def takeWhileImpl(p: A => Boolean): LazyList[A] = newLL { - if (isEmpty || !p(head)) State.Empty - else sCons(head, tail.takeWhileImpl(p)) + if (isEmpty || !p(head)) Empty + else eagerCons(head, tail.takeWhileImpl(p)) } /** @inheritdoc @@ -714,8 +790,8 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $initiallyLazy */ override def takeRight(n: Int): LazyList[A] = - if (n <= 0 || knownIsEmpty) LazyList.empty - else LazyList.takeRightImpl(this, n) + if (n <= 0 || knownIsEmpty) Empty + else takeRightImpl(this, n) /** @inheritdoc * @@ -728,20 +804,20 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * * $evaluatesAllElements */ - override def reverse: LazyList[A] = reverseOnto(LazyList.empty) + override def reverse: LazyList[A] = reverseOnto(Empty) // need contravariant type B to make the compiler happy - still returns LazyList[A] @tailrec private def reverseOnto[B >: A](tl: LazyList[B]): LazyList[B] = if (isEmpty) tl - else tail.reverseOnto(newLL(sCons(head, tl))) + else tail.reverseOnto(newLL(eagerCons(head, tl))) /** @inheritdoc * * $preservesLaziness */ override def diff[B >: A](that: collection.Seq[B]): LazyList[A] = - if (knownIsEmpty) LazyList.empty + if (knownIsEmpty) Empty else super.diff(that) /** @inheritdoc @@ -749,7 +825,7 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * $preservesLaziness */ override def intersect[B >: A](that: collection.Seq[B]): LazyList[A] = - if (knownIsEmpty) LazyList.empty + if (knownIsEmpty) Empty else super.intersect(that) @tailrec @@ -786,13 +862,12 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * * $preservesLaziness */ - override def padTo[B >: A](len: Int, elem: B): LazyList[B] = { + override def padTo[B >: A](len: Int, elem: B): LazyList[B] = if (len <= 0) this else newLL { - if (isEmpty) LazyList.fill(len)(elem).state - else sCons(head, tail.padTo(len - 1, elem)) + if (isEmpty) LazyList.fill(len)(elem) + else eagerCons(head, tail.padTo(len - 1, elem)) } - } /** @inheritdoc * @@ -804,9 +879,9 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta private def patchImpl[B >: A](from: Int, other: IterableOnce[B], replaced: Int): LazyList[B] = newLL { - if (from <= 0) stateFromIteratorConcatSuffix(other.iterator)(LazyList.dropImpl(this, replaced).state) - else if (isEmpty) stateFromIterator(other.iterator) - else sCons(head, tail.patchImpl(from - 1, other, replaced)) + if (from <= 0) eagerHeadPrependIterator(other.iterator)(dropImpl(this, replaced)) + else if (isEmpty) eagerHeadFromIterator(other.iterator) + else eagerCons(head, tail.patchImpl(from - 1, other, replaced)) } /** @inheritdoc @@ -824,13 +899,12 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta if (index < 0) throw new IndexOutOfBoundsException(s"$index") else updatedImpl(index, elem, index) - private def updatedImpl[B >: A](index: Int, elem: B, startIndex: Int): LazyList[B] = { + private def updatedImpl[B >: A](index: Int, elem: B, startIndex: Int): LazyList[B] = newLL { - if (index <= 0) sCons(elem, tail) + if (index <= 0) eagerCons(elem, tail) else if (tail.isEmpty) throw new IndexOutOfBoundsException(startIndex.toString) - else sCons(head, tail.updatedImpl(index - 1, elem, startIndex)) + else eagerCons(head, tail.updatedImpl(index - 1, elem, startIndex)) } - } /** Appends all elements of this $coll to a string builder using start, end, and separator strings. * The written text begins with the string `start` and ends with the string `end`. @@ -855,63 +929,62 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta private[this] def addStringNoForce(b: JStringBuilder, start: String, sep: String, end: String): b.type = { b.append(start) - if (!stateDefined) b.append("") + if (!isEvaluated) b.append("") else if (!isEmpty) { b.append(head) var cursor = this - @inline def appendCursorElement(): Unit = b.append(sep).append(cursor.head) + // explicit param to prevent an ObjectRef for cursor + @inline def appendHead(c: LazyList[A]): Unit = b.append(sep).append(c.head) var scout = tail - @inline def scoutNonEmpty: Boolean = scout.stateDefined && !scout.isEmpty - if ((cursor ne scout) && (!scout.stateDefined || (cursor.state ne scout.state))) { + if (cursor ne scout) { cursor = scout - if (scoutNonEmpty) { + if (scout.knownNonEmpty) { scout = scout.tail // Use 2x 1x iterator trick for cycle detection; slow iterator can add strings - while ((cursor ne scout) && scoutNonEmpty && (cursor.state ne scout.state)) { - appendCursorElement() + while ((cursor ne scout) && scout.knownNonEmpty) { + appendHead(cursor) cursor = cursor.tail scout = scout.tail - if (scoutNonEmpty) scout = scout.tail + if (scout.knownNonEmpty) scout = scout.tail } } } - if (!scoutNonEmpty) { // Not a cycle, scout hit an end + if (!scout.knownNonEmpty) { // Not a cycle, scout hit an end (empty or non-evaluated) while (cursor ne scout) { - appendCursorElement() + appendHead(cursor) cursor = cursor.tail } // if cursor (eq scout) has state defined, it is empty; else unknown state - if (!cursor.stateDefined) b.append(sep).append("") + if (!cursor.isEvaluated) b.append(sep).append("") } else { - @inline def same(a: LazyList[A], b: LazyList[A]): Boolean = (a eq b) || (a.state eq b.state) - // Cycle. - // If we have a prefix of length P followed by a cycle of length C, - // the scout will be at position (P%C) in the cycle when the cursor - // enters it at P. They'll then collide when the scout advances another - // C - (P%C) ahead of the cursor. - // If we run the scout P farther, then it will be at the start of - // the cycle: (C - (P%C) + (P%C)) == C == 0. So if another runner - // starts at the beginning of the prefix, they'll collide exactly at - // the start of the loop. - var runner = this - var k = 0 - while (!same(runner, scout)) { - runner = runner.tail - scout = scout.tail - k += 1 - } - // Now runner and scout are at the beginning of the cycle. Advance - // cursor, adding to string, until it hits; then we'll have covered - // everything once. If cursor is already at beginning, we'd better - // advance one first unless runner didn't go anywhere (in which case - // we've already looped once). - if (same(cursor, scout) && (k > 0)) { - appendCursorElement() - cursor = cursor.tail - } - while (!same(cursor, scout)) { - appendCursorElement() - cursor = cursor.tail + // Cycle: the scout is `knownNonEmpty` and `eq cursor`. + // if the cycle starts at `this`, its elements were already added + if (cursor ne this) { + // If we have a prefix of length P followed by a cycle of length C, + // the scout will be at position (P%C) in the cycle when the cursor + // enters it at P. They'll then collide when the scout advances another + // C - (P%C) ahead of the cursor. + // If we run the scout P farther, then it will be at the start of + // the cycle: (C - (P%C) + (P%C)) == C == 0. So if another runner + // starts at the beginning of the prefix, they'll collide exactly at + // the start of the loop. + var runner = this + while (runner ne scout) { + runner = runner.tail + scout = scout.tail + } + while({ + val ct = cursor.tail + if (ct ne scout) { + // In `lazy val xs: LazyList[Int] = 1 #:: 2 #:: xs`, method `#::` creates a LazyList instance which ends up as the 3rd element. + // That 3rd element initially has unknown head/tail. Once it completes, the tail is assigned to be `xs.tail`. + // So in memory the structure is `LLx(1, LLy(2, LLz(1, )))`. + // In `toString` we skip the last element to maintain the illusion. + appendHead(cursor) + } + cursor = ct + cursor ne scout + }) () } b.append(sep).append("") } @@ -940,17 +1013,17 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta */ @deprecated("Check .knownSize instead of .hasDefiniteSize for more actionable information (see scaladoc for details)", "2.13.0") override def hasDefiniteSize: Boolean = { - if (!stateDefined) false + if (!isEvaluated) false else if (isEmpty) true else { // Two-iterator trick (2x & 1x speed) for cycle detection. var those = this var these = tail while (those ne these) { - if (!these.stateDefined) return false + if (!these.isEvaluated) return false else if (these.isEmpty) return true these = these.tail - if (!these.stateDefined) return false + if (!these.isEvaluated) return false else if (these.isEmpty) return true these = these.tail if (those eq these) return false @@ -966,32 +1039,24 @@ final class LazyList[+A] private(private[this] var lazyState: () => LazyList.Sta * @define coll lazy list * @define Coll `LazyList` */ -@SerialVersionUID(3L) +@SerialVersionUID(4L) object LazyList extends SeqFactory[LazyList] { - // Eagerly evaluate cached empty instance - private[this] val _empty = newLL(State.Empty).force - private sealed trait State[+A] extends Serializable { - def head: A - def tail: LazyList[A] - } + // LazyListTest.countAlloc + // var k = 0 + // def kount(): Unit = k += 1 - private object State { - @SerialVersionUID(3L) - object Empty extends State[Nothing] { - def head: Nothing = throw new NoSuchElementException("head of empty lazy list") - def tail: LazyList[Nothing] = throw new UnsupportedOperationException("tail of empty lazy list") - } + private object Uninitialized extends Serializable + private object MidEvaluation + private object EmptyMarker - @SerialVersionUID(3L) - final class Cons[A](val head: A, val tail: LazyList[A]) extends State[A] - } + private val Empty: LazyList[Nothing] = new LazyList(EmptyMarker) /** Creates a new LazyList. */ - @inline private def newLL[A](state: => State[A]): LazyList[A] = new LazyList[A](() => state) + @inline private def newLL[A](state: => LazyList[A]): LazyList[A] = new LazyList[A](() => state) - /** Creates a new State.Cons. */ - @inline private def sCons[A](hd: A, tl: LazyList[A]): State[A] = new State.Cons[A](hd, tl) + /** Creates a new LazyList with evaluated `head` and `tail`. */ + @inline private def eagerCons[A](hd: A, tl: LazyList[A]): LazyList[A] = new LazyList[A](hd, tl) private val anyToMarker: Any => Any = _ => Statics.pfMarker @@ -1016,7 +1081,7 @@ object LazyList extends SeqFactory[LazyList] { rest = rest.tail restRef = rest // restRef.elem = rest } - if (found) sCons(elem, filterImpl(rest, p, isFlipped)) else State.Empty + if (found) eagerCons(elem, filterImpl(rest, p, isFlipped)) else Empty } } @@ -1034,8 +1099,8 @@ object LazyList extends SeqFactory[LazyList] { rest = rest.tail restRef = rest // restRef.elem = rest } - if (res.asInstanceOf[AnyRef] eq marker) State.Empty - else sCons(res, collectImpl(rest, pf)) + if (res.asInstanceOf[AnyRef] eq marker) Empty + else eagerCons(res, collectImpl(rest, pf)) } } @@ -1058,8 +1123,8 @@ object LazyList extends SeqFactory[LazyList] { val head = it.next() rest = rest.tail restRef = rest // restRef.elem = rest - sCons(head, newLL(stateFromIteratorConcatSuffix(it)(flatMapImpl(rest, f).state))) - } else State.Empty + eagerCons(head, newLL(eagerHeadPrependIterator(it)(flatMapImpl(rest, f)))) + } else Empty } } @@ -1076,7 +1141,7 @@ object LazyList extends SeqFactory[LazyList] { i -= 1 iRef = i // iRef.elem = i } - rest.state + rest } } @@ -1089,7 +1154,7 @@ object LazyList extends SeqFactory[LazyList] { rest = rest.tail restRef = rest // restRef.elem = rest } - rest.state + rest } } @@ -1117,7 +1182,7 @@ object LazyList extends SeqFactory[LazyList] { restRef = rest // restRef.elem = rest } // `rest` is the last `n` elements (or all of them) - rest.state + rest } } @@ -1128,7 +1193,7 @@ object LazyList extends SeqFactory[LazyList] { * @param hd The first element of the result lazy list * @param tl The remaining elements of the result lazy list */ - def apply[A](hd: => A, tl: => LazyList[A]): LazyList[A] = newLL(sCons(hd, newLL(tl.state))) + def apply[A](hd: => A, tl: => LazyList[A]): LazyList[A] = newLL(eagerCons(hd, newLL(tl))) /** Maps a lazy list to its head and tail */ def unapply[A](xs: LazyList[A]): Option[(A, LazyList[A])] = #::.unapply(xs) @@ -1140,7 +1205,7 @@ object LazyList extends SeqFactory[LazyList] { /** Construct a LazyList consisting of a given first element followed by elements * from another LazyList. */ - def #:: [B >: A](elem: => B): LazyList[B] = newLL(sCons(elem, newLL(l().state))) + def #:: [B >: A](elem: => B): LazyList[B] = newLL(eagerCons(elem, newLL(l()))) /** Construct a LazyList consisting of the concatenation of the given LazyList and * another LazyList. */ @@ -1155,30 +1220,30 @@ object LazyList extends SeqFactory[LazyList] { def from[A](coll: collection.IterableOnce[A]): LazyList[A] = coll match { case lazyList: LazyList[A] => lazyList case _ if coll.knownSize == 0 => empty[A] - case _ => newLL(stateFromIterator(coll.iterator)) + case _ => newLL(eagerHeadFromIterator(coll.iterator)) } - def empty[A]: LazyList[A] = _empty + def empty[A]: LazyList[A] = Empty - /** Creates a State from an Iterator, with another State appended after the Iterator - * is empty. - */ - private def stateFromIteratorConcatSuffix[A](it: Iterator[A])(suffix: => State[A]): State[A] = - if (it.hasNext) sCons(it.next(), newLL(stateFromIteratorConcatSuffix(it)(suffix))) + /** Creates a LazyList with the elements of an iterator followed by a LazyList suffix. + * Eagerly evaluates the first element. + */ + private def eagerHeadPrependIterator[A](it: Iterator[A])(suffix: => LazyList[A]): LazyList[A] = + if (it.hasNext) eagerCons(it.next(), newLL(eagerHeadPrependIterator(it)(suffix))) else suffix - /** Creates a State from an IterableOnce. */ - private def stateFromIterator[A](it: Iterator[A]): State[A] = - if (it.hasNext) sCons(it.next(), newLL(stateFromIterator(it))) - else State.Empty + /** Creates a LazyList from an Iterator. Eagerly evaluates the first element. */ + private def eagerHeadFromIterator[A](it: Iterator[A]): LazyList[A] = + if (it.hasNext) eagerCons(it.next(), newLL(eagerHeadFromIterator(it))) + else Empty override def concat[A](xss: collection.Iterable[A]*): LazyList[A] = if (xss.knownSize == 0) empty - else newLL(concatIterator(xss.iterator)) + else newLL(eagerHeadConcatIterators(xss.iterator)) - private def concatIterator[A](it: Iterator[collection.Iterable[A]]): State[A] = - if (!it.hasNext) State.Empty - else stateFromIteratorConcatSuffix(it.next().iterator)(concatIterator(it)) + private def eagerHeadConcatIterators[A](it: Iterator[collection.Iterable[A]]): LazyList[A] = + if (!it.hasNext) Empty + else eagerHeadPrependIterator(it.next().iterator)(eagerHeadConcatIterators(it)) /** An infinite LazyList that repeatedly applies a given function to a start value. * @@ -1189,7 +1254,7 @@ object LazyList extends SeqFactory[LazyList] { def iterate[A](start: => A)(f: A => A): LazyList[A] = newLL { val head = start - sCons(head, iterate(f(head))(f)) + eagerCons(head, iterate(f(head))(f)) } /** @@ -1201,7 +1266,7 @@ object LazyList extends SeqFactory[LazyList] { * @return the LazyList starting at value `start`. */ def from(start: Int, step: Int): LazyList[Int] = - newLL(sCons(start, from(start + step, step))) + newLL(eagerCons(start, from(start + step, step))) /** * Create an infinite LazyList starting at `start` and incrementing by `1`. @@ -1218,14 +1283,14 @@ object LazyList extends SeqFactory[LazyList] { * @param elem the element composing the resulting LazyList * @return the LazyList containing an infinite number of elem */ - def continually[A](elem: => A): LazyList[A] = newLL(sCons(elem, continually(elem))) + def continually[A](elem: => A): LazyList[A] = newLL(eagerCons(elem, continually(elem))) override def fill[A](n: Int)(elem: => A): LazyList[A] = - if (n > 0) newLL(sCons(elem, fill(n - 1)(elem))) else empty + if (n > 0) newLL(eagerCons(elem, LazyList.fill(n - 1)(elem))) else empty override def tabulate[A](n: Int)(f: Int => A): LazyList[A] = { def at(index: Int): LazyList[A] = - if (index < n) newLL(sCons(f(index), at(index + 1))) else empty + if (index < n) newLL(eagerCons(f(index), at(index + 1))) else empty at(0) } @@ -1234,8 +1299,8 @@ object LazyList extends SeqFactory[LazyList] { override def unfold[A, S](init: S)(f: S => Option[(A, S)]): LazyList[A] = newLL { f(init) match { - case Some((elem, state)) => sCons(elem, unfold(state)(f)) - case None => State.Empty + case Some((elem, state)) => eagerCons(elem, unfold(state)(f)) + case None => Empty } } @@ -1303,13 +1368,13 @@ object LazyList extends SeqFactory[LazyList] { } override def result(): LazyList[A] = { - next init State.Empty + next init Empty list } override def addOne(elem: A): this.type = { val deferred = new DeferredState[A] - next init sCons(elem, newLL(deferred.eval())) + next init eagerCons(elem, newLL(deferred.eval())) next = deferred this } @@ -1318,7 +1383,7 @@ object LazyList extends SeqFactory[LazyList] { override def addAll(xs: IterableOnce[A]): this.type = { if (xs.knownSize != 0) { val deferred = new DeferredState[A] - next init stateFromIteratorConcatSuffix(xs.iterator)(deferred.eval()) + next init eagerHeadPrependIterator(xs.iterator)(deferred.eval()) next = deferred } this @@ -1327,18 +1392,18 @@ object LazyList extends SeqFactory[LazyList] { private object LazyBuilder { final class DeferredState[A] { - private[this] var _state: () => State[A] = _ + private[this] var _tail: () => LazyList[A] = _ - def eval(): State[A] = { - val state = _state + def eval(): LazyList[A] = { + val state = _tail if (state == null) throw new IllegalStateException("uninitialized") state() } // racy - def init(state: => State[A]): Unit = { - if (_state != null) throw new IllegalStateException("already initialized") - _state = () => state + def init(state: => LazyList[A]): Unit = { + if (_tail != null) throw new IllegalStateException("already initialized") + _tail = () => state } } } @@ -1348,7 +1413,7 @@ object LazyList extends SeqFactory[LazyList] { * standard Java serialization to store the complete structure of unevaluated thunks. This allows the serialization * of long evaluated lazy lists without exhausting the stack through recursive serialization of cons cells. */ - @SerialVersionUID(3L) + @SerialVersionUID(4L) final class SerializationProxy[A](@transient protected var coll: LazyList[A]) extends Serializable { private[this] def writeObject(out: ObjectOutputStream): Unit = { @@ -1371,10 +1436,10 @@ object LazyList extends SeqFactory[LazyList] { case a => init += a.asInstanceOf[A] } val tail = in.readObject().asInstanceOf[LazyList[A]] - // scala/scala#10118: caution that no code path can evaluate `tail.state` + // scala/scala#10118: caution that no code path can evaluate `tail.evaluated` // before the resulting LazyList is returned val it = init.toList.iterator - coll = newLL(stateFromIteratorConcatSuffix(it)(tail.state)) + coll = newLL(eagerHeadPrependIterator(it)(tail)) } private[this] def readResolve(): Any = coll diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index 97738e98997f..cee22bcc6d54 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,64 +17,64 @@ package immutable import scala.annotation.unchecked.uncheckedVariance import scala.annotation.tailrec import mutable.{Builder, ListBuffer} -import scala.collection.generic.DefaultSerializable +import scala.collection.generic.{CommonErrors, DefaultSerializable} import scala.runtime.Statics.releaseFence /** A class for immutable linked lists representing ordered collections - * of elements of type `A`. - * - * This class comes with two implementing case classes `scala.Nil` - * and `scala.::` that implement the abstract members `isEmpty`, - * `head` and `tail`. - * - * This class is optimal for last-in-first-out (LIFO), stack-like access patterns. If you need another access - * pattern, for example, random access or FIFO, consider using a collection more suited to this than `List`. - * - * ==Performance== - * '''Time:''' `List` has `O(1)` prepend and head/tail access. Most other operations are `O(n)` on the number of elements in the list. - * This includes the index-based lookup of elements, `length`, `append` and `reverse`. - * - * '''Space:''' `List` implements '''structural sharing''' of the tail list. This means that many operations are either - * zero- or constant-memory cost. - * {{{ - * val mainList = List(3, 2, 1) - * val with4 = 4 :: mainList // re-uses mainList, costs one :: instance - * val with42 = 42 :: mainList // also re-uses mainList, cost one :: instance - * val shorter = mainList.tail // costs nothing as it uses the same 2::1::Nil instances as mainList - * }}} - * - * @example {{{ - * // Make a list via the companion object factory - * val days = List("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") - * - * // Make a list element-by-element - * val when = "AM" :: "PM" :: Nil - * - * // Pattern match - * days match { - * case firstDay :: otherDays => - * println("The first day of the week is: " + firstDay) - * case Nil => - * println("There don't seem to be any week days.") - * } - * }}} - * - * @note The functional list is characterized by persistence and structural sharing, thus offering considerable - * performance and space consumption benefits in some scenarios if used correctly. - * However, note that objects having multiple references into the same functional list (that is, - * objects that rely on structural sharing), will be serialized and deserialized with multiple lists, one for - * each reference to it. I.e. structural sharing is lost after serialization/deserialization. - * - * @see [[https://docs.scala-lang.org/overviews/collections-2.13/concrete-immutable-collection-classes.html#lists "Scala's Collection Library overview"]] - * section on `Lists` for more information. - * - * @define coll list - * @define Coll `List` - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ + * of elements of type `A`. + * + * This class comes with two implementing case classes `scala.Nil` + * and `scala.::` that implement the abstract members `isEmpty`, + * `head` and `tail`. + * + * This class is optimal for last-in-first-out (LIFO), stack-like access patterns. If you need another access + * pattern, for example, random access or FIFO, consider using a collection more suited to this than `List`. + * + * ==Performance== + * '''Time:''' `List` has `O(1)` prepend and head/tail access. Most other operations are `O(n)` on the number of elements in the list. + * This includes the index-based lookup of elements, `length`, `append` and `reverse`. + * + * '''Space:''' `List` implements '''structural sharing''' of the tail list. This means that many operations are either + * zero- or constant-memory cost. + * {{{ + * val mainList = List(3, 2, 1) + * val with4 = 4 :: mainList // re-uses mainList, costs one :: instance + * val with42 = 42 :: mainList // also re-uses mainList, cost one :: instance + * val shorter = mainList.tail // costs nothing as it uses the same 2::1::Nil instances as mainList + * }}} + * + * @example {{{ + * // Make a list via the companion object factory + * val days = List("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") + * + * // Make a list element-by-element + * val when = "AM" :: "PM" :: Nil + * + * // Pattern match + * days match { + * case firstDay :: otherDays => + * println("The first day of the week is: " + firstDay) + * case Nil => + * println("There don't seem to be any week days.") + * } + * }}} + * + * @note The functional list is characterized by persistence and structural sharing, thus offering considerable + * performance and space consumption benefits in some scenarios if used correctly. + * However, note that objects having multiple references into the same functional list (that is, + * objects that rely on structural sharing), will be serialized and deserialized with multiple lists, one for + * each reference to it. I.e. structural sharing is lost after serialization/deserialization. + * + * @see [[https://docs.scala-lang.org/overviews/collections-2.13/concrete-immutable-collection-classes.html#lists "Scala's Collection Library overview"]] + * section on `Lists` for more information. + * + * @define coll list + * @define Coll `List` + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ @SerialVersionUID(3L) sealed abstract class List[+A] extends AbstractSeq[A] @@ -186,17 +186,6 @@ sealed abstract class List[+A] h } - /** @inheritdoc - * - * @example {{{ - * // Given a list - * val letters = List('a','b','c','d','e') - * - * // `slice` returns all elements beginning at index `from` and afterwards, - * // up until index `until` (excluding index `until`.) - * letters.slice(1,3) // Returns List('b','c') - * }}} - */ override def slice(from: Int, until: Int): List[A] = { val lo = scala.math.max(from, 0) if (until <= lo || isEmpty) Nil @@ -238,7 +227,7 @@ sealed abstract class List[+A] if (i == index && current.nonEmpty) { prefix.prependToList(elem :: current.tail) } else { - throw new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${length-1})") + throw CommonErrors.indexOutOfBounds(index = index, max = length - 1) } } diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index 0a0c01fdd8ac..74d1697cac7f 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index e2ab0de858da..2e2758cb2747 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/LongMap.scala b/src/library/scala/collection/immutable/LongMap.scala index 8c0f6e6a3bd0..8ff968f58305 100644 --- a/src/library/scala/collection/immutable/LongMap.scala +++ b/src/library/scala/collection/immutable/LongMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala index f57b6a5294dd..8f372312512e 100644 --- a/src/library/scala/collection/immutable/Map.scala +++ b/src/library/scala/collection/immutable/Map.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index ed02d17bb5c3..78efb2adafca 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,7 @@ package scala.collection.immutable import scala.collection.Stepper.EfficientSplit import scala.collection.{AbstractIterator, AnyStepper, IterableFactoryDefaults, Iterator, Stepper, StepperShape} +import scala.collection.generic.CommonErrors /** `NumericRange` is a more generic version of the * `Range` class which works with arbitrary types. @@ -104,7 +105,8 @@ sealed class NumericRange[T]( @throws[IndexOutOfBoundsException] def apply(idx: Int): T = { - if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${length - 1})") + if (idx < 0 || idx >= length) + throw CommonErrors.indexOutOfBounds(index = idx, max = length - 1) else locationAfterN(idx) } diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala index c96321cf3814..89def7096aea 100644 --- a/src/library/scala/collection/immutable/Queue.scala +++ b/src/library/scala/collection/immutable/Queue.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 07bd340fa189..9a35153ace64 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,46 +15,48 @@ package collection.immutable import scala.collection.Stepper.EfficientSplit import scala.collection.convert.impl.RangeStepper +import scala.collection.generic.CommonErrors import scala.collection.{AbstractIterator, AnyStepper, IterableFactoryDefaults, Iterator, Stepper, StepperShape} import scala.util.hashing.MurmurHash3 /** The `Range` class represents integer values in range - * ''[start;end)'' with non-zero step value `step`. - * It's a special case of an indexed sequence. - * For example: - * - * {{{ - * val r1 = 0 until 10 - * val r2 = r1.start until r1.end by r1.step + 1 - * println(r2.length) // = 5 - * }}} - * - * Ranges that contain more than `Int.MaxValue` elements can be created, but - * these overfull ranges have only limited capabilities. Any method that - * could require a collection of over `Int.MaxValue` length to be created, or - * could be asked to index beyond `Int.MaxValue` elements will throw an - * exception. Overfull ranges can safely be reduced in size by changing - * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, - * `equals`, and access to the ends of the range (`head`, `last`, `tail`, - * `init`) are also permitted on overfull ranges. - * - * @param start the start of this range. - * @param end the end of the range. For exclusive ranges, e.g. - * `Range(0,3)` or `(0 until 3)`, this is one - * step past the last one in the range. For inclusive - * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, - * it may be in the range if it is not skipped by the step size. - * To find the last element inside a non-empty range, - * use `last` instead. - * @param step the step for the range. - * - * @define coll range - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define doesNotUseBuilders - * '''Note:''' this method does not use builders to construct a new range, - * and its complexity is O(1). - */ + * ''[start;end)'' with non-zero step value `step`. + * It's a special case of an indexed sequence. + * For example: + * + * {{{ + * val r1 = 0 until 10 + * val r2 = r1.start until r1.end by r1.step + 1 + * println(r2.length) // = 5 + * }}} + * + * Ranges that contain more than `Int.MaxValue` elements can be created, but + * these overfull ranges have only limited capabilities. Any method that + * could require a collection of over `Int.MaxValue` length to be created, or + * could be asked to index beyond `Int.MaxValue` elements will throw an + * exception. Overfull ranges can safely be reduced in size by changing + * the step size (e.g. `by 3`) or taking/dropping elements. `contains`, + * `equals`, and access to the ends of the range (`head`, `last`, `tail`, + * `init`) are also permitted on overfull ranges. + * + * @param start the start of this range. + * @param end the end of the range. For exclusive ranges, e.g. + * `Range(0,3)` or `(0 until 3)`, this is one + * step past the last one in the range. For inclusive + * ranges, e.g. `Range.inclusive(0,3)` or `(0 to 3)`, + * it may be in the range if it is not skipped by the step size. + * To find the last element inside a non-empty range, + * use `last` instead. + * @param step the step for the range. + * + * @define coll range + * @define ccoll indexed sequence + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define doesNotUseBuilders + * '''Note:''' this method does not use builders to construct a new range, + * and its complexity is O(1). + */ @SerialVersionUID(3L) sealed abstract class Range( val start: Int, @@ -177,7 +179,8 @@ sealed abstract class Range( @throws[IndexOutOfBoundsException] final def apply(idx: Int): Int = { validateMaxLength() - if (idx < 0 || idx >= numRangeElements) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${numRangeElements-1})") + if (idx < 0 || idx >= numRangeElements) + throw CommonErrors.indexOutOfBounds(index = idx, max = numRangeElements - 1) else start + (step * idx) } @@ -520,11 +523,7 @@ sealed abstract class Range( } } -/** - * Companion object for ranges. - * @define Coll `Range` - * @define coll range - */ +/** Companion object for ranges. */ object Range { /** Counts the number of range elements. diff --git a/src/library/scala/collection/immutable/RedBlackTree.scala b/src/library/scala/collection/immutable/RedBlackTree.scala index 01e326fd102d..33f7d9ceb7e2 100644 --- a/src/library/scala/collection/immutable/RedBlackTree.scala +++ b/src/library/scala/collection/immutable/RedBlackTree.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -19,12 +19,12 @@ import scala.annotation.tailrec import scala.runtime.Statics.releaseFence /** An object containing the RedBlack tree implementation used by for `TreeMaps` and `TreeSets`. - * - * Implementation note: since efficiency is important for data structures this implementation - * uses `null` to represent empty trees. This also means pattern matching cannot - * easily be used. The API represented by the RedBlackTree object tries to hide these - * optimizations behind a reasonably clean API. - */ + * + * Implementation note: since efficiency is important for data structures this implementation + * uses `null` to represent empty trees. This also means pattern matching cannot + * easily be used. The API represented by the RedBlackTree object tries to hide these + * optimizations behind a reasonably clean API. + */ private[collection] object RedBlackTree { def validate[A](tree: Tree[A, _])(implicit ordering: Ordering[A]): tree.type = { def impl(tree: Tree[A, _], keyProp: A => Boolean): Int = { @@ -1236,7 +1236,7 @@ private[collection] object RedBlackTree { if((t1 eq null) || (t2 eq null)) t1 else if (t1 eq t2) null else { - val (l1, _, r1, k1) = split(t1, t2.key) + val (l1, _, r1, _) = split(t1, t2.key) val tl = _difference(l1, t2.left) val tr = _difference(r1, t2.right) join2(tl, tr) diff --git a/src/library/scala/collection/immutable/Seq.scala b/src/library/scala/collection/immutable/Seq.scala index 925fd648c70c..81a40c1c375b 100644 --- a/src/library/scala/collection/immutable/Seq.scala +++ b/src/library/scala/collection/immutable/Seq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/SeqMap.scala b/src/library/scala/collection/immutable/SeqMap.scala index 654bfa3baa21..03daef1481a8 100644 --- a/src/library/scala/collection/immutable/SeqMap.scala +++ b/src/library/scala/collection/immutable/SeqMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala index 707ddf40354f..e8509b58016e 100644 --- a/src/library/scala/collection/immutable/Set.scala +++ b/src/library/scala/collection/immutable/Set.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index 666d8c55bfb0..120ae23ae024 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/SortedSet.scala b/src/library/scala/collection/immutable/SortedSet.scala index 303e5ea9658c..2eda00ac6b2f 100644 --- a/src/library/scala/collection/immutable/SortedSet.scala +++ b/src/library/scala/collection/immutable/SortedSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 8f377f199dc3..898a988735c6 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/StrictOptimizedSeqOps.scala b/src/library/scala/collection/immutable/StrictOptimizedSeqOps.scala index caf2abc218a7..90b803d54e70 100644 --- a/src/library/scala/collection/immutable/StrictOptimizedSeqOps.scala +++ b/src/library/scala/collection/immutable/StrictOptimizedSeqOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,8 @@ package scala package collection package immutable +import scala.collection.generic.CommonErrors + /** Trait that overrides operations to take advantage of strict builders. */ trait StrictOptimizedSeqOps[+A, +CC[_], +C] @@ -38,7 +40,11 @@ trait StrictOptimizedSeqOps[+A, +CC[_], +C] } override def updated[B >: A](index: Int, elem: B): CC[B] = { - if (index < 0) throw new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${if (knownSize>=0) knownSize else "unknown"})") + if (index < 0) + throw ( + if (knownSize >= 0) CommonErrors.indexOutOfBounds(index = index, max = knownSize) + else CommonErrors.indexOutOfBounds(index = index) + ) val b = iterableFactory.newBuilder[B] b.sizeHint(this) var i = 0 @@ -47,7 +53,8 @@ trait StrictOptimizedSeqOps[+A, +CC[_], +C] b += it.next() i += 1 } - if (!it.hasNext) throw new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${i-1})") + if (!it.hasNext) + throw CommonErrors.indexOutOfBounds(index = index, max = i - 1) b += elem it.next() while (it.hasNext) b += it.next() diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index a51c7b9e7bf6..970e9a174440 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -132,6 +132,16 @@ final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit va else resultOrNull.value } + // override for performance -- no Some allocation + override def apply(key: K): V = { + val resultOrNull = RB.lookup(tree, key) + if (resultOrNull eq null) default(key) + else resultOrNull.value + } + + // override for performance -- no Some allocation + override def contains(key: K): Boolean = RB.contains(tree, key) + def removed(key: K): TreeMap[K,V] = newMapOrSelf(RB.delete(tree, key)) diff --git a/src/library/scala/collection/immutable/TreeSeqMap.scala b/src/library/scala/collection/immutable/TreeSeqMap.scala index 20862b17277a..4eaa8487b6ff 100644 --- a/src/library/scala/collection/immutable/TreeSeqMap.scala +++ b/src/library/scala/collection/immutable/TreeSeqMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -392,10 +392,11 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { if (it != Zero) push(it) - def hasNext = index != 0 + def hasNext = index > 0 @tailrec def next(): V = - pop match { + if (!hasNext) scala.collection.Iterator.empty.next() + else pop match { case Bin(_,_, Tip(_, v), right) => push(right) v diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala index 2a010cb3218b..4348f62ece74 100644 --- a/src/library/scala/collection/immutable/TreeSet.scala +++ b/src/library/scala/collection/immutable/TreeSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala index 31e97673d314..f38cdbc77b5d 100644 --- a/src/library/scala/collection/immutable/Vector.scala +++ b/src/library/scala/collection/immutable/Vector.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -20,7 +20,7 @@ import java.util.{Arrays, Spliterator} import scala.annotation.switch import scala.annotation.unchecked.uncheckedVariance import scala.collection.Stepper.EfficientSplit -import scala.collection.generic.DefaultSerializable +import scala.collection.generic.{CommonErrors, DefaultSerializable} import scala.collection.immutable.VectorInline._ import scala.collection.immutable.VectorStatics._ import scala.collection.mutable.ReusableBuilder @@ -81,8 +81,9 @@ object Vector extends StrictOptimizedSeqFactory[Vector] { } private val defaultApplyPreferredMaxLength: Int = - try System.getProperty("scala.collection.immutable.Vector.defaultApplyPreferredMaxLength", - "250").toInt + // explicit StringOps to avoid initialization cycle with Predef (scala/bug#13009) + try new StringOps(System.getProperty("scala.collection.immutable.Vector.defaultApplyPreferredMaxLength", + "250")).toInt catch { case _: SecurityException => 250 } @@ -282,7 +283,7 @@ sealed abstract class Vector[+A] private[immutable] (private[immutable] final va } protected[this] def ioob(index: Int): IndexOutOfBoundsException = - new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${length-1})") + CommonErrors.indexOutOfBounds(index = index, max = length - 1) override final def head: A = if (prefix1.length == 0) throw new NoSuchElementException("empty.head") diff --git a/src/library/scala/collection/immutable/VectorMap.scala b/src/library/scala/collection/immutable/VectorMap.scala index 9d3114273485..361427a86c53 100644 --- a/src/library/scala/collection/immutable/VectorMap.scala +++ b/src/library/scala/collection/immutable/VectorMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/WrappedString.scala b/src/library/scala/collection/immutable/WrappedString.scala index b7ef41ec9b20..a6c0256fe800 100644 --- a/src/library/scala/collection/immutable/WrappedString.scala +++ b/src/library/scala/collection/immutable/WrappedString.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/immutable/package.scala b/src/library/scala/collection/immutable/package.scala index 8458429727e8..6a92c8cef284 100644 --- a/src/library/scala/collection/immutable/package.scala +++ b/src/library/scala/collection/immutable/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/AnyRefMap.scala b/src/library/scala/collection/mutable/AnyRefMap.scala index ef8a078d1bc1..9ad433309b10 100644 --- a/src/library/scala/collection/mutable/AnyRefMap.scala +++ b/src/library/scala/collection/mutable/AnyRefMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,7 @@ package scala package collection package mutable +import scala.annotation.meta.companionClass import scala.annotation.nowarn import scala.collection.generic.DefaultSerializationProxy import scala.language.implicitConversions @@ -41,6 +42,7 @@ import scala.language.implicitConversions * rapidly as 2^30^ is approached. * */ +@(deprecated @companionClass)("Use `scala.collection.mutable.HashMap` instead for better performance.", since = "2.13.16") class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initialBufferSize: Int, initBlank: Boolean) extends AbstractMap[K, V] with MapOps[K, V, Map, AnyRefMap[K, V]] @@ -161,13 +163,17 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initi val h = hashOf(key) var i = seekEntryOrOpen(h, key) if (i < 0) { - // It is possible that the default value computation was side-effecting - // Our hash table may have resized or even contain what we want now - // (but if it does, we'll replace it) val value = { - val oh = _hashes + val ohs = _hashes + val j = i & IndexMask + val oh = ohs(j) val ans = defaultValue - if (oh ne _hashes) { + // Evaluating `defaultValue` may change the map + // - repack: the array is different + // - element added at `j`: since `i < 0`, the key was missing and `oh` is either 0 or MinValue. + // If `defaultValue` added an element at `j` then `_hashes(j)` must be different now. + // (`hashOf` never returns 0 or MinValue.) + if (ohs.ne(_hashes) || oh != _hashes(j)) { i = seekEntryOrOpen(h, key) if (i >= 0) _size -= 1 } @@ -517,6 +523,7 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initi override protected[this] def stringPrefix = "AnyRefMap" } +@deprecated("Use `scala.collection.mutable.HashMap` instead for better performance.", since = "2.13.16") object AnyRefMap { private final val IndexMask = 0x3FFFFFFF private final val MissingBit = 0x80000000 diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala index 046cd6f6602c..bc0f39af6829 100644 --- a/src/library/scala/collection/mutable/ArrayBuffer.scala +++ b/src/library/scala/collection/mutable/ArrayBuffer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,27 +17,26 @@ package mutable import java.util.Arrays import scala.annotation.{nowarn, tailrec} import scala.collection.Stepper.EfficientSplit -import scala.collection.generic.DefaultSerializable +import scala.collection.generic.{CommonErrors, DefaultSerializable} import scala.runtime.PStatics.VM_MaxArraySize /** An implementation of the `Buffer` class using an array to - * represent the assembled sequence internally. Append, update and random - * access take constant time (amortized time). Prepends and removes are - * linear in the buffer size. - * - * @see [[https://docs.scala-lang.org/overviews/collections-2.13/concrete-mutable-collection-classes.html#array-buffers "Scala's Collection Library overview"]] - * section on `Array Buffers` for more information. - - * - * @tparam A the type of this arraybuffer's elements. - * - * @define Coll `mutable.ArrayBuffer` - * @define coll array buffer - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - */ + * represent the assembled sequence internally. Append, update and random + * access take constant time (amortized time). Prepends and removes are + * linear in the buffer size. + * + * @see [[https://docs.scala-lang.org/overviews/collections-2.13/concrete-mutable-collection-classes.html#array-buffers "Scala's Collection Library overview"]] + * section on `Array Buffers` for more information. + * + * @tparam A the type of this arraybuffer's elements. + * + * @define Coll `mutable.ArrayBuffer` + * @define coll array buffer + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + */ @SerialVersionUID(-1582447879429021880L) class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int) extends AbstractBuffer[A] @@ -99,8 +98,8 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int) array = ArrayBuffer.downsize(array, requiredLength) @inline private def checkWithinBounds(lo: Int, hi: Int) = { - if (lo < 0) throw new IndexOutOfBoundsException(s"$lo is out of bounds (min 0, max ${size0 - 1})") - if (hi > size0) throw new IndexOutOfBoundsException(s"${hi - 1} is out of bounds (min 0, max ${size0 - 1})") + if (lo < 0) throw CommonErrors.indexOutOfBounds(index = lo, max = size0 - 1) + if (hi > size0) throw CommonErrors.indexOutOfBounds(index = hi - 1, max = size0 - 1) } def apply(n: Int): A = { @@ -140,9 +139,9 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int) def addOne(elem: A): this.type = { mutationCount += 1 val newSize = size0 + 1 - ensureSize(newSize) + if(array.length <= newSize - 1) ensureSize(newSize) size0 = newSize - this(size0 - 1) = elem + array(newSize - 1) = elem.asInstanceOf[AnyRef] this } @@ -192,7 +191,7 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int) // the previous line // - `copyElemsToArray` will call `System.arraycopy` // - `System.arraycopy` will effectively "read" all the values before - // overwriting any of them when two arrays are the the same reference + // overwriting any of them when two arrays are the same reference val actual = IterableOnce.copyElemsToArray(elems, array.asInstanceOf[Array[Any]], index, elemsLength) if (actual != elemsLength) throw new IllegalStateException(s"Copied $actual of $elemsLength") size0 = len + elemsLength // update size AFTER the copy, in case we're inserting a proxy @@ -269,9 +268,16 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int) override def foldRight[B](z: B)(op: (A, B) => B): B = foldr(0, length, z, op) - override def reduceLeft[B >: A](op: (B, A) => B): B = if (length > 0) foldl(1, length, array(0).asInstanceOf[B], op) else super.reduceLeft(op) + override def reduceLeft[B >: A](op: (B, A) => B): B = + if (length > 0) foldl(1, length, array(0).asInstanceOf[B], op) + else super.reduceLeft(op) + + override def reduceRight[B >: A](op: (A, B) => B): B = + if (length > 0) foldr(0, length - 1, array(length - 1).asInstanceOf[B], op) + else super.reduceRight(op) - override def reduceRight[B >: A](op: (A, B) => B): B = if (length > 0) foldr(0, length - 1, array(length - 1).asInstanceOf[B], op) else super.reduceRight(op) + override def sliding(size: Int, step: Int): Iterator[ArrayBuffer[A]] = + new MutationTracker.CheckedIterator(super.sliding(size = size, step = step), mutationCount) } /** @@ -316,20 +322,12 @@ object ArrayBuffer extends StrictOptimizedSeqFactory[ArrayBuffer] { * - `max(targetLen, arrayLen * 2, DefaultInitialSize)`. * - Throws an exception if `targetLen` exceeds `VM_MaxArraySize` or is negative (overflow). */ - private[mutable] def resizeUp(arrayLen: Int, targetLen: Int): Int = { - def checkArrayLengthLimit(): Unit = - if (targetLen > VM_MaxArraySize) - throw new Exception(s"Array of array-backed collection exceeds VM length limit of $VM_MaxArraySize. Requested length: $targetLen; current length: $arrayLen") - else if (targetLen < 0) - throw new Exception(s"Overflow while resizing array of array-backed collection. Requested length: $targetLen; current length: $arrayLen; increase: ${targetLen - arrayLen}") - - if (targetLen > 0 && targetLen <= arrayLen) -1 - else { - checkArrayLengthLimit() - if (arrayLen > VM_MaxArraySize / 2) VM_MaxArraySize - else math.max(targetLen, math.max(arrayLen * 2, DefaultInitialSize)) - } - } + private[mutable] def resizeUp(arrayLen: Int, targetLen: Int): Int = + if (targetLen < 0) throw new RuntimeException(s"Overflow while resizing array of array-backed collection. Requested length: $targetLen; current length: $arrayLen; increase: ${targetLen - arrayLen}") + else if (targetLen <= arrayLen) -1 + else if (targetLen > VM_MaxArraySize) throw new RuntimeException(s"Array of array-backed collection exceeds VM length limit of $VM_MaxArraySize. Requested length: $targetLen; current length: $arrayLen") + else if (arrayLen > VM_MaxArraySize / 2) VM_MaxArraySize + else math.max(targetLen, math.max(arrayLen * 2, DefaultInitialSize)) // if necessary, copy (curSize elements of) the array to a new array of capacity n. // Should use Array.copyOf(array, resizeEnsuring(array.length))? diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index 0ad9b082c427..e962dd024836 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -25,7 +25,7 @@ sealed abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable { protected[this] var capacity: Int = 0 - protected[this] def elems: Array[T] + protected[this] def elems: Array[T] // may not be allocated at size = capacity = 0 protected var size: Int = 0 /** Current number of elements. */ @@ -45,14 +45,23 @@ sealed abstract class ArrayBuilder[T] protected[this] def resize(size: Int): Unit - /** Add all elements of an array */ + /** Add all elements of an array. */ def addAll(xs: Array[_ <: T]): this.type = addAll(xs, 0, xs.length) - /** Add a slice of an array */ + /** Add a slice of an array. */ def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = { - ensureSize(this.size + length) - Array.copy(xs, offset, elems, this.size, length) - size += length + val offset1 = offset.max(0) + val length1 = length.max(0) + val effectiveLength = length1.min(xs.length - offset1) + doAddAll(xs, offset1, effectiveLength) + } + + private def doAddAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = { + if (length > 0) { + ensureSize(this.size + length) + Array.copy(xs, offset, elems, this.size, length) + size += length + } this } diff --git a/src/library/scala/collection/mutable/ArrayDeque.scala b/src/library/scala/collection/mutable/ArrayDeque.scala index f164c76283bc..ca70f31d1869 100644 --- a/src/library/scala/collection/mutable/ArrayDeque.scala +++ b/src/library/scala/collection/mutable/ArrayDeque.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,7 +16,7 @@ package mutable import scala.annotation.nowarn import scala.collection.Stepper.EfficientSplit -import scala.collection.generic.DefaultSerializable +import scala.collection.generic.{CommonErrors, DefaultSerializable} import scala.reflect.ClassTag /** An implementation of a double-ended queue that internally uses a resizable circular buffer. @@ -580,7 +580,8 @@ trait ArrayDequeOps[A, +CC[_], +C <: AnyRef] extends StrictOptimizedSeqOps[A, CC protected def start_+(idx: Int): Int @inline protected final def requireBounds(idx: Int, until: Int = length): Unit = - if (idx < 0 || idx >= until) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${until-1})") + if (idx < 0 || idx >= until) + throw CommonErrors.indexOutOfBounds(index = idx, max = until - 1) /** * This is a more general version of copyToArray - this also accepts a srcStart unlike copyToArray @@ -632,16 +633,8 @@ trait ArrayDequeOps[A, +CC[_], +C <: AnyRef] extends StrictOptimizedSeqOps[A, CC } } - override def sliding(window: Int, step: Int): Iterator[C] = { - require(window > 0 && step > 0, s"window=$window and step=$step, but both must be positive") - length match { - case 0 => Iterator.empty - case n if n <= window => Iterator.single(slice(0, length)) - case n => - val lag = if (window > step) window - step else 0 - Iterator.range(start = 0, end = n - lag, step = step).map(i => slice(i, i + window)) - } - } + override def sliding(@deprecatedName("window") size: Int, step: Int): Iterator[C] = + super.sliding(size = size, step = step) override def grouped(n: Int): Iterator[C] = sliding(n, n) } diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala index b315c870e87c..0537092d0b13 100644 --- a/src/library/scala/collection/mutable/ArraySeq.scala +++ b/src/library/scala/collection/mutable/ArraySeq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -42,13 +42,13 @@ sealed abstract class ArraySeq[T] override def iterableFactory: scala.collection.SeqFactory[ArraySeq] = ArraySeq.untagged override protected def fromSpecific(coll: scala.collection.IterableOnce[T]): ArraySeq[T] = { - val b = ArrayBuilder.make(elemTag).asInstanceOf[ArrayBuilder[T]] + val b = ArrayBuilder.make(using elemTag).asInstanceOf[ArrayBuilder[T]] b.sizeHint(coll, delta = 0) b ++= coll ArraySeq.make(b.result()) } - override protected def newSpecificBuilder: Builder[T, ArraySeq[T]] = ArraySeq.newBuilder(elemTag).asInstanceOf[Builder[T, ArraySeq[T]]] - override def empty: ArraySeq[T] = ArraySeq.empty(elemTag.asInstanceOf[ClassTag[T]]) + override protected def newSpecificBuilder: Builder[T, ArraySeq[T]] = ArraySeq.newBuilder(using elemTag).asInstanceOf[Builder[T, ArraySeq[T]]] + override def empty: ArraySeq[T] = ArraySeq.empty(using elemTag.asInstanceOf[ClassTag[T]]) /** The tag of the element type. This does not have to be equal to the element type of this ArraySeq. A primitive * ArraySeq can be backed by an array of boxed values and a reference ArraySeq can be backed by an array of a supertype diff --git a/src/library/scala/collection/mutable/BitSet.scala b/src/library/scala/collection/mutable/BitSet.scala index 89c5687189d7..ba77d7161a0b 100644 --- a/src/library/scala/collection/mutable/BitSet.scala +++ b/src/library/scala/collection/mutable/BitSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Buffer.scala b/src/library/scala/collection/mutable/Buffer.scala index dc0ac517a938..2ec13c1fdbc5 100644 --- a/src/library/scala/collection/mutable/Buffer.scala +++ b/src/library/scala/collection/mutable/Buffer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,7 +16,11 @@ package mutable import scala.annotation.nowarn -/** A `Buffer` is a growable and shrinkable `Seq`. */ +/** A `Buffer` is a growable and shrinkable `Seq`. + * + * @define coll buffer + * @define Coll `Buffer` + */ trait Buffer[A] extends Seq[A] with SeqOps[A, Buffer, Buffer[A]] diff --git a/src/library/scala/collection/mutable/Builder.scala b/src/library/scala/collection/mutable/Builder.scala index 072c057ab41f..e59fc8639104 100644 --- a/src/library/scala/collection/mutable/Builder.scala +++ b/src/library/scala/collection/mutable/Builder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -91,7 +91,7 @@ trait Builder[-A, +To] extends Growable[A] { self => } } - /** A builder resulting from this builder my mapping the result using `f`. */ + /** A builder resulting from this builder by mapping the result using `f`. */ def mapResult[NewTo](f: To => NewTo): Builder[A, NewTo] = new Builder[A, NewTo] { def addOne(x: A): this.type = { self += x; this } def clear(): Unit = self.clear() diff --git a/src/library/scala/collection/mutable/CheckedIndexedSeqView.scala b/src/library/scala/collection/mutable/CheckedIndexedSeqView.scala index b9598904375d..6953dd0ed660 100644 --- a/src/library/scala/collection/mutable/CheckedIndexedSeqView.scala +++ b/src/library/scala/collection/mutable/CheckedIndexedSeqView.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Cloneable.scala b/src/library/scala/collection/mutable/Cloneable.scala index 940ecf3549ad..5c11faea155e 100644 --- a/src/library/scala/collection/mutable/Cloneable.scala +++ b/src/library/scala/collection/mutable/Cloneable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/CollisionProofHashMap.scala b/src/library/scala/collection/mutable/CollisionProofHashMap.scala index 916621c5600e..f56e679df2d2 100644 --- a/src/library/scala/collection/mutable/CollisionProofHashMap.scala +++ b/src/library/scala/collection/mutable/CollisionProofHashMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -766,7 +766,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { @SerialVersionUID(3L) private final class DeserializationFactory[K, V](val tableLength: Int, val loadFactor: Double, val ordering: Ordering[K]) extends Factory[(K, V), CollisionProofHashMap[K, V]] with Serializable { def fromSpecific(it: IterableOnce[(K, V)]): CollisionProofHashMap[K, V] = new CollisionProofHashMap[K, V](tableLength, loadFactor)(ordering) ++= it - def newBuilder: Builder[(K, V), CollisionProofHashMap[K, V]] = CollisionProofHashMap.newBuilder(tableLength, loadFactor)(ordering) + def newBuilder: Builder[(K, V), CollisionProofHashMap[K, V]] = CollisionProofHashMap.newBuilder(tableLength, loadFactor)(using ordering) } @unused @`inline` private def compare[K, V](key: K, hash: Int, node: LLNode[K, V])(implicit ord: Ordering[K]): Int = { diff --git a/src/library/scala/collection/mutable/Growable.scala b/src/library/scala/collection/mutable/Growable.scala index f37b06bcccbb..b2d4806089dc 100644 --- a/src/library/scala/collection/mutable/Growable.scala +++ b/src/library/scala/collection/mutable/Growable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/GrowableBuilder.scala b/src/library/scala/collection/mutable/GrowableBuilder.scala index 7e945dffb99e..247bc58da150 100644 --- a/src/library/scala/collection/mutable/GrowableBuilder.scala +++ b/src/library/scala/collection/mutable/GrowableBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala index 4647ded6113b..86aa9541c4e3 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala index 332888a48287..9f0abbfa6cfd 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index 4153bd532163..d58f6e01b7ac 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/ImmutableBuilder.scala b/src/library/scala/collection/mutable/ImmutableBuilder.scala index c801f073fb0d..3907cfd55305 100644 --- a/src/library/scala/collection/mutable/ImmutableBuilder.scala +++ b/src/library/scala/collection/mutable/ImmutableBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/IndexedSeq.scala b/src/library/scala/collection/mutable/IndexedSeq.scala index 24d54905de22..464bc00d45db 100644 --- a/src/library/scala/collection/mutable/IndexedSeq.scala +++ b/src/library/scala/collection/mutable/IndexedSeq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Iterable.scala b/src/library/scala/collection/mutable/Iterable.scala index d05aeed88044..c84d0e6ec675 100644 --- a/src/library/scala/collection/mutable/Iterable.scala +++ b/src/library/scala/collection/mutable/Iterable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala index ec547803bec9..d529fee42596 100644 --- a/src/library/scala/collection/mutable/LinkedHashMap.scala +++ b/src/library/scala/collection/mutable/LinkedHashMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index e247cbce5926..1a189d607010 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index 452dcdb49c3e..241f1edc480b 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,7 @@ package scala.collection package mutable import scala.annotation.{nowarn, tailrec} +import scala.collection.generic.CommonErrors import scala.collection.immutable.{::, List, Nil} import java.lang.{IllegalArgumentException, IndexOutOfBoundsException} @@ -50,7 +51,7 @@ class ListBuffer[A] private[this] var aliased = false private[this] var len = 0 - private type Predecessor[A0] = ::[A0] /*| Null*/ + private type Predecessor = ::[A] /*| Null*/ def iterator: Iterator[A] = new MutationTracker.CheckedIterator(first.iterator, mutationCount) @@ -185,7 +186,8 @@ class ListBuffer[A] last0 = null } - private def locate(i: Int): Predecessor[A] = + // returns the `::` at `i - 1` (such that its `next` at position `i` can be mutated), or `null` if `i == 0`. + private def predecessor(i: Int): Predecessor = if (i == 0) null else if (i == len) last0 else { @@ -195,15 +197,15 @@ class ListBuffer[A] p = p.tail j -= 1 } - p.asInstanceOf[Predecessor[A]] + p.asInstanceOf[Predecessor] } - private def getNext(p: Predecessor[A]): List[A] = + private def getNext(p: Predecessor): List[A] = if (p == null) first else p.next def update(idx: Int, elem: A): Unit = { ensureUnaliased() - if (idx < 0 || idx >= len) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${len-1})") + if (idx < 0 || idx >= len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) if (idx == 0) { val newElem = new :: (elem, first.tail) if (last0 eq first) { @@ -212,7 +214,7 @@ class ListBuffer[A] first = newElem } else { // `p` can not be `null` because the case where `idx == 0` is handled above - val p = locate(idx) + val p = predecessor(idx) val newElem = new :: (elem, p.tail.tail) if (last0 eq p.tail) { last0 = newElem @@ -223,10 +225,10 @@ class ListBuffer[A] def insert(idx: Int, elem: A): Unit = { ensureUnaliased() - if (idx < 0 || idx > len) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${len-1})") + if (idx < 0 || idx > len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) if (idx == len) addOne(elem) else { - val p = locate(idx) + val p = predecessor(idx) val nx = elem :: getNext(p) if(p eq null) first = nx else p.next = nx len += 1 @@ -239,7 +241,7 @@ class ListBuffer[A] } // `fresh` must be a `ListBuffer` that only we have access to - private def insertAfter(prev: Predecessor[A], fresh: ListBuffer[A]): Unit = { + private def insertAfter(prev: Predecessor, fresh: ListBuffer[A]): Unit = { if (!fresh.isEmpty) { val follow = getNext(prev) if (prev eq null) first = fresh.first else prev.next = fresh.first @@ -250,22 +252,22 @@ class ListBuffer[A] } def insertAll(idx: Int, elems: IterableOnce[A]): Unit = { - if (idx < 0 || idx > len) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${len-1})") + if (idx < 0 || idx > len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) val it = elems.iterator if (it.hasNext) { if (idx == len) addAll(it) else { val fresh = new ListBuffer[A].freshFrom(it) ensureUnaliased() - insertAfter(locate(idx), fresh) + insertAfter(predecessor(idx), fresh) } } } def remove(idx: Int): A = { ensureUnaliased() - if (idx < 0 || idx >= len) throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${len-1})") - val p = locate(idx) + if (idx < 0 || idx >= len) throw CommonErrors.indexOutOfBounds(index = idx, max = len - 1) + val p = predecessor(idx) val nx = getNext(p) if(p eq null) { first = nx.tail @@ -281,13 +283,13 @@ class ListBuffer[A] def remove(idx: Int, count: Int): Unit = if (count > 0) { ensureUnaliased() - if (idx < 0 || idx + count > len) throw new IndexOutOfBoundsException(s"$idx to ${idx + count} is out of bounds (min 0, max ${len-1})") - removeAfter(locate(idx), count) + if (idx < 0 || idx + count > len) throw new IndexOutOfBoundsException(s"$idx to ${idx + count} is out of bounds (min 0, max ${len - 1})") + removeAfter(predecessor(idx), count) } else if (count < 0) { throw new IllegalArgumentException("removing negative number of elements: " + count) } - private def removeAfter(prev: Predecessor[A], n: Int) = { + private def removeAfter(prev: Predecessor, n: Int) = { @tailrec def ahead(p: List[A], n: Int): List[A] = if (n == 0) p else ahead(p.tail, n - 1) val nx = ahead(getNext(prev), n) @@ -344,7 +346,7 @@ class ListBuffer[A] */ def filterInPlace(p: A => Boolean): this.type = { ensureUnaliased() - var prev: Predecessor[A] = null + var prev: Predecessor = null var cur: List[A] = first while (!cur.isEmpty) { val follow = cur.tail @@ -353,7 +355,7 @@ class ListBuffer[A] else prev.next = follow len -= 1 } else { - prev = cur.asInstanceOf[Predecessor[A]] + prev = cur.asInstanceOf[Predecessor] } cur = follow } @@ -377,7 +379,7 @@ class ListBuffer[A] ensureUnaliased() val i = math.min(_from, _len) val n = math.min(_replaced, _len) - val p = locate(i) + val p = predecessor(i) removeAfter(p, math.min(n, _len - i)) insertAfter(p, fresh) } diff --git a/src/library/scala/collection/mutable/ListMap.scala b/src/library/scala/collection/mutable/ListMap.scala index 7cc5aa227757..e1a273bfd5af 100644 --- a/src/library/scala/collection/mutable/ListMap.scala +++ b/src/library/scala/collection/mutable/ListMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/LongMap.scala b/src/library/scala/collection/mutable/LongMap.scala index 2a0d43fa1b59..e36c337437e3 100644 --- a/src/library/scala/collection/mutable/LongMap.scala +++ b/src/library/scala/collection/mutable/LongMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -185,13 +185,17 @@ final class LongMap[V] private[collection] (defaultEntry: Long => V, initialBuff else { var i = seekEntryOrOpen(key) if (i < 0) { - // It is possible that the default value computation was side-effecting - // Our hash table may have resized or even contain what we want now - // (but if it does, we'll replace it) val value = { - val ok = _keys + val oks = _keys + val j = i & IndexMask + val ok = oks(j) val ans = defaultValue - if (ok ne _keys) { + // Evaluating `defaultValue` may change the map + // - repack: the array is different + // - element added at `j`: since `i < 0`, the key was missing and `ok` is either 0 or MinValue. + // If `defaultValue` added an element at `j` then `_keys(j)` must be different now. + // (`_keys` never contains 0 or MinValue.) + if (oks.ne(_keys) || ok != _keys(j)) { i = seekEntryOrOpen(key) if (i >= 0) _size -= 1 } @@ -269,19 +273,14 @@ final class LongMap[V] private[collection] (defaultEntry: Long => V, initialBuff } /** Repacks the contents of this `LongMap` for maximum efficiency of lookup. - * - * For maps that undergo a complex creation process with both addition and - * removal of keys, and then are used heavily with no further removal of - * elements, calling `repack` after the end of the creation can result in - * improved performance. Repacking takes time proportional to the number - * of entries in the map. - */ - def repack(): Unit = { - var m = mask - if (_size + _vacant >= 0.5*mask && !(_vacant > 0.2*mask)) m = ((m << 1) + 1) & IndexMask - while (m > 8 && 8*_size < m) m = m >>> 1 - repack(m) - } + * + * For maps that undergo a complex creation process with both addition and + * removal of keys, and then are used heavily with no further removal of + * elements, calling `repack` after the end of the creation can result in + * improved performance. Repacking takes time proportional to the number + * of entries in the map. + */ + def repack(): Unit = repack(repackMask(mask, _size = _size, _vacant = _vacant)) override def put(key: Long, value: V): Option[V] = { if (key == -key) { @@ -587,10 +586,10 @@ final class LongMap[V] private[collection] (defaultEntry: Long => V, initialBuff } object LongMap { - private final val IndexMask = 0x3FFFFFFF - private final val MissingBit = 0x80000000 - private final val VacantBit = 0x40000000 - private final val MissVacant = 0xC0000000 + private final val IndexMask = 0x3FFF_FFFF + private final val MissingBit = 0x8000_0000 + private final val VacantBit = 0x4000_0000 + private final val MissVacant = 0xC000_0000 private val exceptionDefault: Long => Nothing = (k: Long) => throw new NoSuchElementException(k.toString) @@ -682,4 +681,11 @@ object LongMap { implicit def iterableFactory[V]: Factory[(Long, V), LongMap[V]] = toFactory(this) implicit def buildFromLongMap[V]: BuildFrom[LongMap[_], (Long, V), LongMap[V]] = toBuildFrom(this) + + private def repackMask(mask: Int, _size: Int, _vacant: Int): Int = { + var m = mask + if (_size + _vacant >= 0.5*mask && !(_vacant > 0.2*mask)) m = ((m << 1) + 1) & IndexMask + while (m > 8 && _size < (m >>> 3)) m = m >>> 1 + m /*.ensuring(_size <= _ + 1)*/ + } } diff --git a/src/library/scala/collection/mutable/Map.scala b/src/library/scala/collection/mutable/Map.scala index c22d3cc783fd..8659b45e86e6 100644 --- a/src/library/scala/collection/mutable/Map.scala +++ b/src/library/scala/collection/mutable/Map.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -128,11 +128,11 @@ trait MapOps[K, V, +CC[X, Y] <: MapOps[X, Y, CC, _], +C <: MapOps[K, V, CC, C]] /** If given key is already in this map, returns associated value. * - * Otherwise, computes value from given expression `op`, stores with key + * Otherwise, computes value from given expression `defaultValue`, stores with key * in map and returns that value. * - * Concurrent map implementations may evaluate the expression `op` - * multiple times, or may evaluate `op` without inserting the result. + * Concurrent map implementations may evaluate the expression `defaultValue` + * multiple times, or may evaluate `defaultValue` without inserting the result. * * @param key the key to test * @param defaultValue the computation yielding the value to associate with `key`, if diff --git a/src/library/scala/collection/mutable/MultiMap.scala b/src/library/scala/collection/mutable/MultiMap.scala index 13d7c35e0165..b06a99b15d51 100644 --- a/src/library/scala/collection/mutable/MultiMap.scala +++ b/src/library/scala/collection/mutable/MultiMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/MutationTracker.scala b/src/library/scala/collection/mutable/MutationTracker.scala index e98536d0dad5..fe0314068a43 100644 --- a/src/library/scala/collection/mutable/MutationTracker.scala +++ b/src/library/scala/collection/mutable/MutationTracker.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/OpenHashMap.scala b/src/library/scala/collection/mutable/OpenHashMap.scala index 22e99d4650d1..5840a0abc954 100644 --- a/src/library/scala/collection/mutable/OpenHashMap.scala +++ b/src/library/scala/collection/mutable/OpenHashMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 1c01dfd4e209..147cffc22a95 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala index 18cce0bd3852..cc3dad2e2495 100644 --- a/src/library/scala/collection/mutable/Queue.scala +++ b/src/library/scala/collection/mutable/Queue.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/RedBlackTree.scala b/src/library/scala/collection/mutable/RedBlackTree.scala index 0e14151e10ed..aca36f0271d8 100644 --- a/src/library/scala/collection/mutable/RedBlackTree.scala +++ b/src/library/scala/collection/mutable/RedBlackTree.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/ReusableBuilder.scala b/src/library/scala/collection/mutable/ReusableBuilder.scala index d7d3b6db4f09..c8565d6953f1 100644 --- a/src/library/scala/collection/mutable/ReusableBuilder.scala +++ b/src/library/scala/collection/mutable/ReusableBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Seq.scala b/src/library/scala/collection/mutable/Seq.scala index e83d79987208..afabb834a63f 100644 --- a/src/library/scala/collection/mutable/Seq.scala +++ b/src/library/scala/collection/mutable/Seq.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/SeqMap.scala b/src/library/scala/collection/mutable/SeqMap.scala index 67066f99e07e..dda2c47c3447 100644 --- a/src/library/scala/collection/mutable/SeqMap.scala +++ b/src/library/scala/collection/mutable/SeqMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Set.scala b/src/library/scala/collection/mutable/Set.scala index 6530e8fedf05..cede5411a349 100644 --- a/src/library/scala/collection/mutable/Set.scala +++ b/src/library/scala/collection/mutable/Set.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/Shrinkable.scala b/src/library/scala/collection/mutable/Shrinkable.scala index 006a3b88e49f..acf1b4bf42ac 100644 --- a/src/library/scala/collection/mutable/Shrinkable.scala +++ b/src/library/scala/collection/mutable/Shrinkable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,30 +16,30 @@ package collection.mutable import scala.annotation.tailrec /** This trait forms part of collections that can be reduced - * using a `-=` operator. - * - * @define coll shrinkable collection - * @define Coll `Shrinkable` - */ + * using a `-=` operator. + * + * @define coll shrinkable collection + * @define Coll `Shrinkable` + */ trait Shrinkable[-A] { /** Removes a single element from this $coll. - * - * @param elem the element to remove. - * @return the $coll itself - */ + * + * @param elem the element to remove. + * @return the $coll itself + */ def subtractOne(elem: A): this.type /** Alias for `subtractOne` */ @`inline` final def -= (elem: A): this.type = subtractOne(elem) /** Removes two or more elements from this $coll. - * - * @param elem1 the first element to remove. - * @param elem2 the second element to remove. - * @param elems the remaining elements to remove. - * @return the $coll itself - */ + * + * @param elem1 the first element to remove. + * @param elem2 the second element to remove. + * @param elems the remaining elements to remove. + * @return the $coll itself + */ @deprecated("Use `--=` aka `subtractAll` instead of varargs `-=`; infix operations with an operand of multiple args will be deprecated", "2.13.3") def -= (elem1: A, elem2: A, elems: A*): this.type = { this -= elem1 @@ -48,10 +48,10 @@ trait Shrinkable[-A] { } /** Removes all elements produced by an iterator from this $coll. - * - * @param xs the iterator producing the elements to remove. - * @return the $coll itself - */ + * + * @param xs the iterator producing the elements to remove. + * @return the $coll itself + */ def subtractAll(xs: collection.IterableOnce[A]): this.type = { @tailrec def loop(xs: collection.LinearSeq[A]): Unit = { if (xs.nonEmpty) { diff --git a/src/library/scala/collection/mutable/SortedMap.scala b/src/library/scala/collection/mutable/SortedMap.scala index eb2f0d231b7a..1884840f91e2 100644 --- a/src/library/scala/collection/mutable/SortedMap.scala +++ b/src/library/scala/collection/mutable/SortedMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/SortedSet.scala b/src/library/scala/collection/mutable/SortedSet.scala index 2bcb8dc7845a..7faf70b87cdc 100644 --- a/src/library/scala/collection/mutable/SortedSet.scala +++ b/src/library/scala/collection/mutable/SortedSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,9 +14,8 @@ package scala package collection package mutable -/** - * Base type for mutable sorted set collections - */ +/** Base type for mutable sorted set collections + */ trait SortedSet[A] extends Set[A] with collection.SortedSet[A] @@ -30,7 +29,7 @@ trait SortedSet[A] /** * @define coll mutable sorted set - * @define Coll `mutable.Sortedset` + * @define Coll `mutable.SortedSet` */ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]] extends SetOps[A, Set, C] @@ -40,9 +39,7 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]] } /** - * $factoryInfo - * @define coll mutable sorted set - * @define Coll `mutable.Sortedset` - */ + * $factoryInfo + */ @SerialVersionUID(3L) object SortedSet extends SortedIterableFactory.Delegate[SortedSet](TreeSet) diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala index ff2beda3ff24..01aacc22c65e 100644 --- a/src/library/scala/collection/mutable/Stack.scala +++ b/src/library/scala/collection/mutable/Stack.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala index 1d8b9563e917..ad9755389c48 100644 --- a/src/library/scala/collection/mutable/StringBuilder.scala +++ b/src/library/scala/collection/mutable/StringBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/TreeMap.scala b/src/library/scala/collection/mutable/TreeMap.scala index 8fcb7b688a1f..076239278299 100644 --- a/src/library/scala/collection/mutable/TreeMap.scala +++ b/src/library/scala/collection/mutable/TreeMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/TreeSet.scala b/src/library/scala/collection/mutable/TreeSet.scala index bed474dc02a3..9820af9037ca 100644 --- a/src/library/scala/collection/mutable/TreeSet.scala +++ b/src/library/scala/collection/mutable/TreeSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala index 64a660143bae..4aecac001505 100644 --- a/src/library/scala/collection/mutable/UnrolledBuffer.scala +++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,7 +14,7 @@ package scala.collection package mutable import scala.annotation.tailrec -import scala.collection.generic.DefaultSerializable +import scala.collection.generic.{CommonErrors, DefaultSerializable} import scala.reflect.ClassTag import scala.collection.immutable.Nil @@ -158,11 +158,11 @@ sealed class UnrolledBuffer[T](implicit val tag: ClassTag[T]) def apply(idx: Int) = if (idx >= 0 && idx < sz) headptr(idx) - else throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${sz-1})") + else throw CommonErrors.indexOutOfBounds(index = idx, max = sz - 1) def update(idx: Int, newelem: T) = if (idx >= 0 && idx < sz) headptr(idx) = newelem - else throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${sz-1})") + else throw CommonErrors.indexOutOfBounds(index = idx, max = sz - 1) /** Replace the contents of this $coll with the mapped result. * @@ -178,7 +178,7 @@ sealed class UnrolledBuffer[T](implicit val tag: ClassTag[T]) if (idx >= 0 && idx < sz) { sz -= 1 headptr.remove(idx, this) - } else throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${sz-1})") + } else throw CommonErrors.indexOutOfBounds(index = idx, max = sz - 1) @tailrec final def remove(idx: Int, count: Int): Unit = if (count > 0) { @@ -198,7 +198,7 @@ sealed class UnrolledBuffer[T](implicit val tag: ClassTag[T]) def insertAll(idx: Int, elems: IterableOnce[T]): Unit = if (idx >= 0 && idx <= sz) { sz += headptr.insertAll(idx, elems, this) - } else throw new IndexOutOfBoundsException(s"$idx is out of bounds (min 0, max ${sz-1})") + } else throw CommonErrors.indexOutOfBounds(index = idx, max = sz - 1) override def subtractOne(elem: T): this.type = { if (headptr.subtractOne(elem, this)) { diff --git a/src/library/scala/collection/mutable/WeakHashMap.scala b/src/library/scala/collection/mutable/WeakHashMap.scala index 7286a318e1f9..ae0230c8ab83 100644 --- a/src/library/scala/collection/mutable/WeakHashMap.scala +++ b/src/library/scala/collection/mutable/WeakHashMap.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/mutable/package.scala b/src/library/scala/collection/mutable/package.scala index 4915e8a48b22..4ad5df4813d8 100644 --- a/src/library/scala/collection/mutable/package.scala +++ b/src/library/scala/collection/mutable/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/collection/package.scala b/src/library/scala/collection/package.scala index 954573ff1ddd..f6a89b5c288c 100644 --- a/src/library/scala/collection/package.scala +++ b/src/library/scala/collection/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/compat/Platform.scala b/src/library/scala/compat/Platform.scala index 22c778cc9210..b3ecb194a12c 100644 --- a/src/library/scala/compat/Platform.scala +++ b/src/library/scala/compat/Platform.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/Awaitable.scala b/src/library/scala/concurrent/Awaitable.scala index d201a14570f2..1372e1614ac8 100644 --- a/src/library/scala/concurrent/Awaitable.scala +++ b/src/library/scala/concurrent/Awaitable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/BatchingExecutor.scala b/src/library/scala/concurrent/BatchingExecutor.scala index d9ae17cc7064..ac197c89f8c1 100644 --- a/src/library/scala/concurrent/BatchingExecutor.scala +++ b/src/library/scala/concurrent/BatchingExecutor.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/BlockContext.scala b/src/library/scala/concurrent/BlockContext.scala index e282a4125c33..37483c307fd0 100644 --- a/src/library/scala/concurrent/BlockContext.scala +++ b/src/library/scala/concurrent/BlockContext.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/Channel.scala b/src/library/scala/concurrent/Channel.scala index 66feb4d7083b..a9ada60e3da0 100644 --- a/src/library/scala/concurrent/Channel.scala +++ b/src/library/scala/concurrent/Channel.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/DelayedLazyVal.scala b/src/library/scala/concurrent/DelayedLazyVal.scala index f7049dc1fdb8..1a450c3c0458 100644 --- a/src/library/scala/concurrent/DelayedLazyVal.scala +++ b/src/library/scala/concurrent/DelayedLazyVal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index 41dfbb609816..b132e2dee5b7 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 1be6130db645..4142d8400200 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,15 +14,14 @@ package scala.concurrent import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.locks.LockSupport - -import scala.util.control.{NonFatal, NoStackTrace} +import scala.util.control.{NoStackTrace, NonFatal} import scala.util.{Failure, Success, Try} import scala.concurrent.duration._ import scala.collection.BuildFrom -import scala.collection.mutable.{Builder, ArrayBuffer} +import scala.collection.mutable.{ArrayBuffer, Builder} import scala.reflect.ClassTag - import scala.concurrent.ExecutionContext.parasitic +import scala.concurrent.impl.Promise.DefaultPromise /** A `Future` represents a value which may or may not be currently available, * but will be available at some point, or an exception if that value could not be made available. @@ -126,7 +125,6 @@ trait Future[+T] extends Awaitable[T] { */ def onComplete[U](f: Try[T] => U)(implicit executor: ExecutionContext): Unit - /* Miscellaneous */ /** Returns whether the future had already been completed with @@ -732,15 +730,28 @@ object Future { if (!i.hasNext) Future.never else { val p = Promise[T]() - val firstCompleteHandler = new AtomicReference[Promise[T]](p) with (Try[T] => Unit) { - override final def apply(v1: Try[T]): Unit = { - val r = getAndSet(null) - if (r ne null) - r tryComplete v1 // tryComplete is likely to be cheaper than complete + val firstCompleteHandler = new AtomicReference(List.empty[() => Unit]) with (Try[T] => Unit) { + final def apply(res: Try[T]): Unit = { + val deregs = getAndSet(null) + if (deregs != null) { + p.tryComplete(res) // tryComplete is likely to be cheaper than complete + deregs.foreach(_.apply()) + } + } + } + var completed = false + while (i.hasNext && !completed) { + val deregs = firstCompleteHandler.get + if (deregs == null) completed = true + else i.next() match { + case dp: DefaultPromise[T @unchecked] => + val d = dp.onCompleteWithUnregister(firstCompleteHandler) + if (!firstCompleteHandler.compareAndSet(deregs, d :: deregs)) + d.apply() + case f => + f.onComplete(firstCompleteHandler) } } - while(i.hasNext && firstCompleteHandler.get != null) // exit early if possible - i.next().onComplete(firstCompleteHandler) p.future } } diff --git a/src/library/scala/concurrent/JavaConversions.scala b/src/library/scala/concurrent/JavaConversions.scala index 15a6483f87b9..3250e656941a 100644 --- a/src/library/scala/concurrent/JavaConversions.scala +++ b/src/library/scala/concurrent/JavaConversions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/Promise.scala b/src/library/scala/concurrent/Promise.scala index e13541b17bc7..cf3f23543c5a 100644 --- a/src/library/scala/concurrent/Promise.scala +++ b/src/library/scala/concurrent/Promise.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/SyncChannel.scala b/src/library/scala/concurrent/SyncChannel.scala index 306512bc2c3b..8792524524c3 100644 --- a/src/library/scala/concurrent/SyncChannel.scala +++ b/src/library/scala/concurrent/SyncChannel.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala index 66cefc828c43..66c5fd1bb81d 100644 --- a/src/library/scala/concurrent/SyncVar.scala +++ b/src/library/scala/concurrent/SyncVar.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/duration/Deadline.scala b/src/library/scala/concurrent/duration/Deadline.scala index 9a81d1423910..353d0f30fff8 100644 --- a/src/library/scala/concurrent/duration/Deadline.scala +++ b/src/library/scala/concurrent/duration/Deadline.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala index 1f84b1e67340..1312bb12d1d5 100644 --- a/src/library/scala/concurrent/duration/Duration.scala +++ b/src/library/scala/concurrent/duration/Duration.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/duration/DurationConversions.scala b/src/library/scala/concurrent/duration/DurationConversions.scala index b8f29f2f5d8b..30036331be73 100644 --- a/src/library/scala/concurrent/duration/DurationConversions.scala +++ b/src/library/scala/concurrent/duration/DurationConversions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/duration/package.scala b/src/library/scala/concurrent/duration/package.scala index 415af1c915a2..f81b8777f6d0 100644 --- a/src/library/scala/concurrent/duration/package.scala +++ b/src/library/scala/concurrent/duration/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index d662df8927a8..262a12b1b4b9 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/impl/FutureConvertersImpl.scala b/src/library/scala/concurrent/impl/FutureConvertersImpl.scala index 0980ade5a5a7..a9eed4cbb055 100644 --- a/src/library/scala/concurrent/impl/FutureConvertersImpl.scala +++ b/src/library/scala/concurrent/impl/FutureConvertersImpl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index 7024344c1184..89f1addb8aa8 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -215,6 +215,16 @@ private[concurrent] object Promise { override final def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit = dispatchOrAddCallbacks(get(), new Transformation[T, Unit](Xform_onComplete, func, executor)) + /** The same as [[onComplete]], but additionally returns a function which can be + * invoked to unregister the callback function. Removing a callback from a long-lived + * future can enable garbage collection of objects referenced by the closure. + */ + private[concurrent] final def onCompleteWithUnregister[U](func: Try[T] => U)(implicit executor: ExecutionContext): () => Unit = { + val t = new Transformation[T, Unit](Xform_onComplete, func, executor) + dispatchOrAddCallbacks(get(), t) + () => unregisterCallback(t) + } + override final def failed: Future[Throwable] = if (!get().isInstanceOf[Success[_]]) super.failed else Future.failedFailureFuture // Cached instance in case of already known success @@ -319,6 +329,15 @@ private[concurrent] object Promise { p.dispatchOrAddCallbacks(p.get(), callbacks) } + @tailrec private def unregisterCallback(t: Transformation[_, _]): Unit = { + val state = get() + if (state eq t) { + if (!compareAndSet(state, Noop)) unregisterCallback(t) + } else if (state.isInstanceOf[ManyCallbacks[_]]) { + if (!compareAndSet(state, removeCallback(state.asInstanceOf[ManyCallbacks[T]], t))) unregisterCallback(t) + } + } + // IMPORTANT: Noop should never be passed in here, neither as left OR as right @tailrec private[this] final def concatCallbacks(left: Callbacks[T], right: Callbacks[T]): Callbacks[T] = if (left.isInstanceOf[Transformation[T,_]]) new ManyCallbacks[T](left.asInstanceOf[Transformation[T,_]], right) @@ -327,6 +346,20 @@ private[concurrent] object Promise { concatCallbacks(m.rest, new ManyCallbacks(m.first, right)) } + @tailrec private[this] final def removeCallback(cs: Callbacks[T], t: Transformation[_, _], result: Callbacks[T] = null): AnyRef = + if (cs eq t) { + if (result == null) Noop + else result + } + else if (cs.isInstanceOf[ManyCallbacks[_]]) { + val m = cs.asInstanceOf[ManyCallbacks[T]] + if (m.first eq t) { + if (result == null) m.rest + else concatCallbacks(m.rest, result) + } + else removeCallback(m.rest, t, if (result == null) m.first else new ManyCallbacks(m.first, result)) + } else cs + // IMPORTANT: Noop should not be passed in here, `callbacks` cannot be null @tailrec private[this] final def submitWithValue(callbacks: Callbacks[T], resolved: Try[T]): Unit = @@ -489,7 +522,7 @@ private[concurrent] object Promise { if (v.isInstanceOf[Failure[F]]) { val f = fun.asInstanceOf[PartialFunction[Throwable, Future[T]]].applyOrElse(v.asInstanceOf[Failure[F]].exception, Future.recoverWithFailed) if (f ne Future.recoverWithFailedMarker) { - if (f.isInstanceOf[DefaultPromise[T]]) f.asInstanceOf[DefaultPromise[T]].linkRootOf(this, null) else completeWith(f.asInstanceOf[Future[T]]) + if (f.isInstanceOf[DefaultPromise[_]]) f.asInstanceOf[DefaultPromise[T]].linkRootOf(this, null) else completeWith(f.asInstanceOf[Future[T]]) null } else v } else v diff --git a/src/library/scala/concurrent/package.scala b/src/library/scala/concurrent/package.scala index 652551eb988b..d648a1c90a15 100644 --- a/src/library/scala/concurrent/package.scala +++ b/src/library/scala/concurrent/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/deprecated.scala b/src/library/scala/deprecated.scala index 84e97be55f59..bb1ded88437c 100644 --- a/src/library/scala/deprecated.scala +++ b/src/library/scala/deprecated.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/deprecatedInheritance.scala b/src/library/scala/deprecatedInheritance.scala index 21e3932d97df..f95b3ef100a0 100644 --- a/src/library/scala/deprecatedInheritance.scala +++ b/src/library/scala/deprecatedInheritance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/deprecatedName.scala b/src/library/scala/deprecatedName.scala index 2669ac25ac77..1a8341b8d498 100644 --- a/src/library/scala/deprecatedName.scala +++ b/src/library/scala/deprecatedName.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/deprecatedOverriding.scala b/src/library/scala/deprecatedOverriding.scala index b6c75819785a..0268bee15a10 100644 --- a/src/library/scala/deprecatedOverriding.scala +++ b/src/library/scala/deprecatedOverriding.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/inline.scala b/src/library/scala/inline.scala index 7bb733f85d21..d7d7b55d8d3c 100644 --- a/src/library/scala/inline.scala +++ b/src/library/scala/inline.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/io/AnsiColor.scala b/src/library/scala/io/AnsiColor.scala index 906f1098d0ce..ca27dac45a6b 100644 --- a/src/library/scala/io/AnsiColor.scala +++ b/src/library/scala/io/AnsiColor.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/io/BufferedSource.scala b/src/library/scala/io/BufferedSource.scala index edb963664e36..2369b528f8f7 100644 --- a/src/library/scala/io/BufferedSource.scala +++ b/src/library/scala/io/BufferedSource.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala index 8c4ab5a8baff..a6eeab50b299 100644 --- a/src/library/scala/io/Codec.scala +++ b/src/library/scala/io/Codec.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/io/Position.scala b/src/library/scala/io/Position.scala index 719976c10ded..5a0a4aecdc31 100644 --- a/src/library/scala/io/Position.scala +++ b/src/library/scala/io/Position.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala index 02f8d50dbf3c..360c9fe0cf6d 100644 --- a/src/library/scala/io/Source.scala +++ b/src/library/scala/io/Source.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/io/StdIn.scala b/src/library/scala/io/StdIn.scala index 6324da5c2ede..a39f99b4d689 100644 --- a/src/library/scala/io/StdIn.scala +++ b/src/library/scala/io/StdIn.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/Accumulator.scala b/src/library/scala/jdk/Accumulator.scala index ca1b0215bcd8..0398a204b9a0 100644 --- a/src/library/scala/jdk/Accumulator.scala +++ b/src/library/scala/jdk/Accumulator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/AnyAccumulator.scala b/src/library/scala/jdk/AnyAccumulator.scala index 3aa2c8053d1f..fa952105fcca 100644 --- a/src/library/scala/jdk/AnyAccumulator.scala +++ b/src/library/scala/jdk/AnyAccumulator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/CollectionConverters.scala b/src/library/scala/jdk/CollectionConverters.scala index 70d54c9d7210..9cbe1c5fea43 100644 --- a/src/library/scala/jdk/CollectionConverters.scala +++ b/src/library/scala/jdk/CollectionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -28,7 +28,7 @@ import scala.collection.convert.{AsJavaExtensions, AsScalaExtensions} * }}} * * The conversions return adapters for the corresponding API, i.e., the collections are wrapped, - * not converted. Changes to the original collection are reflected in the view, and vice versa: + * not copied. Changes to the original collection are reflected in the view, and vice versa: * * {{{ * scala> import scala.jdk.CollectionConverters._ diff --git a/src/library/scala/jdk/DoubleAccumulator.scala b/src/library/scala/jdk/DoubleAccumulator.scala index db6c0f692758..dfdb2feba9ea 100644 --- a/src/library/scala/jdk/DoubleAccumulator.scala +++ b/src/library/scala/jdk/DoubleAccumulator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,6 +17,7 @@ import java.util.Spliterator import java.util.function.{Consumer, DoubleConsumer} import java.{lang => jl} +import scala.annotation._ import scala.collection.Stepper.EfficientSplit import scala.collection.{AnyStepper, DoubleStepper, Factory, SeqFactory, Stepper, StepperShape, mutable} import scala.language.implicitConversions @@ -236,6 +237,7 @@ final class DoubleAccumulator } /** Copies the elements in this `DoubleAccumulator` into an `Array[Double]` */ + @nowarn // cat=lint-overload see toArray[B: ClassTag] def toArray: Array[Double] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) val a = new Array[Double](totalSize.toInt) diff --git a/src/library/scala/jdk/DurationConverters.scala b/src/library/scala/jdk/DurationConverters.scala index c3c7db3d6653..a98cd5b709d6 100644 --- a/src/library/scala/jdk/DurationConverters.scala +++ b/src/library/scala/jdk/DurationConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/FunctionConverters.scala b/src/library/scala/jdk/FunctionConverters.scala index 1c01fdd06d36..3c2d42564df0 100644 --- a/src/library/scala/jdk/FunctionConverters.scala +++ b/src/library/scala/jdk/FunctionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/FunctionExtensions.scala b/src/library/scala/jdk/FunctionExtensions.scala index 768ed587cfd0..e932609e7af5 100644 --- a/src/library/scala/jdk/FunctionExtensions.scala +++ b/src/library/scala/jdk/FunctionExtensions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/FunctionWrappers.scala b/src/library/scala/jdk/FunctionWrappers.scala index b6ae8259e82e..27153ffed820 100644 --- a/src/library/scala/jdk/FunctionWrappers.scala +++ b/src/library/scala/jdk/FunctionWrappers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/FutureConverters.scala b/src/library/scala/jdk/FutureConverters.scala index 7c7385c2c00b..9b9b6ad3c8b6 100644 --- a/src/library/scala/jdk/FutureConverters.scala +++ b/src/library/scala/jdk/FutureConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/IntAccumulator.scala b/src/library/scala/jdk/IntAccumulator.scala index 89f5b9e40cfc..9b7a904b36e3 100644 --- a/src/library/scala/jdk/IntAccumulator.scala +++ b/src/library/scala/jdk/IntAccumulator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,6 +17,7 @@ import java.util.Spliterator import java.util.function.{Consumer, IntConsumer} import java.{lang => jl} +import scala.annotation._ import scala.collection.Stepper.EfficientSplit import scala.collection.{AnyStepper, Factory, IntStepper, SeqFactory, Stepper, StepperShape, mutable} import scala.language.implicitConversions @@ -241,6 +242,7 @@ final class IntAccumulator } /** Copies the elements in this `IntAccumulator` into an `Array[Int]` */ + @nowarn // cat=lint-overload see toArray[B: ClassTag] def toArray: Array[Int] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) val a = new Array[Int](totalSize.toInt) diff --git a/src/library/scala/jdk/LongAccumulator.scala b/src/library/scala/jdk/LongAccumulator.scala index 5b6338dce013..38b868ae1111 100644 --- a/src/library/scala/jdk/LongAccumulator.scala +++ b/src/library/scala/jdk/LongAccumulator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,6 +17,7 @@ import java.util.Spliterator import java.util.function.{Consumer, LongConsumer} import java.{lang => jl} +import scala.annotation._ import scala.collection.Stepper.EfficientSplit import scala.collection.{AnyStepper, Factory, LongStepper, SeqFactory, Stepper, StepperShape, mutable} import scala.language.implicitConversions @@ -236,6 +237,7 @@ final class LongAccumulator } /** Copies the elements in this `LongAccumulator` into an `Array[Long]` */ + @nowarn // cat=lint-overload see toArray[B: ClassTag] def toArray: Array[Long] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) val a = new Array[Long](totalSize.toInt) diff --git a/src/library/scala/jdk/OptionConverters.scala b/src/library/scala/jdk/OptionConverters.scala index 033b78f4111e..5fbfef206394 100644 --- a/src/library/scala/jdk/OptionConverters.scala +++ b/src/library/scala/jdk/OptionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/OptionShape.scala b/src/library/scala/jdk/OptionShape.scala index c93d9f1ea51e..e56b3296e439 100644 --- a/src/library/scala/jdk/OptionShape.scala +++ b/src/library/scala/jdk/OptionShape.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/StreamConverters.scala b/src/library/scala/jdk/StreamConverters.scala index 11ae61d8032f..e3338bdba011 100644 --- a/src/library/scala/jdk/StreamConverters.scala +++ b/src/library/scala/jdk/StreamConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/javaapi/CollectionConverters.scala b/src/library/scala/jdk/javaapi/CollectionConverters.scala index b9338057e079..8bf1bb9e2a41 100644 --- a/src/library/scala/jdk/javaapi/CollectionConverters.scala +++ b/src/library/scala/jdk/javaapi/CollectionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -34,7 +34,7 @@ import scala.collection.convert.{AsJavaConverters, AsScalaConverters} * }}} * * The conversions return adapters for the corresponding API, i.e., the collections are wrapped, - * not converted. Changes to the original collection are reflected in the view, and vice versa. + * not copied. Changes to the original collection are reflected in the view, and vice versa. * * The following conversions are supported via `asScala` and `asJava`: * diff --git a/src/library/scala/jdk/javaapi/DurationConverters.scala b/src/library/scala/jdk/javaapi/DurationConverters.scala index f99c9b3c4c09..00285a11c41a 100644 --- a/src/library/scala/jdk/javaapi/DurationConverters.scala +++ b/src/library/scala/jdk/javaapi/DurationConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/javaapi/FunctionConverters.scala b/src/library/scala/jdk/javaapi/FunctionConverters.scala index a76dbbdbfe7c..22c9769bbf42 100644 --- a/src/library/scala/jdk/javaapi/FunctionConverters.scala +++ b/src/library/scala/jdk/javaapi/FunctionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/javaapi/FutureConverters.scala b/src/library/scala/jdk/javaapi/FutureConverters.scala index 62a8d12858b5..d28a8da8a92e 100644 --- a/src/library/scala/jdk/javaapi/FutureConverters.scala +++ b/src/library/scala/jdk/javaapi/FutureConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/javaapi/OptionConverters.scala b/src/library/scala/jdk/javaapi/OptionConverters.scala index a514024f8a5a..27ae7b4e6060 100644 --- a/src/library/scala/jdk/javaapi/OptionConverters.scala +++ b/src/library/scala/jdk/javaapi/OptionConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/javaapi/StreamConverters.scala b/src/library/scala/jdk/javaapi/StreamConverters.scala index 5f11ce14a700..d5adeb84ab71 100644 --- a/src/library/scala/jdk/javaapi/StreamConverters.scala +++ b/src/library/scala/jdk/javaapi/StreamConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/jdk/package.scala b/src/library/scala/jdk/package.scala index 2571d2b18ef5..386a6886cefd 100644 --- a/src/library/scala/jdk/package.scala +++ b/src/library/scala/jdk/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala index 13b5f57fb3fc..d0359b8ac55f 100644 --- a/src/library/scala/language.scala +++ b/src/library/scala/language.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/languageFeature.scala b/src/library/scala/languageFeature.scala index 5d80e7c406d9..236774c990ba 100644 --- a/src/library/scala/languageFeature.scala +++ b/src/library/scala/languageFeature.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index ff54ea15abf8..e70cdbab41e4 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index a69f6ea9d301..9a17ee02a51a 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -379,7 +379,7 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo else if (_long < 0) BigInt(-1) else BigInt(0) // for _long >= 0 } else BigInt(this.bigInteger.shiftRight(n)) - + /** Bitwise and of BigInts */ def &(that: BigInt): BigInt = @@ -501,7 +501,7 @@ final class BigInt private (private var _bigInteger: BigInteger, private val _lo (_long & (1L << n)) != 0 else _long < 0 // give the sign bit - } else _bigInteger.testBit(n) + } else this.bigInteger.testBit(n) /** Returns a BigInt whose value is equivalent to this BigInt with the designated bit set. */ diff --git a/src/library/scala/math/Equiv.scala b/src/library/scala/math/Equiv.scala index f615963f1f04..b5d01b362901 100644 --- a/src/library/scala/math/Equiv.scala +++ b/src/library/scala/math/Equiv.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/Fractional.scala b/src/library/scala/math/Fractional.scala index 8674dc6a0628..2066cc65d8ac 100644 --- a/src/library/scala/math/Fractional.scala +++ b/src/library/scala/math/Fractional.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/Integral.scala b/src/library/scala/math/Integral.scala index fababfa881a8..d5dd189d64fe 100644 --- a/src/library/scala/math/Integral.scala +++ b/src/library/scala/math/Integral.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala index 9dca0e4f0199..84028f13f833 100644 --- a/src/library/scala/math/Numeric.scala +++ b/src/library/scala/math/Numeric.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala index 8daf235819f3..fe3ed90453e0 100644 --- a/src/library/scala/math/Ordered.scala +++ b/src/library/scala/math/Ordered.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index 8ff5a72d6c27..5a34f1fe91a9 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -69,7 +69,6 @@ import scala.annotation.migration * * @see [[scala.math.Ordered]], [[scala.util.Sorting]], [[scala.math.Ordering.Implicits]] */ -@annotation.implicitNotFound(msg = "No implicit Ordering defined for ${T}.") trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable { outer => @@ -383,8 +382,15 @@ object Ordering extends LowPriorityOrderingImplicits { /** `Ordering`s for `Float`s. * - * The behavior of the comparison operations provided by the default (implicit) - * ordering on `Float` changed in 2.10.0 and 2.13.0. + * The default extends `Ordering.Float.TotalOrdering`. + * + * `Ordering.Float.TotalOrdering` uses the `java.lang.Float.compare` semantics for all operations. + * Scala also provides the `Ordering.Float.IeeeOrdering` semantics. Which uses the IEEE 754 semantics + * for float ordering. + * + * Historically: `IeeeOrdering` was used in Scala from 2.10.x through 2.12.x. This changed in 2.13.0 + * to `TotalOrdering`. + * * Prior to Scala 2.10.0, the `Ordering` instance used semantics * consistent with `java.lang.Float.compare`. * @@ -395,11 +401,6 @@ object Ordering extends LowPriorityOrderingImplicits { * `false` thus `0.0F < Float.NaN`, `0.0F > Float.NaN`, and * `Float.NaN == Float.NaN` all yield `false`, analogous `None` in `flatMap`. * - * Recognizing the limitation of the IEEE 754 semantics in terms of ordering, - * Scala 2.13.0 created two instances: `Ordering.Float.IeeeOrdering`, which retains - * the IEEE 754 semantics from Scala 2.12.x, and `Ordering.Float.TotalOrdering`, - * which brings back the `java.lang.Float.compare` semantics for all operations. - * The default extends `TotalOrdering`. * * {{{ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).sorted // List(-Infinity, 0.0, 1.0, NaN) diff --git a/src/library/scala/math/PartialOrdering.scala b/src/library/scala/math/PartialOrdering.scala index 580fec46b82a..e8ea9d355344 100644 --- a/src/library/scala/math/PartialOrdering.scala +++ b/src/library/scala/math/PartialOrdering.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/PartiallyOrdered.scala b/src/library/scala/math/PartiallyOrdered.scala index a937e7316c27..b955879ae0f1 100644 --- a/src/library/scala/math/PartiallyOrdered.scala +++ b/src/library/scala/math/PartiallyOrdered.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/ScalaNumber.java b/src/library/scala/math/ScalaNumber.java index 5a6a8a7c65f5..5ed76ec3fb22 100644 --- a/src/library/scala/math/ScalaNumber.java +++ b/src/library/scala/math/ScalaNumber.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/ScalaNumericConversions.scala b/src/library/scala/math/ScalaNumericConversions.scala index b3e6ca17ba03..a3fa90c98c9d 100644 --- a/src/library/scala/math/ScalaNumericConversions.scala +++ b/src/library/scala/math/ScalaNumericConversions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala index 13f24c318f8e..dbfde894aa0c 100644 --- a/src/library/scala/math/package.scala +++ b/src/library/scala/math/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/native.scala b/src/library/scala/native.scala index c81498f284c5..6a453d1809d1 100644 --- a/src/library/scala/native.scala +++ b/src/library/scala/native.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/noinline.scala b/src/library/scala/noinline.scala index b74dc81c072a..eede8d5051f2 100644 --- a/src/library/scala/noinline.scala +++ b/src/library/scala/noinline.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index f256c6975b87..f84dcfd85a73 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ref/PhantomReference.scala b/src/library/scala/ref/PhantomReference.scala index d9961c1c0097..0790f539d03d 100644 --- a/src/library/scala/ref/PhantomReference.scala +++ b/src/library/scala/ref/PhantomReference.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ref/Reference.scala b/src/library/scala/ref/Reference.scala index ecb2723c8c1b..02e673fa4184 100644 --- a/src/library/scala/ref/Reference.scala +++ b/src/library/scala/ref/Reference.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ref/ReferenceQueue.scala b/src/library/scala/ref/ReferenceQueue.scala index e0f8710593cd..70743708c732 100644 --- a/src/library/scala/ref/ReferenceQueue.scala +++ b/src/library/scala/ref/ReferenceQueue.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ref/ReferenceWrapper.scala b/src/library/scala/ref/ReferenceWrapper.scala index bb41fb3211eb..4e681ed18570 100644 --- a/src/library/scala/ref/ReferenceWrapper.scala +++ b/src/library/scala/ref/ReferenceWrapper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ref/SoftReference.scala b/src/library/scala/ref/SoftReference.scala index e6b84b721c8d..859eef5e7fef 100644 --- a/src/library/scala/ref/SoftReference.scala +++ b/src/library/scala/ref/SoftReference.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/ref/WeakReference.scala b/src/library/scala/ref/WeakReference.scala index c31714784c25..5ca06063590b 100644 --- a/src/library/scala/ref/WeakReference.scala +++ b/src/library/scala/ref/WeakReference.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala index f62787f28711..cc8d0a457c2a 100644 --- a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala +++ b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 5226bb5577a8..5ebd3f1506e1 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index ace40b5d3206..9f382fdd800e 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala index 2072b792004e..4980ed5bd6b4 100644 --- a/src/library/scala/reflect/NameTransformer.scala +++ b/src/library/scala/reflect/NameTransformer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala index 838bb986a450..819ffede46d3 100644 --- a/src/library/scala/reflect/NoManifest.scala +++ b/src/library/scala/reflect/NoManifest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala index 1c73efddd68d..f3b3c3117236 100644 --- a/src/library/scala/reflect/OptManifest.scala +++ b/src/library/scala/reflect/OptManifest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/ScalaLongSignature.java b/src/library/scala/reflect/ScalaLongSignature.java index f749e33bf3fa..29a77dc2f352 100644 --- a/src/library/scala/reflect/ScalaLongSignature.java +++ b/src/library/scala/reflect/ScalaLongSignature.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/ScalaSignature.java b/src/library/scala/reflect/ScalaSignature.java index 99d8c0387b62..dbd5a46bfd10 100644 --- a/src/library/scala/reflect/ScalaSignature.java +++ b/src/library/scala/reflect/ScalaSignature.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/macros/internal/macroImpl.scala b/src/library/scala/reflect/macros/internal/macroImpl.scala index bcd408d56ea8..c26426a079f2 100644 --- a/src/library/scala/reflect/macros/internal/macroImpl.scala +++ b/src/library/scala/reflect/macros/internal/macroImpl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 67551c7f6e80..caf79866c71e 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction0.scala b/src/library/scala/runtime/AbstractFunction0.scala index 1d0658dd13ac..c322efcd6281 100644 --- a/src/library/scala/runtime/AbstractFunction0.scala +++ b/src/library/scala/runtime/AbstractFunction0.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction1.scala b/src/library/scala/runtime/AbstractFunction1.scala index a3e505203a08..49977d8a1393 100644 --- a/src/library/scala/runtime/AbstractFunction1.scala +++ b/src/library/scala/runtime/AbstractFunction1.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction10.scala b/src/library/scala/runtime/AbstractFunction10.scala index 0c4a08cbfac7..121c3cc0d53b 100644 --- a/src/library/scala/runtime/AbstractFunction10.scala +++ b/src/library/scala/runtime/AbstractFunction10.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction11.scala b/src/library/scala/runtime/AbstractFunction11.scala index 26dc92a984d8..c4321c10f142 100644 --- a/src/library/scala/runtime/AbstractFunction11.scala +++ b/src/library/scala/runtime/AbstractFunction11.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction12.scala b/src/library/scala/runtime/AbstractFunction12.scala index f52587200984..3f6d666f9c42 100644 --- a/src/library/scala/runtime/AbstractFunction12.scala +++ b/src/library/scala/runtime/AbstractFunction12.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction13.scala b/src/library/scala/runtime/AbstractFunction13.scala index f5280e525973..264de0f87296 100644 --- a/src/library/scala/runtime/AbstractFunction13.scala +++ b/src/library/scala/runtime/AbstractFunction13.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction14.scala b/src/library/scala/runtime/AbstractFunction14.scala index af6784cffaf2..1e92d1e04bae 100644 --- a/src/library/scala/runtime/AbstractFunction14.scala +++ b/src/library/scala/runtime/AbstractFunction14.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction15.scala b/src/library/scala/runtime/AbstractFunction15.scala index aac162fac06a..ed9b6b187e39 100644 --- a/src/library/scala/runtime/AbstractFunction15.scala +++ b/src/library/scala/runtime/AbstractFunction15.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction16.scala b/src/library/scala/runtime/AbstractFunction16.scala index 699842586255..839efed863b6 100644 --- a/src/library/scala/runtime/AbstractFunction16.scala +++ b/src/library/scala/runtime/AbstractFunction16.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction17.scala b/src/library/scala/runtime/AbstractFunction17.scala index 2531a748d885..ee91b466ea5b 100644 --- a/src/library/scala/runtime/AbstractFunction17.scala +++ b/src/library/scala/runtime/AbstractFunction17.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction18.scala b/src/library/scala/runtime/AbstractFunction18.scala index 14d0dd72046a..83aaf6b10c44 100644 --- a/src/library/scala/runtime/AbstractFunction18.scala +++ b/src/library/scala/runtime/AbstractFunction18.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction19.scala b/src/library/scala/runtime/AbstractFunction19.scala index 13d633113954..93741656a585 100644 --- a/src/library/scala/runtime/AbstractFunction19.scala +++ b/src/library/scala/runtime/AbstractFunction19.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction2.scala b/src/library/scala/runtime/AbstractFunction2.scala index 56ba89085b53..7c8d1628e545 100644 --- a/src/library/scala/runtime/AbstractFunction2.scala +++ b/src/library/scala/runtime/AbstractFunction2.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction20.scala b/src/library/scala/runtime/AbstractFunction20.scala index 4debd7473893..b2858b27c125 100644 --- a/src/library/scala/runtime/AbstractFunction20.scala +++ b/src/library/scala/runtime/AbstractFunction20.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction21.scala b/src/library/scala/runtime/AbstractFunction21.scala index 523a42f4ebea..e36e6b043959 100644 --- a/src/library/scala/runtime/AbstractFunction21.scala +++ b/src/library/scala/runtime/AbstractFunction21.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction22.scala b/src/library/scala/runtime/AbstractFunction22.scala index 7c77f05e7f03..f9cf63a9542d 100644 --- a/src/library/scala/runtime/AbstractFunction22.scala +++ b/src/library/scala/runtime/AbstractFunction22.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction3.scala b/src/library/scala/runtime/AbstractFunction3.scala index 829125342d3c..fbeb3e7b1cf8 100644 --- a/src/library/scala/runtime/AbstractFunction3.scala +++ b/src/library/scala/runtime/AbstractFunction3.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction4.scala b/src/library/scala/runtime/AbstractFunction4.scala index 6f479f3395ae..9a91280eea52 100644 --- a/src/library/scala/runtime/AbstractFunction4.scala +++ b/src/library/scala/runtime/AbstractFunction4.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction5.scala b/src/library/scala/runtime/AbstractFunction5.scala index 50ad931bdd77..a7880cdb0a14 100644 --- a/src/library/scala/runtime/AbstractFunction5.scala +++ b/src/library/scala/runtime/AbstractFunction5.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction6.scala b/src/library/scala/runtime/AbstractFunction6.scala index e60229bb03df..0a8c4eeacc70 100644 --- a/src/library/scala/runtime/AbstractFunction6.scala +++ b/src/library/scala/runtime/AbstractFunction6.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction7.scala b/src/library/scala/runtime/AbstractFunction7.scala index 1f6eae1291fa..d0f18b0dcbd4 100644 --- a/src/library/scala/runtime/AbstractFunction7.scala +++ b/src/library/scala/runtime/AbstractFunction7.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction8.scala b/src/library/scala/runtime/AbstractFunction8.scala index 06677c3e3923..4f1a528a4ed9 100644 --- a/src/library/scala/runtime/AbstractFunction8.scala +++ b/src/library/scala/runtime/AbstractFunction8.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractFunction9.scala b/src/library/scala/runtime/AbstractFunction9.scala index 863e73f18177..f4ebb395bd5a 100644 --- a/src/library/scala/runtime/AbstractFunction9.scala +++ b/src/library/scala/runtime/AbstractFunction9.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala index bba4a67ad348..f4e8ae1b7818 100644 --- a/src/library/scala/runtime/AbstractPartialFunction.scala +++ b/src/library/scala/runtime/AbstractPartialFunction.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ArrayCharSequence.scala b/src/library/scala/runtime/ArrayCharSequence.scala index 1bee18d7b392..971b0ac24c0d 100644 --- a/src/library/scala/runtime/ArrayCharSequence.scala +++ b/src/library/scala/runtime/ArrayCharSequence.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/BooleanRef.java b/src/library/scala/runtime/BooleanRef.java index 25bf399127ec..2c43fd719366 100644 --- a/src/library/scala/runtime/BooleanRef.java +++ b/src/library/scala/runtime/BooleanRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/BoxedUnit.java b/src/library/scala/runtime/BoxedUnit.java index c190763f4db2..aaa986f87f1a 100644 --- a/src/library/scala/runtime/BoxedUnit.java +++ b/src/library/scala/runtime/BoxedUnit.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index bfcb1f90c7fd..3ddc2516fbb9 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ByteRef.java b/src/library/scala/runtime/ByteRef.java index d66e33467f6a..4630440fd7a7 100644 --- a/src/library/scala/runtime/ByteRef.java +++ b/src/library/scala/runtime/ByteRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/CharRef.java b/src/library/scala/runtime/CharRef.java index b2d6aa0288e1..05e8fa55c982 100644 --- a/src/library/scala/runtime/CharRef.java +++ b/src/library/scala/runtime/CharRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ClassValueCompat.scala b/src/library/scala/runtime/ClassValueCompat.scala index 908c36c6ef3b..09a619f7a5f5 100644 --- a/src/library/scala/runtime/ClassValueCompat.scala +++ b/src/library/scala/runtime/ClassValueCompat.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/DoubleRef.java b/src/library/scala/runtime/DoubleRef.java index bfc47ff84858..52b40cde396e 100644 --- a/src/library/scala/runtime/DoubleRef.java +++ b/src/library/scala/runtime/DoubleRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/FloatRef.java b/src/library/scala/runtime/FloatRef.java index 0d2151d1869b..d28d62a0ccc2 100644 --- a/src/library/scala/runtime/FloatRef.java +++ b/src/library/scala/runtime/FloatRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/IntRef.java b/src/library/scala/runtime/IntRef.java index 287041442ada..d456c3a750b3 100644 --- a/src/library/scala/runtime/IntRef.java +++ b/src/library/scala/runtime/IntRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/LambdaDeserialize.scala b/src/library/scala/runtime/LambdaDeserialize.scala index 95e0f0060f3c..b4270d63e643 100644 --- a/src/library/scala/runtime/LambdaDeserialize.scala +++ b/src/library/scala/runtime/LambdaDeserialize.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/LambdaDeserializer.scala b/src/library/scala/runtime/LambdaDeserializer.scala index a1ea4ef5e304..76fc5d778bec 100644 --- a/src/library/scala/runtime/LambdaDeserializer.scala +++ b/src/library/scala/runtime/LambdaDeserializer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/LazyRef.scala b/src/library/scala/runtime/LazyRef.scala index 2c9b816f45b7..ee0364cfab94 100644 --- a/src/library/scala/runtime/LazyRef.scala +++ b/src/library/scala/runtime/LazyRef.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/LongRef.java b/src/library/scala/runtime/LongRef.java index 130bf9cf0ab9..9e189af0ef2b 100644 --- a/src/library/scala/runtime/LongRef.java +++ b/src/library/scala/runtime/LongRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/MethodCache.scala b/src/library/scala/runtime/MethodCache.scala index 9406efe3c5bb..2aa41c9e352a 100644 --- a/src/library/scala/runtime/MethodCache.scala +++ b/src/library/scala/runtime/MethodCache.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/MethodHandleConstants.java b/src/library/scala/runtime/MethodHandleConstants.java index 47117dff9361..16773431f86a 100644 --- a/src/library/scala/runtime/MethodHandleConstants.java +++ b/src/library/scala/runtime/MethodHandleConstants.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ModuleSerializationProxy.scala b/src/library/scala/runtime/ModuleSerializationProxy.scala index e82e6fed661a..ad12bd17f7bc 100644 --- a/src/library/scala/runtime/ModuleSerializationProxy.scala +++ b/src/library/scala/runtime/ModuleSerializationProxy.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -18,7 +18,7 @@ import java.security.PrivilegedExceptionAction import scala.annotation.nowarn private[runtime] object ModuleSerializationProxy { - private val instances = new ClassValueCompat[Object] { + private val instances: ClassValueCompat[Object] = new ClassValueCompat[Object] { @nowarn("cat=deprecation") // AccessController is deprecated on JDK 17 def getModule(cls: Class[_]): Object = java.security.AccessController.doPrivileged( diff --git a/src/library/scala/runtime/NonLocalReturnControl.scala b/src/library/scala/runtime/NonLocalReturnControl.scala index 6097a9e18781..8abd48501e3c 100644 --- a/src/library/scala/runtime/NonLocalReturnControl.scala +++ b/src/library/scala/runtime/NonLocalReturnControl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/Nothing$.scala b/src/library/scala/runtime/Nothing$.scala index 314ffc2e6240..cb098a5507da 100644 --- a/src/library/scala/runtime/Nothing$.scala +++ b/src/library/scala/runtime/Nothing$.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/Null$.scala b/src/library/scala/runtime/Null$.scala index a56f4c2df8b2..d279f861e94a 100644 --- a/src/library/scala/runtime/Null$.scala +++ b/src/library/scala/runtime/Null$.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ObjectRef.java b/src/library/scala/runtime/ObjectRef.java index eae5a7679aeb..04545449e9a1 100644 --- a/src/library/scala/runtime/ObjectRef.java +++ b/src/library/scala/runtime/ObjectRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/PStatics.scala b/src/library/scala/runtime/PStatics.scala index a50e4773d48b..9196e21e75be 100644 --- a/src/library/scala/runtime/PStatics.scala +++ b/src/library/scala/runtime/PStatics.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichBoolean.scala b/src/library/scala/runtime/RichBoolean.scala index 91e9d1a37f49..8b1c1525cedf 100644 --- a/src/library/scala/runtime/RichBoolean.scala +++ b/src/library/scala/runtime/RichBoolean.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichByte.scala b/src/library/scala/runtime/RichByte.scala index 405948b60ab8..6060d9b75a79 100644 --- a/src/library/scala/runtime/RichByte.scala +++ b/src/library/scala/runtime/RichByte.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichChar.scala b/src/library/scala/runtime/RichChar.scala index f50127a59579..2bdb80be96f4 100644 --- a/src/library/scala/runtime/RichChar.scala +++ b/src/library/scala/runtime/RichChar.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala index 72778674d293..b453e69deee0 100644 --- a/src/library/scala/runtime/RichDouble.scala +++ b/src/library/scala/runtime/RichDouble.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichFloat.scala b/src/library/scala/runtime/RichFloat.scala index 962984a737b3..c6570ab10615 100644 --- a/src/library/scala/runtime/RichFloat.scala +++ b/src/library/scala/runtime/RichFloat.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index 67a58ad62d58..7499e5078006 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala index 95c8801d2031..1f5bc5d0da4b 100644 --- a/src/library/scala/runtime/RichLong.scala +++ b/src/library/scala/runtime/RichLong.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/RichShort.scala b/src/library/scala/runtime/RichShort.scala index 56213a031490..1f4ebfaf0b1a 100644 --- a/src/library/scala/runtime/RichShort.scala +++ b/src/library/scala/runtime/RichShort.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ScalaNumberProxy.scala b/src/library/scala/runtime/ScalaNumberProxy.scala index cf3e21460ca7..a39c0e7854d3 100644 --- a/src/library/scala/runtime/ScalaNumberProxy.scala +++ b/src/library/scala/runtime/ScalaNumberProxy.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index dfdb2a535c7b..5c227b33c5ef 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -152,10 +152,16 @@ object ScalaRunTime { // More background at ticket #2318. def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) + // This is called by the synthetic case class `toString` method. + // It originally had a `CaseClass` parameter type which was changed to `Product`. def _toString(x: Product): String = x.productIterator.mkString(x.productPrefix + "(", ",", ")") - def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.productHash(x) + // This method is called by case classes compiled by older Scala 2.13 / Scala 3 versions, so it needs to stay. + // In newer versions, the synthetic case class `hashCode` has either the calculation inlined or calls + // `MurmurHash3.productHash`. + // There used to be an `_equals` method as well which was removed in 5e7e81ab2a. + def _hashCode(x: Product): Int = scala.util.hashing.MurmurHash3.caseClassHash(x) /** A helper for case classes. */ def typedProductIterator[T](x: Product): Iterator[T] = { @@ -274,22 +280,20 @@ object ScalaRunTime { case s => s + "\n" } - // Convert arrays to immutable.ArraySeq for use with Java varargs: - def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = - if (xs eq null) null - else ArraySeq.unsafeWrapArray(xs) - def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = { - if (xs eq null) null - else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq[T]] - else new ArraySeq.ofRef[T](xs) - } - def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = if (xs ne null) new ArraySeq.ofInt(xs) else null - def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = if (xs ne null) new ArraySeq.ofDouble(xs) else null - def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = if (xs ne null) new ArraySeq.ofLong(xs) else null - def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = if (xs ne null) new ArraySeq.ofFloat(xs) else null - def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = if (xs ne null) new ArraySeq.ofChar(xs) else null - def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = if (xs ne null) new ArraySeq.ofByte(xs) else null - def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = if (xs ne null) new ArraySeq.ofShort(xs) else null - def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = if (xs ne null) new ArraySeq.ofBoolean(xs) else null - def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = if (xs ne null) new ArraySeq.ofUnit(xs) else null + // Convert arrays to immutable.ArraySeq for use with Scala varargs. + // By construction, calls to these methods always receive a fresh (and non-null), non-empty array. + // In cases where an empty array would appear, the compiler uses a direct reference to Nil instead. + // Synthetic Java varargs forwarders (@annotation.varargs or varargs bridges when overriding) may pass + // `null` to these methods; but returning `null` or `ArraySeq(null)` makes little difference in practice. + def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = ArraySeq.unsafeWrapArray(xs) + def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq[T] = new ArraySeq.ofRef[T](xs) + def wrapIntArray(xs: Array[Int]): ArraySeq[Int] = new ArraySeq.ofInt(xs) + def wrapDoubleArray(xs: Array[Double]): ArraySeq[Double] = new ArraySeq.ofDouble(xs) + def wrapLongArray(xs: Array[Long]): ArraySeq[Long] = new ArraySeq.ofLong(xs) + def wrapFloatArray(xs: Array[Float]): ArraySeq[Float] = new ArraySeq.ofFloat(xs) + def wrapCharArray(xs: Array[Char]): ArraySeq[Char] = new ArraySeq.ofChar(xs) + def wrapByteArray(xs: Array[Byte]): ArraySeq[Byte] = new ArraySeq.ofByte(xs) + def wrapShortArray(xs: Array[Short]): ArraySeq[Short] = new ArraySeq.ofShort(xs) + def wrapBooleanArray(xs: Array[Boolean]): ArraySeq[Boolean] = new ArraySeq.ofBoolean(xs) + def wrapUnitArray(xs: Array[Unit]): ArraySeq[Unit] = new ArraySeq.ofUnit(xs) } diff --git a/src/library/scala/runtime/ShortRef.java b/src/library/scala/runtime/ShortRef.java index 3ea87bf4e997..11fd2aece720 100644 --- a/src/library/scala/runtime/ShortRef.java +++ b/src/library/scala/runtime/ShortRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/Static.java b/src/library/scala/runtime/Static.java index 4bb78b24e18f..1971fe3b463e 100644 --- a/src/library/scala/runtime/Static.java +++ b/src/library/scala/runtime/Static.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/Statics.java b/src/library/scala/runtime/Statics.java index 886d000592ef..34dc1818065a 100644 --- a/src/library/scala/runtime/Statics.java +++ b/src/library/scala/runtime/Statics.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/StructuralCallSite.scala b/src/library/scala/runtime/StructuralCallSite.scala index b7f93656ae53..8e245e6c99db 100644 --- a/src/library/scala/runtime/StructuralCallSite.scala +++ b/src/library/scala/runtime/StructuralCallSite.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/SymbolLiteral.java b/src/library/scala/runtime/SymbolLiteral.java index 560fef53333c..67f59b15fbe2 100644 --- a/src/library/scala/runtime/SymbolLiteral.java +++ b/src/library/scala/runtime/SymbolLiteral.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala index d0e5058f426c..e49bf9e1aba6 100644 --- a/src/library/scala/runtime/Tuple2Zipped.scala +++ b/src/library/scala/runtime/Tuple2Zipped.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/Tuple3Zipped.scala b/src/library/scala/runtime/Tuple3Zipped.scala index 581ada8c4f1c..b1e8763f9891 100644 --- a/src/library/scala/runtime/Tuple3Zipped.scala +++ b/src/library/scala/runtime/Tuple3Zipped.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileBooleanRef.java b/src/library/scala/runtime/VolatileBooleanRef.java index 64105e8bfbac..0436cf5ee882 100644 --- a/src/library/scala/runtime/VolatileBooleanRef.java +++ b/src/library/scala/runtime/VolatileBooleanRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileByteRef.java b/src/library/scala/runtime/VolatileByteRef.java index de4a43b774f4..23ea7ce3d32e 100644 --- a/src/library/scala/runtime/VolatileByteRef.java +++ b/src/library/scala/runtime/VolatileByteRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileCharRef.java b/src/library/scala/runtime/VolatileCharRef.java index a27220012bec..b8d11584556a 100644 --- a/src/library/scala/runtime/VolatileCharRef.java +++ b/src/library/scala/runtime/VolatileCharRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileDoubleRef.java b/src/library/scala/runtime/VolatileDoubleRef.java index a602063c0ed0..809a27040540 100644 --- a/src/library/scala/runtime/VolatileDoubleRef.java +++ b/src/library/scala/runtime/VolatileDoubleRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileFloatRef.java b/src/library/scala/runtime/VolatileFloatRef.java index 44ac2ae03c40..954c7522c407 100644 --- a/src/library/scala/runtime/VolatileFloatRef.java +++ b/src/library/scala/runtime/VolatileFloatRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileIntRef.java b/src/library/scala/runtime/VolatileIntRef.java index 0bed1cf7a8f0..a3d2c33eab71 100644 --- a/src/library/scala/runtime/VolatileIntRef.java +++ b/src/library/scala/runtime/VolatileIntRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileLongRef.java b/src/library/scala/runtime/VolatileLongRef.java index a949066ab762..9e93e0b49e3b 100644 --- a/src/library/scala/runtime/VolatileLongRef.java +++ b/src/library/scala/runtime/VolatileLongRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileObjectRef.java b/src/library/scala/runtime/VolatileObjectRef.java index 4677b6cd0cdc..78aef1eaff26 100644 --- a/src/library/scala/runtime/VolatileObjectRef.java +++ b/src/library/scala/runtime/VolatileObjectRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/VolatileShortRef.java b/src/library/scala/runtime/VolatileShortRef.java index 519478377d23..87a0c12dd7ed 100644 --- a/src/library/scala/runtime/VolatileShortRef.java +++ b/src/library/scala/runtime/VolatileShortRef.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcB$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcB$sp.scala index 6fd838bd47df..cccb1a1a9430 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcB$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcB$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcC$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcC$sp.scala index debd30ee1009..c4e0ed82bd2f 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcC$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcC$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcD$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcD$sp.scala index dd53c1862d08..21b9e0152222 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcF$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcF$sp.scala index 055777707a69..b90637f54c60 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcI$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcI$sp.scala index d33297da67da..dd4e0738f985 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcJ$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcJ$sp.scala index 7265c07cdfd7..25d340fa9aae 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcS$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcS$sp.scala index 7df8606908ab..44d2a6ae934f 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcS$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcS$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcV$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcV$sp.scala index 7dbb004f0904..867d5cfe1052 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcV$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcV$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction0$mcZ$sp.scala b/src/library/scala/runtime/java8/JFunction0$mcZ$sp.scala index e0c65c96b10f..9f9389aa4445 100644 --- a/src/library/scala/runtime/java8/JFunction0$mcZ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction0$mcZ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcDD$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcDD$sp.scala index 5c103a840fec..98491234c57c 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcDF$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcDF$sp.scala index 0aee258afc85..702e7201ac7a 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcDF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcDF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcDI$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcDI$sp.scala index 1e58621a7cc1..3d1badf17393 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.scala index 78c529c32f61..ce0c27f8f279 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcFD$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcFD$sp.scala index 985098548dc9..eb436da193bf 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcFD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcFD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcFF$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcFF$sp.scala index 192c9de0ff3c..c7a253449554 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcFF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcFF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcFI$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcFI$sp.scala index 857e5ab8dca8..c77a5272ab66 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcFI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcFI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.scala index 2b20d4437222..c0ceaae6856a 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcID$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcID$sp.scala index 15b3a92886a7..742b46d23602 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcIF$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcIF$sp.scala index 9e5748a561d0..d5dc57ea6d49 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcIF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcIF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcII$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcII$sp.scala index b235ca392be9..1c84c49dccd9 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.scala index 0547799ccebb..298afef64518 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcJD$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcJD$sp.scala index de4eecf0c036..a315b0ca7e5c 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcJF$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcJF$sp.scala index 75152523792c..b810c01df2be 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcJF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcJF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcJI$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcJI$sp.scala index bdc3ff6ca797..11a0e2c9513b 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.scala index 1fdf7ff3b385..e6388f802798 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcVD$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcVD$sp.scala index 6bc518dccbe1..51b919af7bd6 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcVD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcVD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcVF$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcVF$sp.scala index 79c4f976355a..7c032068bd06 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcVF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcVF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcVI$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcVI$sp.scala index 5d140c64a156..06c78e4d4074 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcVI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcVI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.scala index d3f7fde7328a..ade57aaad9ea 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcZD$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcZD$sp.scala index b6fe80bdb684..070c0fed73ee 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcZD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcZD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcZF$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcZF$sp.scala index a5fed06dd575..af1cab6c44d4 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcZF$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcZF$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcZI$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcZI$sp.scala index 7d81d5978fc2..d9d5f5417b7b 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcZI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcZI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.scala b/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.scala index ca9e77c44e33..b1ac4f5fb0c1 100644 --- a/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.scala index 9e68a5eae609..a7dba65aa372 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.scala index f32aece646d8..f4dd19493eaa 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.scala index adbcede490f3..5ded95bd8910 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDID$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDID$sp.scala index 2efb23f52ab3..2aabd59d8c8e 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDII$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDII$sp.scala index 1c6526e31ba6..ad4467dbe07e 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.scala index c081bb93a998..4bc84d0b9a51 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.scala index 637a81715445..bc8f02173ad1 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.scala index 5eeed7108a7a..f139ad404716 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.scala index 2d483fbe0776..8d3b45df6e42 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.scala index 35b9a5cbda55..4381735c8973 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.scala index 193489e58242..e3e5b9a9026d 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.scala index e4d888f67ae5..1a26782f59dc 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFID$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFID$sp.scala index 293535d96c00..08f8ac2872d6 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFII$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFII$sp.scala index 1e57b321b0f1..8a482dfa722f 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.scala index 4d4e510bc0bd..a3f02eb64c01 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.scala index 7acb70e2a8fd..a78fed85f23d 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.scala index e8f0e4b90598..52dd6c11fe40 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.scala index 5d832704eb91..15e91de115c1 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.scala index b2ccf8d4400f..09f7188d5447 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.scala index f0ec009e1077..d53a99a61972 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.scala index bf59424fadff..eedd1db3df17 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIID$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIID$sp.scala index c2e5d331354f..067044482034 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIII$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIII$sp.scala index 1d6ca6e42a49..c868fad4e8f5 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.scala index 123627d228e6..c23e514092aa 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.scala index bd1d9bcaf8ee..48f58e3d3859 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.scala index efa695ac6052..c9ce9c1186d3 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.scala index a7f2b66b2452..7749b84ebefe 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.scala index 92837f610bac..4e2885c0c8b1 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.scala index 720790f13755..29e102ae3e01 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.scala index bb7e5c996c13..537d83a4e9d5 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJID$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJID$sp.scala index e06aeff156ef..c943f1bbcd1e 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJII$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJII$sp.scala index 80ae8ae7f9f0..387d6424c8d1 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.scala index ebf9eaebabf0..ef33074c5b5e 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.scala index bbbcf0ea463a..314930812281 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.scala index 22147082034a..87bc0de39256 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.scala index 6ab6607de49a..391582994fc6 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.scala index 2fffe4aefbc3..056fee1df387 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.scala index 4157b4ca5ce9..0683881a2923 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.scala index 6fab974de556..9a50555c1921 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVID$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVID$sp.scala index 690c9530bb0e..b0df076be14f 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVII$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVII$sp.scala index 2b266807a616..822fa89df106 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.scala index f2f23c833aa7..b922343162e6 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.scala index 0499474557d5..bb514d145017 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.scala index c84e91359719..079e48276a7d 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.scala index 901ec7e1be0d..4b80f04c9dba 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.scala index d831a492875e..0918660b802d 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.scala index 1a772fc91604..4514d78b8f3a 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.scala index ab943185a5b5..daebfd82f041 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZID$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZID$sp.scala index f7bde7dc12bb..c0a06d1c9373 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZID$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZID$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZII$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZII$sp.scala index 9c5a77b27c31..c49fea6a2543 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZII$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZII$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.scala index 2bf231610112..bbf003ebd17b 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.scala index 453f26225546..ab08030714e2 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.scala index eae68417cdfd..5f32af16f201 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.scala b/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.scala index 8ae76da6c337..b588644fb0c4 100644 --- a/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.scala +++ b/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/specialized.scala b/src/library/scala/specialized.scala index 856f9f196e6f..c099612e1370 100644 --- a/src/library/scala/specialized.scala +++ b/src/library/scala/specialized.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/BooleanProp.scala b/src/library/scala/sys/BooleanProp.scala index e87806a98ab8..70066c070c37 100644 --- a/src/library/scala/sys/BooleanProp.scala +++ b/src/library/scala/sys/BooleanProp.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/Prop.scala b/src/library/scala/sys/Prop.scala index 83d4d1689bbc..7645e4ac8993 100644 --- a/src/library/scala/sys/Prop.scala +++ b/src/library/scala/sys/Prop.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/PropImpl.scala b/src/library/scala/sys/PropImpl.scala index 3a73d3df6aa1..390c5c9c576d 100644 --- a/src/library/scala/sys/PropImpl.scala +++ b/src/library/scala/sys/PropImpl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/ShutdownHookThread.scala b/src/library/scala/sys/ShutdownHookThread.scala index 07bc852eea62..d7a8ae5bb3ca 100644 --- a/src/library/scala/sys/ShutdownHookThread.scala +++ b/src/library/scala/sys/ShutdownHookThread.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala index aa2f0bd5d06c..1f848a73358e 100644 --- a/src/library/scala/sys/SystemProperties.scala +++ b/src/library/scala/sys/SystemProperties.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/package.scala b/src/library/scala/sys/package.scala index f1dfd9799c73..122f19d12c3a 100644 --- a/src/library/scala/sys/package.scala +++ b/src/library/scala/sys/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/BasicIO.scala b/src/library/scala/sys/process/BasicIO.scala index 8492f4e965a7..a242fe312bbf 100644 --- a/src/library/scala/sys/process/BasicIO.scala +++ b/src/library/scala/sys/process/BasicIO.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/Parser.scala b/src/library/scala/sys/process/Parser.scala index 38b1e9f45f6a..e9a25a0f9366 100644 --- a/src/library/scala/sys/process/Parser.scala +++ b/src/library/scala/sys/process/Parser.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala index e3f75fa0f3be..531971125e6d 100644 --- a/src/library/scala/sys/process/Process.scala +++ b/src/library/scala/sys/process/Process.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala index 05f3489de844..bf1c1507707d 100644 --- a/src/library/scala/sys/process/ProcessBuilder.scala +++ b/src/library/scala/sys/process/ProcessBuilder.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/ProcessBuilderImpl.scala b/src/library/scala/sys/process/ProcessBuilderImpl.scala index f2bdc465be14..186ad134a218 100644 --- a/src/library/scala/sys/process/ProcessBuilderImpl.scala +++ b/src/library/scala/sys/process/ProcessBuilderImpl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/ProcessIO.scala b/src/library/scala/sys/process/ProcessIO.scala index 8e15a462e523..a4898d2c9b1e 100644 --- a/src/library/scala/sys/process/ProcessIO.scala +++ b/src/library/scala/sys/process/ProcessIO.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/ProcessImpl.scala b/src/library/scala/sys/process/ProcessImpl.scala index b1148b5ce51a..3ed0c5766412 100644 --- a/src/library/scala/sys/process/ProcessImpl.scala +++ b/src/library/scala/sys/process/ProcessImpl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/ProcessLogger.scala b/src/library/scala/sys/process/ProcessLogger.scala index cc21ef447d52..e048ca5c9446 100644 --- a/src/library/scala/sys/process/ProcessLogger.scala +++ b/src/library/scala/sys/process/ProcessLogger.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/sys/process/package.scala b/src/library/scala/sys/process/package.scala index 5d2dd56a2aa0..11e6640d8e21 100644 --- a/src/library/scala/sys/process/package.scala +++ b/src/library/scala/sys/process/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/throws.scala b/src/library/scala/throws.scala index a539eb79829b..d5391ce9242c 100644 --- a/src/library/scala/throws.scala +++ b/src/library/scala/throws.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/transient.scala b/src/library/scala/transient.scala index 2dd6c824243a..b40ce540547a 100644 --- a/src/library/scala/transient.scala +++ b/src/library/scala/transient.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/typeConstraints.scala b/src/library/scala/typeConstraints.scala index ea11c1a538e0..f17205e122cf 100644 --- a/src/library/scala/typeConstraints.scala +++ b/src/library/scala/typeConstraints.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/unchecked.scala b/src/library/scala/unchecked.scala index a6867102abf8..6927db7293e5 100644 --- a/src/library/scala/unchecked.scala +++ b/src/library/scala/unchecked.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/ChainingOps.scala b/src/library/scala/util/ChainingOps.scala index df41a533c024..4bfbdc82a833 100644 --- a/src/library/scala/util/ChainingOps.scala +++ b/src/library/scala/util/ChainingOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/DynamicVariable.scala b/src/library/scala/util/DynamicVariable.scala index 40d8b2014128..a2568c5a9c69 100644 --- a/src/library/scala/util/DynamicVariable.scala +++ b/src/library/scala/util/DynamicVariable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala index 98839d2320ca..0542decbcf46 100644 --- a/src/library/scala/util/Either.scala +++ b/src/library/scala/util/Either.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index 4fea468ee1bc..24dee49ae951 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -92,7 +92,7 @@ private[scala] trait PropertiesTrait { /** A verbose alternative to [[versionNumberString]]. */ val versionString = s"version ${scalaPropOrElse("version.number", "(unknown)")}" - val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2024, LAMP/EPFL and Lightbend, Inc.") + val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2025, LAMP/EPFL and Lightbend, Inc. dba Akka") /** This is the encoding to use reading in source files, overridden with -encoding. * Note that it uses "prop" i.e. looks in the scala jar, not the system properties. @@ -130,20 +130,30 @@ private[scala] trait PropertiesTrait { /* Some derived values. */ /** Returns `true` iff the underlying operating system is a version of Microsoft Windows. */ - def isWin = osName startsWith "Windows" + lazy val isWin = osName.startsWith("Windows") // See https://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-November/005148.html for // the reason why we don't follow developer.apple.com/library/mac/#technotes/tn2002/tn2110. /** Returns `true` iff the underlying operating system is a version of Apple Mac OSX. */ - def isMac = osName startsWith "Mac OS X" + lazy val isMac = osName.startsWith("Mac OS X") /** Returns `true` iff the underlying operating system is a Linux distribution. */ - def isLinux = osName startsWith "Linux" + lazy val isLinux = osName.startsWith("Linux") /* Some runtime values. */ - private[scala] def isAvian = javaVmName contains "Avian" + private[scala] lazy val isAvian = javaVmName.contains("Avian") private[scala] def coloredOutputEnabled: Boolean = propOrElse("scala.color", "auto") match { - case "auto" => System.console() != null && !isWin - case s => s == "" || "true".equalsIgnoreCase(s) + case "auto" => consoleIsTerminal + case s => "" == s || "true".equalsIgnoreCase(s) + } + + /** System.console.isTerminal, or just check for null console on JDK < 22 */ + private[scala] lazy val consoleIsTerminal: Boolean = { + import language.reflectiveCalls + val console = System.console + def isTerminal: Boolean = + try console.asInstanceOf[{ def isTerminal(): Boolean }].isTerminal() + catch { case _: NoSuchMethodException => false } + console != null && (!isJavaAtLeast("22") || isTerminal) } // This is looking for javac, tools.jar, etc. diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index b3a39e59e8be..84b44fcc91f5 100644 --- a/src/library/scala/util/Random.scala +++ b/src/library/scala/util/Random.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala index 4c7eea357353..7e2da2434f82 100644 --- a/src/library/scala/util/Sorting.scala +++ b/src/library/scala/util/Sorting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala index 567a53714836..c17d457c9fe5 100644 --- a/src/library/scala/util/Try.scala +++ b/src/library/scala/util/Try.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -217,7 +217,7 @@ object Try { val r1 = r Success(r1) } catch { - case NonFatal(e) => return Failure(e) + case NonFatal(e) => Failure(e) } } diff --git a/src/library/scala/util/Using.scala b/src/library/scala/util/Using.scala index 4817f9939d20..ebec5e7007ec 100644 --- a/src/library/scala/util/Using.scala +++ b/src/library/scala/util/Using.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -125,8 +125,8 @@ import scala.util.control.{ControlThrowable, NonFatal} * - `java.lang.LinkageError` * - `java.lang.InterruptedException` and `java.lang.ThreadDeath` * - [[scala.util.control.NonFatal fatal exceptions]], excluding `scala.util.control.ControlThrowable` + * - all other exceptions, excluding `scala.util.control.ControlThrowable` * - `scala.util.control.ControlThrowable` - * - all other exceptions * * When more than two exceptions are thrown, the first two are combined and * re-thrown as described above, and each successive exception thrown is combined @@ -265,9 +265,9 @@ object Using { case _: VirtualMachineError => 4 case _: LinkageError => 3 case _: InterruptedException | _: ThreadDeath => 2 - case _: ControlThrowable => 0 + case _: ControlThrowable => -1 // below everything case e if !NonFatal(e) => 1 // in case this method gets out of sync with NonFatal - case _ => -1 + case _ => 0 } @inline def suppress(t: Throwable, suppressed: Throwable): Throwable = { t.addSuppressed(suppressed); t } diff --git a/src/library/scala/util/control/Breaks.scala b/src/library/scala/util/control/Breaks.scala index 770e61aaa504..888867c0acaf 100644 --- a/src/library/scala/util/control/Breaks.scala +++ b/src/library/scala/util/control/Breaks.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/control/ControlThrowable.scala b/src/library/scala/util/control/ControlThrowable.scala index 62b5915c8f9c..ea5ff549e121 100644 --- a/src/library/scala/util/control/ControlThrowable.scala +++ b/src/library/scala/util/control/ControlThrowable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 2d729b2c4f02..181bb22743a7 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/control/NoStackTrace.scala b/src/library/scala/util/control/NoStackTrace.scala index bee5deacd515..f34fec38180c 100644 --- a/src/library/scala/util/control/NoStackTrace.scala +++ b/src/library/scala/util/control/NoStackTrace.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/control/NonFatal.scala b/src/library/scala/util/control/NonFatal.scala index 3bce19e8b2be..80d8812a42ef 100644 --- a/src/library/scala/util/control/NonFatal.scala +++ b/src/library/scala/util/control/NonFatal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/control/TailCalls.scala b/src/library/scala/util/control/TailCalls.scala index 442143c38980..717ea9004f3f 100644 --- a/src/library/scala/util/control/TailCalls.scala +++ b/src/library/scala/util/control/TailCalls.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -10,14 +10,17 @@ * additional information regarding copyright ownership. */ -package scala -package util.control +package scala.util.control + +import annotation.tailrec /** Methods exported by this object implement tail calls via trampolining. - * Tail calling methods have to return their result using `done` or call the - * next method using `tailcall`. Both return a `TailRec` object. The result - * of evaluating a tailcalling function can be retrieved from a `Tailrec` + * + * Tail calling methods must either return their result using `done` or call the + * next method using `tailcall`. Both return an instance of `TailRec`. The result + * of evaluating a tailcalling function can be retrieved from a `TailRec` * value using method `result`. + * * Implemented as described in "Stackless Scala with Free Monads" * [[https://blog.higher-order.com/assets/trampolines.pdf]] * @@ -44,67 +47,65 @@ package util.control */ object TailCalls { - /** This class represents a tailcalling computation + /** This class represents a tailcalling computation. */ sealed abstract class TailRec[+A] { /** Continue the computation with `f`. */ - final def map[B](f: A => B): TailRec[B] = - flatMap(a => Call(() => Done(f(a)))) + final def map[B](f: A => B): TailRec[B] = flatMap(a => Call(() => Done(f(a)))) /** Continue the computation with `f` and merge the trampolining - * of this computation with that of `f`. */ - final def flatMap[B](f: A => TailRec[B]): TailRec[B] = - this match { - case Done(a) => Call(() => f(a)) - case c @ Call(_) => Cont(c, f) - // Take advantage of the monad associative law to optimize the size of the required stack - case c: Cont[a1, b1] => Cont(c.a, (x: a1) => c.f(x) flatMap f) - } + * of this computation with that of `f`. */ + final def flatMap[B](f: A => TailRec[B]): TailRec[B] = this match { + case Done(a) => Call(() => f(a)) + case Call(_) => Cont(this, f) + // Take advantage of the monad associative law to optimize the size of the required stack + case c: Cont[a1, b1] => Cont(c.a, (x: a1) => c.f(x).flatMap(f)) + } /** Returns either the next step of the tailcalling computation, * or the result if there are no more steps. */ - @annotation.tailrec final def resume: Either[() => TailRec[A], A] = this match { - case Done(a) => Right(a) - case Call(k) => Left(k) + @tailrec final def resume: Either[() => TailRec[A], A] = this match { + case Done(a) => Right(a) + case Call(k) => Left(k) case Cont(a, f) => a match { - case Done(v) => f(v).resume - case Call(k) => Left(() => k().flatMap(f)) - case Cont(b, g) => b.flatMap(x => g(x) flatMap f).resume + case Done(v) => f(v).resume + case Call(k) => Left(() => k().flatMap(f)) + case Cont(b, g) => b.flatMap(x => g(x).flatMap(f)).resume } } /** Returns the result of the tailcalling computation. */ - @annotation.tailrec final def result: A = this match { - case Done(a) => a - case Call(t) => t().result + @tailrec final def result: A = this match { + case Done(a) => a + case Call(t) => t().result case Cont(a, f) => a match { - case Done(v) => f(v).result - case Call(t) => t().flatMap(f).result - case Cont(b, g) => b.flatMap(x => g(x) flatMap f).result + case Done(v) => f(v).result + case Call(t) => t().flatMap(f).result + case Cont(b, g) => b.flatMap(x => g(x).flatMap(f)).result } } } - /** Internal class representing a tailcall */ + /** Internal class representing a tailcall. */ protected case class Call[A](rest: () => TailRec[A]) extends TailRec[A] /** Internal class representing the final result returned from a tailcalling - * computation */ + * computation. */ protected case class Done[A](value: A) extends TailRec[A] /** Internal class representing a continuation with function A => TailRec[B]. - * It is needed for the flatMap to be implemented. */ + * It is needed for the flatMap to be implemented. */ protected case class Cont[A, B](a: TailRec[A], f: A => TailRec[B]) extends TailRec[B] - /** Performs a tailcall + /** Perform a tailcall. * @param rest the expression to be evaluated in the tailcall * @return a `TailRec` object representing the expression `rest` */ def tailcall[A](rest: => TailRec[A]): TailRec[A] = Call(() => rest) - /** Used to return final result from tailcalling computation + /** Return the final result from a tailcalling computation. * @param `result` the result value * @return a `TailRec` object representing a computation which immediately * returns `result` diff --git a/src/library/scala/util/hashing/ByteswapHashing.scala b/src/library/scala/util/hashing/ByteswapHashing.scala index 21ff35fa5163..ca96e4d1f4a5 100644 --- a/src/library/scala/util/hashing/ByteswapHashing.scala +++ b/src/library/scala/util/hashing/ByteswapHashing.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/hashing/Hashing.scala b/src/library/scala/util/hashing/Hashing.scala index 2bc157dd4554..28067cce9992 100644 --- a/src/library/scala/util/hashing/Hashing.scala +++ b/src/library/scala/util/hashing/Hashing.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/hashing/MurmurHash3.scala b/src/library/scala/util/hashing/MurmurHash3.scala index a714c25cedfe..1fa98e790445 100644 --- a/src/library/scala/util/hashing/MurmurHash3.scala +++ b/src/library/scala/util/hashing/MurmurHash3.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -60,15 +60,16 @@ private[hashing] class MurmurHash3 { finalizeHash(h, 2) } - /** Compute the hash of a product */ + // @deprecated("use `caseClassHash` instead", "2.13.17") + // The deprecation is commented because this method is called by the synthetic case class hashCode. + // In this case, the `seed` already has the case class name mixed in and `ignorePrefix` is set to true. + // Case classes compiled before 2.13.17 call this method with `productSeed` and `ignorePrefix = false`. + // See `productHashCode` in `SyntheticMethods` for details. final def productHash(x: Product, seed: Int, ignorePrefix: Boolean = false): Int = { val arr = x.productArity - // Case objects have the hashCode inlined directly into the - // synthetic hashCode method, but this method should still give - // a correct result if passed a case object. - if (arr == 0) { - x.productPrefix.hashCode - } else { + if (arr == 0) + if (!ignorePrefix) x.productPrefix.hashCode else seed + else { var h = seed if (!ignorePrefix) h = mix(h, x.productPrefix.hashCode) var i = 0 @@ -80,6 +81,24 @@ private[hashing] class MurmurHash3 { } } + /** See the [[MurmurHash3.caseClassHash(x:Product,caseClassName:String)]] overload */ + final def caseClassHash(x: Product, seed: Int, caseClassName: String): Int = { + val arr = x.productArity + val aye = (if (caseClassName != null) caseClassName else x.productPrefix).hashCode + if (arr == 0) aye + else { + var h = seed + h = mix(h, aye) + var i = 0 + while (i < arr) { + h = mix(h, x.productElement(i).##) + i += 1 + } + finalizeHash(h, arr) + } + } + + /** Compute the hash of a string */ final def stringHash(str: String, seed: Int): Int = { var h = seed @@ -136,7 +155,7 @@ private[hashing] class MurmurHash3 { while (it.hasNext) { h = mix(h, prev) val hash = it.next().## - if(rangeDiff != hash - prev) { + if(rangeDiff != hash - prev || rangeDiff == 0) { h = mix(h, hash) i += 1 while (it.hasNext) { @@ -173,7 +192,7 @@ private[hashing] class MurmurHash3 { while (i < l) { h = mix(h, prev) val hash = a(i).## - if(rangeDiff != hash - prev) { + if(rangeDiff != hash - prev || rangeDiff == 0) { h = mix(h, hash) i += 1 while (i < l) { @@ -252,7 +271,7 @@ private[hashing] class MurmurHash3 { while (i < l) { h = mix(h, prev) val hash = a(i).## - if(rangeDiff != hash - prev) { + if(rangeDiff != hash - prev || rangeDiff == 0) { h = mix(h, hash) i += 1 while (i < l) { @@ -292,7 +311,7 @@ private[hashing] class MurmurHash3 { rangeDiff = hash - prev rangeState = 2 case 2 => - if(rangeDiff != hash - prev) rangeState = 3 + if(rangeDiff != hash - prev || rangeDiff == 0) rangeState = 3 case _ => } prev = hash @@ -337,14 +356,46 @@ object MurmurHash3 extends MurmurHash3 { final val mapSeed = "Map".hashCode final val setSeed = "Set".hashCode - def arrayHash[@specialized T](a: Array[T]): Int = arrayHash(a, arraySeed) - def bytesHash(data: Array[Byte]): Int = bytesHash(data, arraySeed) - def orderedHash(xs: IterableOnce[Any]): Int = orderedHash(xs, symmetricSeed) - def productHash(x: Product): Int = productHash(x, productSeed) - def stringHash(x: String): Int = stringHash(x, stringSeed) - def unorderedHash(xs: IterableOnce[Any]): Int = unorderedHash(xs, traversableSeed) + def arrayHash[@specialized T](a: Array[T]): Int = arrayHash(a, arraySeed) + def bytesHash(data: Array[Byte]): Int = bytesHash(data, arraySeed) + def orderedHash(xs: IterableOnce[Any]): Int = orderedHash(xs, symmetricSeed) + def stringHash(x: String): Int = stringHash(x, stringSeed) + def unorderedHash(xs: IterableOnce[Any]): Int = unorderedHash(xs, traversableSeed) def rangeHash(start: Int, step: Int, last: Int): Int = rangeHash(start, step, last, seqSeed) + @deprecated("use `caseClassHash` instead", "2.13.17") + def productHash(x: Product): Int = caseClassHash(x, productSeed, null) + + /** + * Compute the `hashCode` of a case class instance. This method returns the same value as `x.hashCode` + * if `x` is an instance of a case class with the default, synthetic `hashCode`. + * + * This method can be used to implement case classes with a cached `hashCode`: + * {{{ + * case class C(data: Data) { + * override lazy val hashCode: Int = MurmurHash3.caseClassHash(this) + * } + * }}} + * + * '''NOTE''': For case classes (or subclasses) that override `productPrefix`, the `caseClassName` parameter + * needs to be specified in order to obtain the same result as the synthetic `hashCode`. Otherwise, the value + * is not in sync with the case class `equals` method (scala/bug#13033). + * + * {{{ + * scala> case class C(x: Int) { override def productPrefix = "Y" } + * + * scala> C(1).hashCode + * val res0: Int = -668012062 + * + * scala> MurmurHash3.caseClassHash(C(1)) + * val res1: Int = 1015658380 + * + * scala> MurmurHash3.caseClassHash(C(1), "C") + * val res2: Int = -668012062 + * }}} + */ + def caseClassHash(x: Product, caseClassName: String = null): Int = caseClassHash(x, productSeed, caseClassName) + private[scala] def arraySeqHash[@specialized T](a: Array[T]): Int = arrayHash(a, seqSeed) private[scala] def tuple2Hash(x: Any, y: Any): Int = tuple2Hash(x.##, y.##, productSeed) @@ -397,8 +448,13 @@ object MurmurHash3 extends MurmurHash3 { def hash(xs: IterableOnce[Any]) = orderedHash(xs) } + @deprecated("use `caseClassHashing` instead", "2.13.17") def productHashing = new Hashing[Product] { - def hash(x: Product) = productHash(x) + def hash(x: Product) = caseClassHash(x) + } + + def caseClassHashing = new Hashing[Product] { + def hash(x: Product) = caseClassHash(x) } def stringHashing = new Hashing[String] { diff --git a/src/library/scala/util/hashing/package.scala b/src/library/scala/util/hashing/package.scala index f8ca83cf5339..530b729e2f81 100644 --- a/src/library/scala/util/hashing/package.scala +++ b/src/library/scala/util/hashing/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala index 2c3b45153cdf..a90171243e3a 100644 --- a/src/library/scala/util/matching/Regex.scala +++ b/src/library/scala/util/matching/Regex.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -508,9 +508,10 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends * @return The target string after replacements. */ def replaceAllIn(target: CharSequence, replacer: Match => String): String = { - val it = new Regex.MatchIterator(target, this, groupNames).replacementData - it foreach (md => it replace replacer(md)) - it.replaced + val rit = new Regex.MatchIterator(target, this, groupNames).replacementData + for (matchdata <- rit; replacement = replacer(matchdata)) + rit.replace(replacement) + rit.replaced } /** @@ -535,11 +536,10 @@ class Regex private[matching](val pattern: Pattern, groupNames: String*) extends * @return The target string after replacements. */ def replaceSomeIn(target: CharSequence, replacer: Match => Option[String]): String = { - val it = new Regex.MatchIterator(target, this, groupNames).replacementData - for (matchdata <- it ; replacement <- replacer(matchdata)) - it replace replacement - - it.replaced + val rit = new Regex.MatchIterator(target, this, groupNames).replacementData + for (matchdata <- rit; replacement <- replacer(matchdata)) + rit.replace(replacement) + rit.replaced } /** Replaces the first match by a string. @@ -874,28 +874,27 @@ object Regex { /** Convert to an iterator that yields MatchData elements instead of Strings and has replacement support. */ private[matching] def replacementData = new AbstractIterator[Match] with Replacement { - def matcher = self.matcher + protected def matcher = self.matcher def hasNext = self.hasNext - def next() = { self.next(); new Match(source, matcher, _groupNames).force } + def next(): Match = { self.next(); new Match(source, matcher, _groupNames).force } } } - /** - * A trait able to build a string with replacements assuming it has a matcher. - * Meant to be mixed in with iterators. + /** Internal trait used by `replaceAllIn` and `replaceSomeIn`. */ private[matching] trait Replacement { protected def matcher: Matcher - private[this] val sb = new java.lang.StringBuffer + private[this] val sb = new java.lang.StringBuffer // StringBuffer for JDK 8 compatibility + // Appends the remaining input and returns the result text. def replaced = { - val newsb = new java.lang.StringBuffer(sb) - matcher.appendTail(newsb) - newsb.toString + matcher.appendTail(sb) + sb.toString } - def replace(rs: String) = matcher.appendReplacement(sb, rs) + // Appends the input prefix and the replacement text. + def replace(replacement: String) = matcher.appendReplacement(sb, replacement) } /** Quotes strings to be used literally in regex patterns. diff --git a/src/library/scala/util/package.scala b/src/library/scala/util/package.scala index 23fa8e207184..1b8b84dd2bfe 100644 --- a/src/library/scala/util/package.scala +++ b/src/library/scala/util/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/library/scala/volatile.scala b/src/library/scala/volatile.scala index 56314f5d2f82..2f4f3c37e676 100644 --- a/src/library/scala/volatile.scala +++ b/src/library/scala/volatile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/manual/scala/man1/scalac.scala b/src/manual/scala/man1/scalac.scala index 88788133debd..1e7e04584781 100644 --- a/src/manual/scala/man1/scalac.scala +++ b/src/manual/scala/man1/scalac.scala @@ -206,7 +206,7 @@ object scalac extends Command { CmdOption("Xfull-lubs"), "Retain pre 2.10 behavior of less aggressive truncation of least upper bounds."), Definition( - CmdOption("Xgenerate-phase-graph", Argument("file")), + CmdOption("Vphase-graph", Argument("file")), "Generate the phase graphs (outputs .dot files) to fileX.dot."), Definition( CmdOption("Xlint"), @@ -239,8 +239,8 @@ object scalac extends Command { CmdOption("Xno-patmat-analysis"), "Don't perform exhaustivity/unreachability analysis. Also, ignore " & MItalic("@switch") & " annotation."), Definition( - CmdOption("Xjline"), - "The JLine keybindings to use: emacs/vi/off."), + CmdOption("Xnojline"), + "Do not use JLine at all for REPL input."), Definition( CmdOptionBound("Xplugin:", Argument("paths")), "Load a plugin from each classpath."), diff --git a/src/manual/scala/tools/docutil/ManMaker.scala b/src/manual/scala/tools/docutil/ManMaker.scala index 60863aca3285..4c19ccac27c6 100644 --- a/src/manual/scala/tools/docutil/ManMaker.scala +++ b/src/manual/scala/tools/docutil/ManMaker.scala @@ -57,7 +57,7 @@ class ManMaker { /** Command line runner for ManMaker which is called from the sbt build. */ object ManMaker extends App { - val Array(commands, htmlout, manout) = args + val Array(commands, htmlout, manout) = args: @unchecked val mm = new ManMaker mm.setCommand(commands) mm.setHtmlout(new File(htmlout)) diff --git a/src/partest/scala/tools/partest/AsmNode.scala b/src/partest/scala/tools/partest/AsmNode.scala index 21447252f024..25272feff90d 100644 --- a/src/partest/scala/tools/partest/AsmNode.scala +++ b/src/partest/scala/tools/partest/AsmNode.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/BytecodeTest.scala b/src/partest/scala/tools/partest/BytecodeTest.scala index 33320a7111ff..e27beb2769ef 100644 --- a/src/partest/scala/tools/partest/BytecodeTest.scala +++ b/src/partest/scala/tools/partest/BytecodeTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala index 8114d071c460..71886ef4a7e9 100644 --- a/src/partest/scala/tools/partest/CompilerTest.scala +++ b/src/partest/scala/tools/partest/CompilerTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -31,11 +31,12 @@ abstract class CompilerTest extends DirectTest { def check(source: String, unit: global.CompilationUnit): Unit lazy val global: Global = newCompiler() - lazy val units: List[global.CompilationUnit] = compilationUnits(global)(sources: _ *) + lazy val computedSources = sources + lazy val units: List[global.CompilationUnit] = compilationUnits(global)(computedSources: _ *) import global._ import definitions.compilerTypeFromTag - def show() = sources.lazyZip(units).foreach(check) + def show() = computedSources.lazyZip(units).foreach(check) // Override at least one of these... def code = "" diff --git a/src/partest/scala/tools/partest/ConsoleLog.scala b/src/partest/scala/tools/partest/ConsoleLog.scala index cae03bbaf19b..53df36711f76 100644 --- a/src/partest/scala/tools/partest/ConsoleLog.scala +++ b/src/partest/scala/tools/partest/ConsoleLog.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala index 37b473a5e09e..44bc08b5c05e 100644 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ b/src/partest/scala/tools/partest/DirectTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -53,12 +53,15 @@ abstract class DirectTest { // a default Settings object using only extraSettings def settings: Settings = newSettings(tokenize(extraSettings)) // settings factory using given args and also debug settings - def newSettings(args: List[String]) = (new Settings).tap { s => - val allArgs = args ++ tokenize(debugSettings) + def newSettings(args: List[String]): Settings = newBaseSettings().tap { s => + val allArgs = debugSettings.pipe(db => if (db.isEmpty) args else args ++ tokenize(db)) log(s"newSettings: allArgs = $allArgs") val (success, residual) = s.processArguments(allArgs, processAll = false) assert(success && residual.isEmpty, s"Bad settings [${args.mkString(",")}], residual [${residual.mkString(",")}]") } + // scaladoc has custom settings + def newBaseSettings(): Settings = new Settings + // new compiler using given ad hoc args, -d and extraSettings def newCompiler(args: String*): Global = { val settings = newSettings(tokenize(s"""-d "${testOutput.path}" ${extraSettings}""") ++ args.toList) diff --git a/src/partest/scala/tools/partest/IcodeComparison.scala b/src/partest/scala/tools/partest/IcodeComparison.scala index dde21136cedc..ae28cfef1755 100644 --- a/src/partest/scala/tools/partest/IcodeComparison.scala +++ b/src/partest/scala/tools/partest/IcodeComparison.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/IcodeTest.scala b/src/partest/scala/tools/partest/IcodeTest.scala index 8be9d63b18f4..688c87d708ec 100644 --- a/src/partest/scala/tools/partest/IcodeTest.scala +++ b/src/partest/scala/tools/partest/IcodeTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/JUnitTest.scala b/src/partest/scala/tools/partest/JUnitTest.scala index 079531fc4a07..85410fe199c4 100644 --- a/src/partest/scala/tools/partest/JUnitTest.scala +++ b/src/partest/scala/tools/partest/JUnitTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/JavapTest.scala b/src/partest/scala/tools/partest/JavapTest.scala index d2c126138bb1..05fb811d3166 100644 --- a/src/partest/scala/tools/partest/JavapTest.scala +++ b/src/partest/scala/tools/partest/JavapTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/MemoryTest.scala b/src/partest/scala/tools/partest/MemoryTest.scala index 23b37f09ca34..6d44a0163080 100644 --- a/src/partest/scala/tools/partest/MemoryTest.scala +++ b/src/partest/scala/tools/partest/MemoryTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/PartestDefaults.scala b/src/partest/scala/tools/partest/PartestDefaults.scala index f92da68b90d0..2e9afd5c633d 100644 --- a/src/partest/scala/tools/partest/PartestDefaults.scala +++ b/src/partest/scala/tools/partest/PartestDefaults.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/ReplTest.scala b/src/partest/scala/tools/partest/ReplTest.scala index eb35dc29238b..af1e1cc729d3 100644 --- a/src/partest/scala/tools/partest/ReplTest.scala +++ b/src/partest/scala/tools/partest/ReplTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -32,7 +32,7 @@ abstract class ReplTest extends DirectTest { // final because we need to enforce the existence of a couple settings. final override def settings: Settings = { val s = super.settings - s.Xjline.value = "off" + s.Xnojline.value = true if (getClass.getClassLoader.getParent != null) { s.classpath.value = s.classpath.value match { case "" => testOutput.toString diff --git a/src/partest/scala/tools/partest/ScaladocJavaModelTest.scala b/src/partest/scala/tools/partest/ScaladocJavaModelTest.scala index 3f89dc71f167..c3e251ced27a 100644 --- a/src/partest/scala/tools/partest/ScaladocJavaModelTest.scala +++ b/src/partest/scala/tools/partest/ScaladocJavaModelTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala index d0bd55be94c3..31f0e692bfa2 100644 --- a/src/partest/scala/tools/partest/ScaladocModelTest.scala +++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -12,13 +12,13 @@ package scala.tools.partest -import scala.sys.process.{Parser => CommandLineParser} import scala.tools.nsc._ +import scala.tools.nsc.doc.{DocFactory, Universe} import scala.tools.nsc.doc.base.comment._ import scala.tools.nsc.doc.model._ import scala.tools.nsc.doc.model.diagram._ -import scala.tools.nsc.doc.{DocFactory, Universe} import scala.tools.nsc.reporters.ConsoleReporter +import scala.util.chaining._ /** A class for testing scaladoc model generation * - you need to specify the code in the `code` method @@ -87,20 +87,21 @@ abstract class ScaladocModelTest extends DirectTest { private[this] var docSettings: doc.Settings = null + // custom settings, silencing "model contains X documentable templates" + override def newBaseSettings(): doc.Settings = new doc.Settings(_ => ()).tap(_.scaladocQuietRun = true) + override def newSettings(args: List[String]): doc.Settings = super.newSettings(args).asInstanceOf[doc.Settings] + override def settings: doc.Settings = newSettings(tokenize(s"$extraSettings $scaladocSettings")) + // create a new scaladoc compiler def newDocFactory: DocFactory = { - docSettings = new doc.Settings(_ => ()) - docSettings.scaladocQuietRun = true // yaay, no more "model contains X documentable templates"! - val args = extraSettings + " " + scaladocSettings - new ScalaDoc.Command((CommandLineParser tokenize (args)), docSettings) // side-effecting, I think - val docFact = new DocFactory(new ConsoleReporter(docSettings), docSettings) - docFact + docSettings = settings + new DocFactory(new ConsoleReporter(docSettings), docSettings) } // compile with scaladoc and output the result def model: Option[Universe] = newDocFactory.makeUniverse(Right(code)) - // finally, enable easy navigation inside the entities + // enable easy navigation inside the entities object access { implicit class TemplateAccess(tpl: DocTemplateEntity) { diff --git a/src/partest/scala/tools/partest/ScriptTest.scala b/src/partest/scala/tools/partest/ScriptTest.scala index ad5362e17520..18775fb4a310 100644 --- a/src/partest/scala/tools/partest/ScriptTest.scala +++ b/src/partest/scala/tools/partest/ScriptTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/SigTest.scala b/src/partest/scala/tools/partest/SigTest.scala index 49a756ea1945..b54487b30fe9 100644 --- a/src/partest/scala/tools/partest/SigTest.scala +++ b/src/partest/scala/tools/partest/SigTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/StoreReporterDirectTest.scala b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala index 32e4ec84136f..613c2d996212 100644 --- a/src/partest/scala/tools/partest/StoreReporterDirectTest.scala +++ b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/StubErrorMessageTest.scala b/src/partest/scala/tools/partest/StubErrorMessageTest.scala index 2cdcfe93832d..949850babcea 100644 --- a/src/partest/scala/tools/partest/StubErrorMessageTest.scala +++ b/src/partest/scala/tools/partest/StubErrorMessageTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/TestKinds.scala b/src/partest/scala/tools/partest/TestKinds.scala index ff9041dd7129..9a5847a35938 100644 --- a/src/partest/scala/tools/partest/TestKinds.scala +++ b/src/partest/scala/tools/partest/TestKinds.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/TestState.scala b/src/partest/scala/tools/partest/TestState.scala index 3b6dc49444ac..056b8d73ecfd 100644 --- a/src/partest/scala/tools/partest/TestState.scala +++ b/src/partest/scala/tools/partest/TestState.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/Util.scala b/src/partest/scala/tools/partest/Util.scala index eaea5484779c..26beb886505f 100644 --- a/src/partest/scala/tools/partest/Util.scala +++ b/src/partest/scala/tools/partest/Util.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/async/CompletableFutureAwait.scala b/src/partest/scala/tools/partest/async/CompletableFutureAwait.scala index 914408bc55b9..a209720911f7 100644 --- a/src/partest/scala/tools/partest/async/CompletableFutureAwait.scala +++ b/src/partest/scala/tools/partest/async/CompletableFutureAwait.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/async/OptionDsl.scala b/src/partest/scala/tools/partest/async/OptionDsl.scala index 098a5bdfcae7..adc6a0141b86 100644 --- a/src/partest/scala/tools/partest/async/OptionDsl.scala +++ b/src/partest/scala/tools/partest/async/OptionDsl.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/async/OutputAwait.scala b/src/partest/scala/tools/partest/async/OutputAwait.scala index d5beb70baddb..96a7bbd6c226 100644 --- a/src/partest/scala/tools/partest/async/OutputAwait.scala +++ b/src/partest/scala/tools/partest/async/OutputAwait.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/instrumented/Instrumentation.scala b/src/partest/scala/tools/partest/instrumented/Instrumentation.scala index 37a7265e0531..6127f82b8403 100644 --- a/src/partest/scala/tools/partest/instrumented/Instrumentation.scala +++ b/src/partest/scala/tools/partest/instrumented/Instrumentation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/instrumented/Profiler.java b/src/partest/scala/tools/partest/instrumented/Profiler.java index d67e7d3572ac..fdb37ad0d06f 100644 --- a/src/partest/scala/tools/partest/instrumented/Profiler.java +++ b/src/partest/scala/tools/partest/instrumented/Profiler.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/AbstractRunner.scala b/src/partest/scala/tools/partest/nest/AbstractRunner.scala index e6473ed074a7..1118e1995bae 100644 --- a/src/partest/scala/tools/partest/nest/AbstractRunner.scala +++ b/src/partest/scala/tools/partest/nest/AbstractRunner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/CommandLine.scala b/src/partest/scala/tools/partest/nest/CommandLine.scala index 57420e993967..f3c22f107554 100644 --- a/src/partest/scala/tools/partest/nest/CommandLine.scala +++ b/src/partest/scala/tools/partest/nest/CommandLine.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/DelegatingSecurityManager.scala b/src/partest/scala/tools/partest/nest/DelegatingSecurityManager.scala index 66dff5d273c0..e73b20fa0af6 100644 --- a/src/partest/scala/tools/partest/nest/DelegatingSecurityManager.scala +++ b/src/partest/scala/tools/partest/nest/DelegatingSecurityManager.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/DirectCompiler.scala b/src/partest/scala/tools/partest/nest/DirectCompiler.scala index 45458276db9a..91f7bbb61180 100644 --- a/src/partest/scala/tools/partest/nest/DirectCompiler.scala +++ b/src/partest/scala/tools/partest/nest/DirectCompiler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -55,9 +55,8 @@ class DirectCompiler(val runner: Runner) { /** Massage args to merge plugins and fix paths. - * Plugin path can be relative to test root, or cwd is out. - * While we're at it, mix in the baseline options, too. - * That's how ant passes in the plugins dir. + * Plugin path can be relative to test root, or cwd (".") means use output dir and copy scalac-plugin.xml there. + * Mix in the baseline options from the suiteRunner (scalacOpts, scalacExtraArgs). */ private def updatePluginPath(args: List[String], out: AbstractFile, srcdir: AbstractFile): Seq[String] = { val dir = runner.suiteRunner.pathSettings.testRoot @@ -87,6 +86,11 @@ class DirectCompiler(val runner: Runner) { runner.suiteRunner.scalacExtraArgs ++ filteredOpts ++ others ++ Xplugin } + private def updatePluginPath(args: List[String]): Seq[String] = { + import runner.testInfo.testFile + val srcDir = if (testFile.isDirectory) testFile else Path(testFile).parent.jfile + updatePluginPath(args, AbstractFile.getDirectory(runner.outDir), AbstractFile.getDirectory(srcDir)) + } def compile(opts0: List[String], sources: List[File]): TestState = { import runner.{sources => _, _} @@ -104,14 +108,15 @@ class DirectCompiler(val runner: Runner) { val testSettings = new TestSettings(FileManager.joinPaths(classPath), s => parseArgErrors += s) val logWriter = new FileWriter(logFile) - val srcDir = if (testFile.isDirectory) testFile else Path(testFile).parent.jfile - val opts = updatePluginPath(opts0, AbstractFile.getDirectory(outDir), AbstractFile.getDirectory(srcDir)) + val opts = updatePluginPath(opts0) val command = new CompilerCommand(opts.toList, testSettings) val reporter = ExtConsoleReporter(testSettings, new PrintWriter(logWriter, true)) val global = newGlobal(testSettings, reporter) def errorCount = reporter.errorCount - testSettings.outputDirs.setSingleOutput(outDir.getPath) + // usually, -d outDir, but don't override setting by the test + if (!testSettings.outdir.isSetByUser) + testSettings.outputDirs.setSingleOutput(outDir.getPath) def reportError(s: String): Unit = reporter.error(NoPosition, s) diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index fdfb2a86594b..6beceaef17dd 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/FromString.scala b/src/partest/scala/tools/partest/nest/FromString.scala index 2237b9ce6fd7..1a801f9d818f 100644 --- a/src/partest/scala/tools/partest/nest/FromString.scala +++ b/src/partest/scala/tools/partest/nest/FromString.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,8 +13,6 @@ package scala.tools.partest.nest import scala.reflect.OptManifest -import scala.sys.process.Parser.tokenize -import scala.tools.nsc.io.Directory /** A general mechanism for defining how a command line argument * (always a String) is transformed into an arbitrary type. A few @@ -30,6 +28,8 @@ abstract class FromString[+T](implicit m: OptManifest[T]) extends PartialFunctio } object FromString { + import scala.sys.process.Parser.tokenize + import scala.tools.nsc.io.Directory // We need this because we clash with the String => Path implicits. private def toDir(s: String) = new Directory(new java.io.File(s)) @@ -66,6 +66,6 @@ object FromString { */ implicit val IntFromString: FromString[Int] = new FromString[Int] { override def isDefinedAt(s: String) = s.toIntOption.isDefined - def apply(s: String) = s.toInt + def apply(s: String) = s.toIntOption.getOrElse(0) } } diff --git a/src/partest/scala/tools/partest/nest/Instance.scala b/src/partest/scala/tools/partest/nest/Instance.scala index 21da651e7031..dabe6d1ba988 100644 --- a/src/partest/scala/tools/partest/nest/Instance.scala +++ b/src/partest/scala/tools/partest/nest/Instance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/Interpolation.scala b/src/partest/scala/tools/partest/nest/Interpolation.scala index 332b44055efd..522a108ccffe 100644 --- a/src/partest/scala/tools/partest/nest/Interpolation.scala +++ b/src/partest/scala/tools/partest/nest/Interpolation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/Meta.scala b/src/partest/scala/tools/partest/nest/Meta.scala index fe84599c7757..28ffec7e89b0 100644 --- a/src/partest/scala/tools/partest/nest/Meta.scala +++ b/src/partest/scala/tools/partest/nest/Meta.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/Opt.scala b/src/partest/scala/tools/partest/nest/Opt.scala index 415f6404cfe7..9c64896301c9 100644 --- a/src/partest/scala/tools/partest/nest/Opt.scala +++ b/src/partest/scala/tools/partest/nest/Opt.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/PathSettings.scala b/src/partest/scala/tools/partest/nest/PathSettings.scala index af3818e8d0bf..e9ed01018acd 100644 --- a/src/partest/scala/tools/partest/nest/PathSettings.scala +++ b/src/partest/scala/tools/partest/nest/PathSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/Reference.scala b/src/partest/scala/tools/partest/nest/Reference.scala index ecf07319f8a5..93c83cf6d40b 100644 --- a/src/partest/scala/tools/partest/nest/Reference.scala +++ b/src/partest/scala/tools/partest/nest/Reference.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/Runner.scala b/src/partest/scala/tools/partest/nest/Runner.scala index 307e2cdcdb50..fbdd16a69c1f 100644 --- a/src/partest/scala/tools/partest/nest/Runner.scala +++ b/src/partest/scala/tools/partest/nest/Runner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -18,15 +18,15 @@ import java.lang.reflect.InvocationTargetException import java.nio.charset.Charset import java.nio.file.{Files, Path, StandardOpenOption}, StandardOpenOption.{APPEND, CREATE} -import scala.annotation.nowarn import scala.collection.mutable, mutable.ListBuffer import scala.concurrent.duration.Duration import scala.reflect.internal.FatalError import scala.reflect.internal.util.ScalaClassLoader, ScalaClassLoader.URLClassLoader import scala.sys.process.{Process, ProcessLogger} -import scala.tools.nsc.Properties.{isWin, propOrEmpty} +import scala.tools.nsc.Properties.{isAvian, isWin, javaSpecVersion, propOrEmpty} import scala.tools.nsc.{CompilerCommand, Global, Settings} import scala.tools.nsc.reporters.ConsoleReporter +import scala.tools.nsc.settings.ScalaVersion import scala.tools.nsc.util.stackTraceString import scala.util.{Failure, Success, Try, Using} import scala.util.Properties.isJavaAtLeast @@ -77,8 +77,12 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { private val _transcript = new TestTranscript + // start log event def pushTranscript(msg: String) = _transcript.add(msg) + // append to last log in transcript + def appendTranscript(log: String) = _transcript.append(log) + lazy val outDir = { outFile.mkdirs() ; outFile } // if there is a checkfile, log message for diff; otherwise log stack trace for post-mortem @@ -113,7 +117,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { joinPaths(outDir :: testClassPath), "-J-Duser.language=en", "-J-Duser.country=US" - ) ++ (toolArgsFor(files)(ToolName.javac) + ) ++ (toolArgsFor(files)(ToolName.javacOpt) ) ++ (files.map(_.getAbsolutePath) ) @@ -220,7 +224,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { pushTranscript((cmd mkString s" \\$EOL ") + " > " + logFile.getName) nextTestAction(runCommand(cmd, logFile)) { case false => - _transcript append EOL + logFile.fileContents + appendTranscript(EOL + logFile.fileContents) genFail("non-zero exit code") } } @@ -257,16 +261,8 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { } pushTranscript(s" > ${logFile.getName}") - - @nowarn("cat=deprecation") // JDK 17 deprecates SecurityManager, so TrapExit is deprecated too - val trapExit = TrapExit - - trapExit(() => run()) match { - case Left((status, throwable)) if status != 0 => - genFail("non-zero exit code") - case _ => - genPass() - } + run() + genPass() } } @@ -286,8 +282,6 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { * A missing flag evaluates the same as true. */ def filteredCheck: Seq[String] = { - import scala.util.Properties.{javaSpecVersion, isAvian, isWin} - import scala.tools.nsc.settings.ScalaVersion // use lines in block with this label? def retainOn(expr0: String) = { val expr = expr0.trim @@ -364,14 +358,8 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { // no spaces in test file paths below root, because otherwise how to detect end of path string? val pathFinder = raw"""(?i)\Q${elided}${File.separator}\E([\${File.separator}\S]*)""".r - def canonicalize: String => String = { - val hiders = toolArgs(ToolName.hide).map(_.r) - (s: String) => { - val pathless = pathFinder.replaceAllIn(s, m => quoteReplacement(ellipsis + squashSlashes(m.group(1)))) - if (hiders.isEmpty) pathless - else hiders.foldLeft(pathless)((s, r) => r.replaceAllIn(s, m => "***")) - } - } + def canonicalize: String => String = + s => pathFinder.replaceAllIn(s, m => quoteReplacement(ellipsis + squashSlashes(m.group(1)))) def masters = { val files = List(new File(parentFile, "filters"), new File(suiteRunner.pathSettings.srcDir.path, "filters")) @@ -411,7 +399,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { else gitRunner.flatMap(_ => withTempFile(outDir, fileBase, filteredCheck)(f => gitDiff(f, logFile))).getOrElse(diff) - _transcript append bestDiff + appendTranscript(bestDiff) genFail("output differs") } } @@ -429,23 +417,19 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { def newCompiler = new DirectCompiler(this) - def attemptCompile(sources: List[File]): TestState = { - val badflags = (testFile :: (if (testFile.isDirectory) sources else Nil)).map(_.changeExtension("flags")).find(_.exists) - if (badflags.isDefined) genFail(s"unexpected flags file ${badflags.get} (use source comment // scalac: -Werror)") - else - newCompiler.compile(flagsForCompilation(sources), sources).tap { state => - if (!state.isOk) _transcript.append("\n" + logFile.fileContents) - } - } + def attemptCompile(sources: List[File], extraFlags: List[String] = Nil): TestState = + newCompiler.compile(flagsForCompilation(sources) ::: extraFlags, sources).tap { state => + if (!state.isOk) appendTranscript(EOL + logFile.fileContents) + } // all sources in a round may contribute flags via // scalac: -flags - // under --realeasy, if a javaVersion isn't specified, require the minimum viable using -release 8 + // under --realeasy, if a jvm isn't specified, require the minimum viable using -release 8 // to avoid accidentally committing a test that requires a later JVM. def flagsForCompilation(sources: List[File]): List[String] = { var perFile = toolArgsFor(sources)(ToolName.scalac) if (parentFile.getParentFile.getName == "macro-annot") perFile ::= "-Ymacro-annotations" - if (realeasy && isJavaAtLeast(9) && !perFile.exists(releaseFlag.matches) && toolArgsFor(sources)(ToolName.javaVersion).isEmpty) + if (realeasy && isJavaAtLeast(9) && !perFile.exists(releaseFlag.matches) && toolArgsFor(sources)(ToolName.jvm).isEmpty) perFile ::= "-release:8" perFile } @@ -456,42 +440,46 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { // for each file, cache the args for each tool private val fileToolArgs = new mutable.HashMap[Path, Map[ToolName, List[String]]] + //private val optionsPattern = raw"\s*//>\s*using\s+(?:([^.]+)\.)?option(s)?\s+(.*)".r + private val optionsPattern = raw"\s*//>\s*using\s+(${ToolName.alts})\s+(.*)".r // Inspect given files for tool args in header line comments of the form `// tool: args`. - // If the line comment starts `//>`, accept `scalac:` options in the form of using pragmas. + // If the line comment starts `//>`, accept `using option` or `using options` pragmas + // to define options to`scalac`. Or take `using test.options`, where test scope is used for test options. + // (`test` scope is not used that way by scala-cli, where framework args are passed on command line.) + // (One could imagine `using test.testOpt` for framework args.) // If `filter:`, return entire line as if quoted, else parse the args string as command line. - // Currently, we look for scalac, javac, java, javaVersion, filter, hide. + // Currently, we look for scalac, javac, java, jvm, filter, test. // def toolArgsFor(files: List[File])(tool: ToolName): List[String] = { def argsFor(f: File): List[String] = fileToolArgs.getOrElseUpdate(f.toPath, readToolArgs(f)).apply(tool) - def readToolArgs(f: File): Map[ToolName, List[String]] = { - val header = readHeaderFrom(f) - ToolName.values.toList - .map(name => name -> fromHeader(name, header)) - .filterNot(_._2.isEmpty) - .toMap[ToolName, List[String]] - .withDefaultValue(List.empty[String]) - } - def fromHeader(name: ToolName, header: List[String]) = { + def readToolArgs(f: File): Map[ToolName, List[String]] = optionsFromHeader(readHeaderFrom(f)) + def optionsFromHeader(header: List[String]) = { import scala.sys.process.Parser.tokenize - val namePattern = raw"\s*//\s*$name:\s*(.*)".r - val optionsPattern = raw"\s*//>\s*using\s+option(s)?\s+(.*)".r - def matchLine(line: String): List[String] = - line match { - case namePattern(rest) => if (name == ToolName.filter) List(rest.trim) else tokenize(rest) - case _ if name == ToolName.scalac => - line match { - case optionsPattern(plural, rest) => - if (plural == null) List(rest.trim) - else tokenize(rest).filter(_ != ",").map(_.stripSuffix(",")) - case _ => Nil - } - case _ => Nil - } + def matchLine(line: String): List[(ToolName, List[String])] = line match { + case optionsPattern(scope, rest) => + val named = Try { + if (scope == null) ToolName.scalac + else ToolName.named(scope) + }.toOption + named match { + case None => + suiteRunner.verbose(s"ignoring pragma with unknown scope '$scope': $line") + Nil + case Some(name) => + val settings = tokenize(rest).filter(_ != ",").map(_.stripSuffix(",")) + if (settings.isEmpty) Nil + else (name, settings) :: Nil + } + case _ => Nil + } header.flatMap(matchLine) + .groupBy(_._1) + .map { case (k, kvs) => (k, kvs.flatMap(_._2)) } + .withDefaultValue(List.empty[String]) } def readHeaderFrom(f: File): List[String] = - Using.resource(Files.lines(f.toPath, codec.charSet))(stream => stream.limit(10).toArray()).toList.map(_.toString) + Using.resource(Files.lines(f.toPath, codec.charSet))(_.limit(10).toArray()).toList.map(_.toString) files.flatMap(argsFor) } @@ -527,7 +515,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { val Range = """(\d+)(?:(\+)|(?:-(\d+)))?""".r lazy val currentJavaVersion = javaSpecVersion.stripPrefix("1.").toInt val allFiles = sources(file) - val skipStates = toolArgsFor(allFiles)(ToolName.javaVersion).flatMap { + val skipStates = toolArgsFor(allFiles)(ToolName.jvm).flatMap { case v @ Range(from, plus, to) => val ok = if (plus == null) @@ -539,7 +527,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { else if (ok) None else Some(genSkip(s"skipped on Java $javaSpecVersion, only running on $v")) case v => - Some(genFail(s"invalid javaVersion range in test comment: $v")) + Some(genFail(s"invalid jvm range in test comment: $v")) } skipStates.headOption match { case Some(state) => List(SkipRound(List(file), state)) @@ -560,14 +548,24 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { else runTestCommon()() def runNegTest(): TestState = { - // pass if it checks and didn't crash the compiler - // or, OK, we'll let you crash the compiler with a FatalError if you supply a check file + // a "crash test" passes if the error is not FatalError and there is a check file to compare. + // a neg test passes if the log compares same to check file. + // under "//> using retest.option -some-flags", also check pos compilation after adding the extra flags. def checked(r: TestState) = r match { case s: Skip => s case crash @ Crash(_, t, _) if !checkFile.canRead || !t.isInstanceOf[FatalError] => crash - case _ => diffIsOk + case _ => + val negRes = diffIsOk + toolArgs(ToolName.retest) match { + case extraFlags if extraFlags.nonEmpty && !negRes.isSkipped && negRes.isOk => + // transcript visible under partest --verbose or after failure + val debug = s"recompile $testIdent with extra flags ${extraFlags.mkString(" ")}" + suiteRunner.verbose(s"% $debug") + pushTranscript(debug) + attemptCompile(sources(testFile), extraFlags = extraFlags) + case _ => negRes + } } - runTestCommon(checked, expectCompile = false)(identity) } @@ -675,7 +673,7 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { } private def runRunTest(): TestState = { - val javaopts = toolArgs(ToolName.java) + val javaopts = toolArgs(ToolName.javaOpt) val execInProcess = PartestDefaults.execInProcess && javaopts.isEmpty && !Set("specialized", "instrumented").contains(testFile.getParentFile.getName) def exec() = if (execInProcess) execTestInProcess(outDir, logFile) else execTest(outDir, logFile, javaopts) def noexec() = genSkip("no-exec: tests compiled but not run") @@ -715,8 +713,8 @@ class Runner(val testInfo: TestInfo, val suiteRunner: AbstractRunner) { def pass(s: String) = bold(green("% ")) + s def fail(s: String) = bold(red("% ")) + s _transcript.toList match { - case Nil => Nil - case xs => (xs.init map pass) :+ fail(xs.last) + case init :+ last => init.map(pass) :+ fail(last) + case _ => Nil } } } @@ -787,15 +785,27 @@ final class TestTranscript { def toList = buf.toList } -// Tool names in test file header: scalac, javac, java, javaVersion, filter, hide. +// Tool names in test file header: scalac, javacOpt, javaOpt, jvm, filter, test, retest. sealed trait ToolName object ToolName { case object scalac extends ToolName - case object javac extends ToolName - case object java extends ToolName - case object javaVersion extends ToolName + case object javacOpt extends ToolName + case object javaOpt extends ToolName + case object jvm extends ToolName + case object test extends ToolName + case object retest extends ToolName case object filter extends ToolName - case object hide extends ToolName - val values = Array(scalac, javac, java, javaVersion, filter, hide) - def named(s: String): ToolName = values.find(_.toString.equalsIgnoreCase(s)).getOrElse(throw new IllegalArgumentException(s)) + val values = Array(scalac, javacOpt, javaOpt, jvm, test, retest, filter) + def named(s: String): ToolName = s match { + case "options" => scalac + case "test.options" => test + case "retest.options" => retest + case _ => values.find(_.toString == s).getOrElse(throw new IllegalArgumentException(s)) + } + def option(toolName: ToolName): String = toolName match { + case `scalac` => "options" + case `test` | `retest` => s"$toolName.options" + case _ => toolName.toString + } + val alts = values.map(option).mkString("|") } diff --git a/src/partest/scala/tools/partest/nest/RunnerSpec.scala b/src/partest/scala/tools/partest/nest/RunnerSpec.scala index 37dc5ca433de..04097a663c25 100644 --- a/src/partest/scala/tools/partest/nest/RunnerSpec.scala +++ b/src/partest/scala/tools/partest/nest/RunnerSpec.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,7 +13,6 @@ package scala.tools.partest.nest import language.postfixOps -import scala.annotation.nowarn trait RunnerSpec extends Spec with Meta.StdOpts with Interpolation { def referenceSpec = RunnerSpec @@ -70,6 +69,5 @@ object RunnerSpec extends RunnerSpec with Reference { def creator(args: List[String]): ThisCommandLine = new CommandLine(RunnerSpec, args) // TODO: restructure to avoid using early initializers - @nowarn("cat=deprecation&msg=early initializers") def forArgs(args: Array[String]): Config = new { val parsed = creator(args.toList) } with Config } diff --git a/src/partest/scala/tools/partest/nest/Spec.scala b/src/partest/scala/tools/partest/nest/Spec.scala index 25b91c84e891..65a892bad758 100644 --- a/src/partest/scala/tools/partest/nest/Spec.scala +++ b/src/partest/scala/tools/partest/nest/Spec.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/Stopwatch.scala b/src/partest/scala/tools/partest/nest/Stopwatch.scala index 9112cc7da9ac..0e8d656fe23d 100644 --- a/src/partest/scala/tools/partest/nest/Stopwatch.scala +++ b/src/partest/scala/tools/partest/nest/Stopwatch.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/StreamCapture.scala b/src/partest/scala/tools/partest/nest/StreamCapture.scala index 893f45cf4248..b1ac81d19f24 100644 --- a/src/partest/scala/tools/partest/nest/StreamCapture.scala +++ b/src/partest/scala/tools/partest/nest/StreamCapture.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -61,7 +61,8 @@ object StreamCapture { extra.foreach { case (k, v) => modified.setProperty(k, v) } // Trying to avoid other threads seeing the new properties object prior to the new entries // https://github.com/scala/scala/pull/6391#issuecomment-371346171 - UnsafeAccess.U.storeFence() + // (JDK 22 deprecates `storeFence`; once we drop JDK 8 we can use the VarHandles one instead) + UnsafeAccess.U.storeFence(): @annotation.nowarn("cat=deprecation") System.setProperties(modified) try { action diff --git a/src/partest/scala/tools/partest/nest/TrapExit.scala b/src/partest/scala/tools/partest/nest/TrapExit.scala deleted file mode 100644 index f5f00dc21859..000000000000 --- a/src/partest/scala/tools/partest/nest/TrapExit.scala +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Scala (https://www.scala-lang.org) - * - * Copyright EPFL and Lightbend, Inc. - * - * Licensed under Apache License 2.0 - * (http://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package scala.tools.partest.nest - -@deprecated("JDK 17 deprecates SecurityManager", since="2.13.7") -object TrapExit { - - private class TrapExitThrowable(val status: Int) extends Throwable { - override def getMessage: String = throw this - override def getCause: Throwable = throw this - } - - def apply[A](action: () => A): Either[(Int, Throwable), A] = { - val saved = System.getSecurityManager - System.setSecurityManager(new DelegatingSecurityManager(saved) { - override def checkExit(status: Int): Unit = throw new TrapExitThrowable(status) - }) - try { - Right(action()) - } catch { - case te: TrapExitThrowable => - Left((te.status, te)) - } finally { - System.setSecurityManager(saved) - } - } -} diff --git a/src/partest/scala/tools/partest/nest/UnsafeAccess.java b/src/partest/scala/tools/partest/nest/UnsafeAccess.java index b28060d4f1d3..fd6958f26816 100644 --- a/src/partest/scala/tools/partest/nest/UnsafeAccess.java +++ b/src/partest/scala/tools/partest/nest/UnsafeAccess.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/nest/package.scala b/src/partest/scala/tools/partest/nest/package.scala index 4cf38946b13b..38a87b0c9398 100644 --- a/src/partest/scala/tools/partest/nest/package.scala +++ b/src/partest/scala/tools/partest/nest/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala index 1f949bc8e303..8130d836c70d 100644 --- a/src/partest/scala/tools/partest/package.scala +++ b/src/partest/scala/tools/partest/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/sbt/Framework.scala b/src/partest/scala/tools/partest/sbt/Framework.scala index 2d3f92eac495..e1f644f25b8c 100644 --- a/src/partest/scala/tools/partest/sbt/Framework.scala +++ b/src/partest/scala/tools/partest/sbt/Framework.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/sbt/SBTRunner.scala b/src/partest/scala/tools/partest/sbt/SBTRunner.scala index 891c51acf88d..be475660cfb7 100644 --- a/src/partest/scala/tools/partest/sbt/SBTRunner.scala +++ b/src/partest/scala/tools/partest/sbt/SBTRunner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/partest/scala/tools/partest/utils/Properties.scala b/src/partest/scala/tools/partest/utils/Properties.scala index 86fc6ec81963..674d427821bb 100644 --- a/src/partest/scala/tools/partest/utils/Properties.scala +++ b/src/partest/scala/tools/partest/utils/Properties.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,5 +17,5 @@ package utils object Properties extends scala.util.PropertiesTrait { protected def propCategory = "scala-partest" protected def pickJarBasedOn = classOf[nest.Runner] - override def isAvian = super.isAvian + override lazy val isAvian = javaVmName.contains("Avian") } diff --git a/src/reflect/scala/reflect/api/Annotations.scala b/src/reflect/scala/reflect/api/Annotations.scala index a38f9964790a..d25357b12a88 100644 --- a/src/reflect/scala/reflect/api/Annotations.scala +++ b/src/reflect/scala/reflect/api/Annotations.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -91,6 +91,20 @@ trait Annotations { self: Universe => @deprecated("use `tree.children.tail` instead", "2.11.0") def scalaArgs: List[Tree] + /** For arguments in [[scalaArgs]], this method returns `true` if the argument AST is a default inserted + * by the compiler, not an explicit argument passed in source code. + * + * Since Scala 2.13.17, the defaults are ASTs of the default expression in the annotation definition. + * Example: + * {{{ + * class ann(x: Int = 42) extends Annotation + * @ann class C + * }}} + * The `annotation.scalaArgs.head` is an AST `Literal(Constant(42))` for which the `argIsDefault` method + * returns `true`. + */ + def argIsDefault(tree: Tree): Boolean + /** Payload of the Java annotation: a list of name-value pairs. * Empty for Scala annotations. */ diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala index 8a6f5f31d075..d35b3a0eaeec 100644 --- a/src/reflect/scala/reflect/api/Constants.scala +++ b/src/reflect/scala/reflect/api/Constants.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala index bc3781412bab..7fae461b1304 100644 --- a/src/reflect/scala/reflect/api/Exprs.scala +++ b/src/reflect/scala/reflect/api/Exprs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala index 8b9955d83aa6..04fe62ef9d35 100644 --- a/src/reflect/scala/reflect/api/FlagSets.scala +++ b/src/reflect/scala/reflect/api/FlagSets.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala index 64aad07bbdff..ad836bbda039 100644 --- a/src/reflect/scala/reflect/api/ImplicitTags.scala +++ b/src/reflect/scala/reflect/api/ImplicitTags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala index 3e2f5f4fe736..21681be868e5 100644 --- a/src/reflect/scala/reflect/api/Internals.scala +++ b/src/reflect/scala/reflect/api/Internals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala index 3c1752c7c934..f5c042f88786 100644 --- a/src/reflect/scala/reflect/api/JavaUniverse.scala +++ b/src/reflect/scala/reflect/api/JavaUniverse.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Liftables.scala b/src/reflect/scala/reflect/api/Liftables.scala index 86770004c533..65cb99c9ff7d 100644 --- a/src/reflect/scala/reflect/api/Liftables.scala +++ b/src/reflect/scala/reflect/api/Liftables.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala index 07959be002cb..6cd554f3d38d 100644 --- a/src/reflect/scala/reflect/api/Mirror.scala +++ b/src/reflect/scala/reflect/api/Mirror.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala index e955f1a07a65..ee373c5fa463 100644 --- a/src/reflect/scala/reflect/api/Mirrors.scala +++ b/src/reflect/scala/reflect/api/Mirrors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala index a9082b8b6cb3..bee0d6f28ffe 100644 --- a/src/reflect/scala/reflect/api/Names.scala +++ b/src/reflect/scala/reflect/api/Names.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Position.scala b/src/reflect/scala/reflect/api/Position.scala index 63778624226e..7f2960de1c4e 100644 --- a/src/reflect/scala/reflect/api/Position.scala +++ b/src/reflect/scala/reflect/api/Position.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala index c224f644401e..d19b12874950 100644 --- a/src/reflect/scala/reflect/api/Positions.scala +++ b/src/reflect/scala/reflect/api/Positions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala index fef8321b6a3f..e0df010c7ae5 100644 --- a/src/reflect/scala/reflect/api/Printers.scala +++ b/src/reflect/scala/reflect/api/Printers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala index 9a31a80032ce..d5acff1fdfe8 100644 --- a/src/reflect/scala/reflect/api/Quasiquotes.scala +++ b/src/reflect/scala/reflect/api/Quasiquotes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Scopes.scala b/src/reflect/scala/reflect/api/Scopes.scala index 2bf5b82fa7ac..e1ea67c19166 100644 --- a/src/reflect/scala/reflect/api/Scopes.scala +++ b/src/reflect/scala/reflect/api/Scopes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/StandardDefinitions.scala b/src/reflect/scala/reflect/api/StandardDefinitions.scala index 8ba689fdb46c..8451dbed7015 100644 --- a/src/reflect/scala/reflect/api/StandardDefinitions.scala +++ b/src/reflect/scala/reflect/api/StandardDefinitions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala index 1b4a1a9f5eb8..fdc83ef0f970 100644 --- a/src/reflect/scala/reflect/api/StandardLiftables.scala +++ b/src/reflect/scala/reflect/api/StandardLiftables.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala index 8c3a7507bc82..21931cb3c600 100644 --- a/src/reflect/scala/reflect/api/StandardNames.scala +++ b/src/reflect/scala/reflect/api/StandardNames.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 37d44794575c..5f48540e21ce 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -442,7 +442,9 @@ trait Symbols { self: Universe => def privateWithin: Symbol /** Does this symbol represent the definition of a package? - * Known issues: [[https://github.com/scala/bug/issues/6732]]. + * + * True for term symbols that are packages and for type symbols + * for which `isPackageClass` is true. * * @group Tests */ diff --git a/src/reflect/scala/reflect/api/TreeCreator.scala b/src/reflect/scala/reflect/api/TreeCreator.scala index 056e1c8bcbcd..8777d8f60956 100644 --- a/src/reflect/scala/reflect/api/TreeCreator.scala +++ b/src/reflect/scala/reflect/api/TreeCreator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index ecf77531b5ba..0a2ff1318e83 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/TypeCreator.scala b/src/reflect/scala/reflect/api/TypeCreator.scala index 8718d6a285e5..7514d879d541 100644 --- a/src/reflect/scala/reflect/api/TypeCreator.scala +++ b/src/reflect/scala/reflect/api/TypeCreator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala index 7dba64a079e7..45ee8ef70715 100644 --- a/src/reflect/scala/reflect/api/TypeTags.scala +++ b/src/reflect/scala/reflect/api/TypeTags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index d59241927674..a01926c08d42 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala index 072f01185d0c..aa3ead9037e9 100644 --- a/src/reflect/scala/reflect/api/Universe.scala +++ b/src/reflect/scala/reflect/api/Universe.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala index ee0040100809..e9d36dac83b7 100644 --- a/src/reflect/scala/reflect/api/package.scala +++ b/src/reflect/scala/reflect/api/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala index fd5222e397b7..70c5eb87e336 100644 --- a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala +++ b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index adf747a858ca..53d26444db25 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -181,27 +181,142 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => override def symbol: Symbol = if (forced) super.symbol else typeSymbol } - /** Typed information about an annotation. It can be attached to either - * a symbol or an annotated type. + /** + * Typed information about an annotation. It can be attached to either a symbol or an annotated type. + * + * `atp` is the type of the annotation class, the `symbol` method returns its [[Symbol]]. * - * Annotations are written to the classfile as Java annotations - * if `atp` conforms to `ClassfileAnnotation` (the classfile parser adds - * this interface to any Java annotation class). + * If `atp` conforms to `ConstantAnnotation` (which is true for annotations defined in Java), the annotation + * arguments are compile-time constants represented in `assocs`. Note that default arguments are *not* present + * in `assocs`. The `assocsWithDefaults` extends `assocs` with the default values from the annotation definition. + * Example: `class a(x: Int = 1) extends ConstantAnnotation`.F or `@ann()` without arguments `assocsWithDefaults` + * contains `x -> 1`. * - * Annotations are pickled (written to scala symtab attribute in the - * classfile) if `atp` inherits form `StaticAnnotation`. + * If `atp` is not a `ConstantAnnotation`, the annotation arguments are represented as type trees in `args`. + * These trees are not transformed by any phases following the type-checker. + * Note that default arguments are inserted into the `args` list. Example: `class a(x: Int = 1) extends Annotation`. + * For `@ann()` without arguments, `args` is `List(1)`. + * The `argIsDefault` method tells if an annotation argument is explicit or a default inserted by the compiler. * - * `args` stores arguments to Scala annotations, represented as typed - * trees. Note that these trees are not transformed by any phases - * following the type-checker. + * Annotations are written to the classfile as Java annotations if `atp` conforms to `ClassfileAnnotation` + * (the classfile parser adds this interface to any Java annotation class). * - * `assocs` stores arguments to classfile annotations as name-value pairs. + * Annotations are pickled (written to scala symtab attribute in the classfile) if `atp` inherits from + * `StaticAnnotation`, such annotations are visible under separate compilation. */ abstract class AnnotationInfo extends AnnotationApi { def atp: Type def args: List[Tree] def assocs: List[(Name, ClassfileAnnotArg)] + /** See [[AnnotationInfo]] */ + def argIsDefault(arg: Tree): Boolean = arg match { + case NamedArg(_, a) => argIsDefault(a) + case treeInfo.Applied(fun, _, _) if fun.symbol != null && fun.symbol.isDefaultGetter => + // if the annotation class was compiled with an old compiler, parameters with defaults don't have a + // `@defaultArg` meta-annotation and the typer inserts a call to the default getter + true + case _ => + // When inserting defaults, the tpe of the argument tree is tagged with the `@defaultArg` annotation. + arg.tpe.hasAnnotation(DefaultArgAttr) + } + + /** See [[AnnotationInfo]]. Note: for Java-defined annotations, this method returns `Nil`. */ + def assocsWithDefaults: List[(Name, ClassfileAnnotArg)] = { + val explicit = assocs.toMap + // ConstantAnnotations cannot have auxiliary constructors, nor multiple parameter lists + val params = symbol.primaryConstructor.paramss.headOption.getOrElse(Nil) + params.flatMap(p => { + val arg = explicit.get(p.name).orElse( + p.getAnnotation(DefaultArgAttr).flatMap(_.args.headOption).collect { + case Literal(c) => LiteralAnnotArg(c) + }) + arg.map(p.name -> _) + }) + } + + /** + * The `assocs` of this annotation passed to the `parent` class. + * + * `parent` needs to be either the annotation class itself or its direct superclass. + * + * If `parent` is the superclass, this method returns the arguments passed at the annotation definition. + * + * Example:given `class nodep extends nowarn("cat=deprecation")`, the call `assocsForSuper(NowarnClassSymbol)` + * returns `List('value' -> "cat=deprecation")`. + */ + def assocsForSuper(parent: Symbol): List[(Name, ClassfileAnnotArg)] = + if (symbol == parent) assocs + else if (symbol.superClass == parent) { + val superConstArgs: Map[String, ClassfileAnnotArg] = symbol.annotations.filter(_.matches(SuperArgAttr)).flatMap(_.args match { + case List(Literal(param), Literal(value)) => Some(param.stringValue -> LiteralAnnotArg(value)) + case _ => None + }).toMap + parent.primaryConstructor.paramss.headOption.getOrElse(Nil).flatMap(p => superConstArgs.get(p.name.toString).map(p.name -> _)) + } else Nil + + + /** + * The `args` of this annotation passed to the `parent` class. + * + * `parent` needs to be either the annotation class itself or its direct superclass. + * + * If `parent` is the superclass, this method returns the arguments passed at the annotation definition. Forwarded + * arguments are supported. + * + * Example: + * + * {{{ + * class ann(x: Int = 1, y: Int = 2) extends Annotation + * class sub(z: Int) extends ann(y = z) + * @sub(3) def f = 1 + * }}} + * + * The call `argsForSuper(symbolOfAnn)` returns `List(1, 3)`. The argument `1` is the default used in the super + * call, the value `3` is a forwarded argument. + */ + def argsForSuper(parent: Symbol): List[Tree] = + if (symbol == parent) args + else if (symbol.superClass == parent) { + val subArgs = symbol.primaryConstructor.paramss.headOption.getOrElse(Nil).map(_.name.toString).zip(args).toMap + val superArgs: Map[String, Tree] = symbol.annotations.filter(_.matches(SuperArgAttr)).flatMap(_.args match { + case List(Literal(param), value) => Some(param.stringValue -> value) + case _ => None + }).toMap + val superFwdArgs: Map[String, String] = symbol.annotations.filter(_.matches(SuperFwdArgAttr)).flatMap(_.args match { + case List(Literal(param), Literal(subParam)) => Some(param.stringValue -> subParam.stringValue) + case _ => None + }).toMap + val params = parent.primaryConstructor.paramss.headOption.getOrElse(Nil) + val res = params.flatMap(p => { + val n = p.name.toString + superArgs.get(n).orElse(subArgs.get(superFwdArgs.getOrElse(n, ""))) + }) + if (params.lengthCompare(res) == 0) res else Nil + } else Nil + + /** + * Obtain the constructor symbol that was used for this annotation. + * If the annotation does not have secondary constructors, use `symbol.primaryConstructor` instead. + * + * To use this method in a compiler plugin, invoke it as follows: + * `val sym = annotationInfo.constructorSymbol(tree => global.exitingTyper(global.typer.typed(tree)))` + * + * Annotation arguments can be paired with the corresponding annotation parameters: + * `sym.paramss.head.zip(annotationInfo.args): List[(Symbol, Tree)]` + * + * Background: Before type checking, `@ann(x)` is represented as a tree `Apply(Select(New(ann), ), x)`. + * That tree is type checked as such and the resulting typed tree is used to build the `AnnotationInfo`. + * The information which constructor symbol was used is not represented in the `AnnoationInfo`. + * Adding it would be difficult because it affects the pickle format. + */ + def constructorSymbol(typer: Tree => Tree): Symbol = { + typer(New(atp, args: _*)) match { + case Apply(constr @ Select(New(_), nme.CONSTRUCTOR), _) => constr.symbol + case _ => atp.typeSymbol.primaryConstructor + } + } + def tpe = atp def scalaArgs = args def javaArgs = ListMap(assocs: _*) diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala index 5d4a4e8baae2..d36d085830d0 100644 --- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/CapturedVariables.scala b/src/reflect/scala/reflect/internal/CapturedVariables.scala index 42734006fa68..66869a75eec3 100644 --- a/src/reflect/scala/reflect/internal/CapturedVariables.scala +++ b/src/reflect/scala/reflect/internal/CapturedVariables.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Chars.scala b/src/reflect/scala/reflect/internal/Chars.scala index d0a12baa7ea4..311b176bf04b 100644 --- a/src/reflect/scala/reflect/internal/Chars.scala +++ b/src/reflect/scala/reflect/internal/Chars.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala index 27db077f5c57..12709fbc34b1 100644 --- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala +++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Constants.scala b/src/reflect/scala/reflect/internal/Constants.scala index d834d806989b..1e95a1b15f87 100644 --- a/src/reflect/scala/reflect/internal/Constants.scala +++ b/src/reflect/scala/reflect/internal/Constants.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -233,23 +233,63 @@ trait Constants extends api.Constants { else if (tag == ClazzTag) signature(typeValue) else value.toString() - def escapedChar(ch: Char): String = (ch: @switch) match { - case '\b' => "\\b" - case '\t' => "\\t" - case '\n' => "\\n" - case '\f' => "\\f" - case '\r' => "\\r" - case '"' => "\\\"" - case '\'' => "\\\'" - case '\\' => "\\\\" - case _ => if (ch.isControl) "\\u%04X".format(ch.toInt) else String.valueOf(ch) - } - def escapedStringValue: String = { - def escape(text: String): String = text flatMap escapedChar + import java.lang.StringBuilder + def requiresFormat(c: Char): Boolean = + (c: @switch) match { + case '\b' | '\t' | '\n' | '\f' | '\r' | '"' | '\'' | '\\' => true + case c => c.isControl + } + def escapedChar(b: StringBuilder, c: Char): Unit = { + def quadNibble(b: StringBuilder, x: Int, i: Int): Unit = + if (i < 4) { + quadNibble(b, x >> 4, i + 1) + val n = x & 0xF + val c = if (n < 10) '0' + n else 'A' + (n - 10) + b.append(c.toChar) + } + val replace = (c: @switch) match { + case '\b' => "\\b" + case '\t' => "\\t" + case '\n' => "\\n" + case '\f' => "\\f" + case '\r' => "\\r" + case '"' => "\\\"" + case '\'' => "\\\'" + case '\\' => "\\\\" + case c => + if (c.isControl) { + b.append("\\u") + quadNibble(b, c.toInt, 0) + } + else b.append(c) + return + } + b.append(replace) + } + def escape(text: String) = { + def mustBuild: Boolean = { + var i = 0 + while (i < text.length) { + if (requiresFormat(text.charAt(i))) return true + i += 1 + } + false + } + if (mustBuild) { + val b = new StringBuilder(text.length + 16).append('"') + var i = 0 + while (i < text.length) { + escapedChar(b, text.charAt(i)) + i += 1 + } + b.append('"').toString + } + else "\"" + text + "\"" + } tag match { case NullTag => "null" - case StringTag => "\"" + escape(stringValue) + "\"" + case StringTag => escape(stringValue) case ClazzTag => def show(tpe: Type) = "classOf[" + signature(tpe) + "]" typeValue match { @@ -264,7 +304,14 @@ trait Constants extends api.Constants { show(clazz.tpe_*) case _ => show(typeValue) } - case CharTag => "'" + escapedChar(charValue) + "'" + case CharTag => + val c = charValue + if (requiresFormat(c)) { + val b = new StringBuilder().append('\'') + escapedChar(b, c) + b.append('\'').toString + } + else "'" + c + "'" case LongTag => longValue.toString() + "L" case EnumTag => symbolValue.name.toString() case _ => String.valueOf(value) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 5be1e6a9ea1a..5ed8fa9b4bcc 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -401,6 +401,7 @@ trait Definitions extends api.StandardDefinitions { lazy val SpecializableModule = requiredModule[Specializable] lazy val ScalaRunTimeModule = requiredModule[scala.runtime.ScalaRunTime.type] + lazy val MurmurHash3Module = requiredModule[scala.util.hashing.MurmurHash3.type] lazy val SymbolModule = requiredModule[scala.Symbol.type] def Symbol_apply = getMemberMethod(SymbolModule, nme.apply) @@ -1342,6 +1343,7 @@ trait Definitions extends api.StandardDefinitions { lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty] lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty] lazy val CompileTimeOnlyAttr = getClassIfDefined("scala.annotation.compileTimeOnly") + lazy val DefaultArgAttr = getClassIfDefined("scala.annotation.meta.defaultArg") lazy val DeprecatedAttr = requiredClass[scala.deprecated] lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName] lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance] @@ -1352,6 +1354,8 @@ trait Definitions extends api.StandardDefinitions { lazy val SerialVersionUIDAttr = requiredClass[scala.SerialVersionUID] lazy val SerialVersionUIDAnnotation = AnnotationInfo(SerialVersionUIDAttr.tpe, List(), List(nme.value -> LiteralAnnotArg(Constant(0)))) lazy val SpecializedClass = requiredClass[scala.specialized] + lazy val SuperArgAttr = getClassIfDefined("scala.annotation.meta.superArg") + lazy val SuperFwdArgAttr = getClassIfDefined("scala.annotation.meta.superFwdArg") lazy val ThrowsClass = requiredClass[scala.throws[_]] lazy val TransientAttr = requiredClass[scala.transient] lazy val UncheckedClass = requiredClass[scala.unchecked] diff --git a/src/reflect/scala/reflect/internal/Depth.scala b/src/reflect/scala/reflect/internal/Depth.scala index 54b293af2f1a..0eb6cad3cf0d 100644 --- a/src/reflect/scala/reflect/internal/Depth.scala +++ b/src/reflect/scala/reflect/internal/Depth.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala index 1ca9a030adbf..722a08bd71b4 100644 --- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala +++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/FatalError.scala b/src/reflect/scala/reflect/internal/FatalError.scala index 759acd116f37..a39b64f839ba 100644 --- a/src/reflect/scala/reflect/internal/FatalError.scala +++ b/src/reflect/scala/reflect/internal/FatalError.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala index ceb592da4cbc..c1fd55ba419f 100644 --- a/src/reflect/scala/reflect/internal/FlagSets.scala +++ b/src/reflect/scala/reflect/internal/FlagSets.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala index e4402f377f43..7a88d2781de3 100644 --- a/src/reflect/scala/reflect/internal/Flags.scala +++ b/src/reflect/scala/reflect/internal/Flags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -373,7 +373,7 @@ class Flags extends ModifierFlags { private final val MODULE_PKL = (1L << 10) private final val INTERFACE_PKL = (1L << 11) - private final val PKL_MASK = 0x00000FFF + //private final val PKL_MASK = 0x00000FFF /** Pickler correspondence, ordered roughly by frequency of occurrence */ private def rawPickledCorrespondence = Array[(Long, Long)]( diff --git a/src/reflect/scala/reflect/internal/FreshNames.scala b/src/reflect/scala/reflect/internal/FreshNames.scala index e59c7781b8d0..948c99184056 100644 --- a/src/reflect/scala/reflect/internal/FreshNames.scala +++ b/src/reflect/scala/reflect/internal/FreshNames.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 587aecc140bf..c9e0abb855a5 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -121,8 +121,6 @@ trait HasFlags { def isOverride = hasFlag(OVERRIDE) def isParamAccessor = hasFlag(PARAMACCESSOR) def isPrivate = hasFlag(PRIVATE) - @deprecated ("use `hasPackageFlag` instead", "2.11.0") - def isPackage = hasFlag(PACKAGE) def isPrivateLocal = hasAllFlags(PrivateLocal) def isProtected = hasFlag(PROTECTED) def isProtectedLocal = hasAllFlags(ProtectedLocal) diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index e54a7069cbbc..37c18f74cecf 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/InfoTransformers.scala b/src/reflect/scala/reflect/internal/InfoTransformers.scala index ed568eaaa42c..85a8eea82b05 100644 --- a/src/reflect/scala/reflect/internal/InfoTransformers.scala +++ b/src/reflect/scala/reflect/internal/InfoTransformers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -38,7 +38,7 @@ trait InfoTransformers { } else if (next.pid <= that.pid && next.pid != NoPhase.id) { next insert that } else { - log("Inserting info transformer %s following %s".format(phaseOf(that.pid), phaseOf(this.pid))) + log(s"Inserting info transformer ${phaseOf(that.pid)} following ${phaseOf(this.pid)}") that.next = next that.prev = this next.prev = that diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala index c08fdd512d6f..af9fd3468935 100644 --- a/src/reflect/scala/reflect/internal/Internals.scala +++ b/src/reflect/scala/reflect/internal/Internals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/JDK9Reflectors.java b/src/reflect/scala/reflect/internal/JDK9Reflectors.java index e0deddf114a7..483e494af7b0 100644 --- a/src/reflect/scala/reflect/internal/JDK9Reflectors.java +++ b/src/reflect/scala/reflect/internal/JDK9Reflectors.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala b/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala index 94fd5b8b7702..79813ee0fec6 100644 --- a/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala +++ b/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/JavaAccFlags.scala b/src/reflect/scala/reflect/internal/JavaAccFlags.scala index 8b07833c213c..726dd4bf329d 100644 --- a/src/reflect/scala/reflect/internal/JavaAccFlags.scala +++ b/src/reflect/scala/reflect/internal/JavaAccFlags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Kinds.scala b/src/reflect/scala/reflect/internal/Kinds.scala index 620038fef482..31e15b16321b 100644 --- a/src/reflect/scala/reflect/internal/Kinds.scala +++ b/src/reflect/scala/reflect/internal/Kinds.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index fecc60ba014a..eceb7b9a77f2 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/MissingRequirementError.scala b/src/reflect/scala/reflect/internal/MissingRequirementError.scala index b31cfc41eed7..91b2abcfaed0 100644 --- a/src/reflect/scala/reflect/internal/MissingRequirementError.scala +++ b/src/reflect/scala/reflect/internal/MissingRequirementError.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Mode.scala b/src/reflect/scala/reflect/internal/Mode.scala index b1206f07e94e..288a488bd99a 100644 --- a/src/reflect/scala/reflect/internal/Mode.scala +++ b/src/reflect/scala/reflect/internal/Mode.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -89,8 +89,20 @@ object Mode { */ final val APPSELmode: Mode = Mode(0x20000) + /** + * Enabled while typing annotations. In this mode, no locals are created for named / default arguments and default + * arguments are AST copies of the default expression. Example: + * + * {{{ + * class a(x: Int = xDefault, y: Int) extends Annotation + * @a(y = yExpr) def f = 0 // annotation is typed as `new a(xDefault, yExpr)` + * new a(y = yExpr) // typed as `{ val x$1 = yExpr; val x$2 = a.init$default$1(); new a(x$2, x$1) }` + * }}} + */ + final val ANNOTmode: Mode = Mode(0x40000) + private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode - private val StickyModesForFun: Mode = StickyModes | SCCmode + private val StickyModesForFun: Mode = StickyModes | SCCmode | ANNOTmode final val MonoQualifierModes: Mode = EXPRmode | QUALmode | APPSELmode final val PolyQualifierModes: Mode = MonoQualifierModes | POLYmode final val OperatorModes: Mode = EXPRmode | POLYmode | TAPPmode | FUNmode @@ -108,7 +120,8 @@ object Mode { LHSmode -> "LHSmode", BYVALmode -> "BYVALmode", TYPEPATmode -> "TYPEPATmode", - APPSELmode -> "APPSELmode" + APPSELmode -> "APPSELmode", + ANNOTmode -> "ANNOTmode", ) // Former modes and their values: diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 4f290d9c2961..2f6c8e01d166 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Phase.scala b/src/reflect/scala/reflect/internal/Phase.scala index 11f8c0fa82f2..50229277af54 100644 --- a/src/reflect/scala/reflect/internal/Phase.scala +++ b/src/reflect/scala/reflect/internal/Phase.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala index 1d45e38783d1..28a456207cc1 100644 --- a/src/reflect/scala/reflect/internal/Positions.scala +++ b/src/reflect/scala/reflect/internal/Positions.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -44,25 +44,26 @@ trait Positions extends api.Positions { self: SymbolTable => * The point of the wrapping position is the point of the default position. * If some of the trees are ranges, returns a range position enclosing all ranges * Otherwise returns default position that is either focused or not. + * If the default point falls outside the calculated range, widen the result to include it. */ def wrappingPos(default: Position, trees: List[Tree]): Position = wrappingPos(default, trees, focus = true) - def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = { - if (useOffsetPositions) default else { - val accum = new WrappingPosAccumulator() - var rest = trees - while (rest ne Nil) { - val head = rest.head - rest = rest.tail - // TODO: a tree's range position should cover the positions of all trees it "includes" - // (inclusion mostly refers to subtrees, but also other attributes reached through the tree, such as its annotations/modifiers); - // concretely, a MemberDef's position should cover its annotations (scala/bug#11060) - // Workaround, which explicitly includes annotations of traversed trees, can be removed when TODO above is resolved: - head match { case md: MemberDef => rest = md.mods.annotations ::: rest case _ => } + private def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = if (useOffsetPositions) default else { + // TODO: a tree's range position should cover the positions of all trees it "includes" + // (inclusion mostly refers to subtrees, but also other attributes reached through the tree, such as its annotations/modifiers); + // concretely, a MemberDef's position should cover its annotations (scala/bug#11060) + // Workaround, which explicitly includes annotations of traversed trees, can be removed when TODO above is resolved: + val accum = new WrappingPosAccumulator() + def loop(trees: List[Tree]): Position = trees match { + case head :: rest => accum(head) - } - accum.result(default, focus) + head match { + case md: MemberDef => loop(md.mods.annotations ::: rest) + case _ => loop(rest) + } + case _ => accum.result(default, focus) } + loop(trees) } private final class WrappingPosAccumulator extends (Tree => Boolean) { private[this] var min: Int = _ @@ -72,11 +73,19 @@ trait Positions extends api.Positions { self: SymbolTable => max = Int.MinValue } reset() - def result(default: Position, focus: Boolean): Position = { - if (min > max) - if (focus) default.focus else default //there are no ranges - else Position.range(default.source, min, default.pointOrElse(min), max) - } + def result(default: Position, focus: Boolean): Position = + if (min > max) // there are no ranges + if (focus) default.focus else default + else { + val point = default.pointOrElse(min) + if (point < min || point > max) { + val start = Math.min(min, point) + val end = Math.max(max, point) + Position.range(default.source, start = start, point = point, end = end) + } + else + Position.range(default.source, start = min, point = point, end = max) + } override def apply(v1: Tree): Boolean = { val pos = v1.pos if (pos.isRange) { @@ -88,8 +97,8 @@ trait Positions extends api.Positions { self: SymbolTable => } /** A position that wraps the non-empty set of trees. - * The point of the wrapping position is the point of the first trees' position. - * If some of the trees are non-synthetic, returns a range position enclosing the non-synthetic trees + * The point of the wrapping position is the point of the first tree's position. + * If some of the trees are non-synthetic, returns a range position enclosing the non-synthetic trees. * Otherwise returns a synthetic offset position to point. */ def wrappingPos(trees: List[Tree]): Position = { @@ -103,9 +112,8 @@ trait Positions extends api.Positions { self: SymbolTable => * shortening the range, assigning TransparentPositions * to some of the nodes in `tree` or focusing on the position. */ - def ensureNonOverlapping(tree: Tree, others: List[Tree]): Unit ={ ensureNonOverlapping(tree, others, focus = true) } - def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean): Unit = { - if (useOffsetPositions) return + def ensureNonOverlapping(tree: Tree, others: List[Tree]): Unit = ensureNonOverlapping(tree, others, focus = true) + def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean): Unit = if (!useOffsetPositions) { def isOverlapping(pos: Position) = pos.isRange && (others exists (pos overlaps _.pos)) @@ -125,51 +133,50 @@ trait Positions extends api.Positions { self: SymbolTable => if (useOffsetPositions) Position.offset(source, point) else Position.range(source, start, point, end) - abstract class ChildSolidDescendantsCollector extends Traverser { // don't traverse annotations override def traverseModifiers(mods: Modifiers): Unit = () override def traverse(tree: Tree): Unit = - if (tree ne EmptyTree) { + if (tree ne EmptyTree) if (tree.pos.isTransparent) super.traverse(tree) - else { - traverseSolidChild(tree) - } - } - def traverseSolidChild(t: Tree): Unit - def apply(t: Tree): Unit = super.traverse(t) - } + else traverseSolidChild(tree) - private[this] def reportTree(prefix: String, tree: Tree): Unit = { - val source = if (tree.pos.isDefined) tree.pos.source else "" - inform("== " + prefix + " tree [" + tree.id + "] of type " + tree.productPrefix + " at " + tree.pos.show + source) - inform("") - inform(treeStatus(tree)) - inform("") - } + def traverseSolidChild(t: Tree): Unit - private[this] def positionError(topTree: Tree, msg: String)(body: => Unit): Unit = { - inform("======= Position error\n" + msg) - body - inform("\nWhile validating #" + topTree.id) - inform(treeStatus(topTree)) - inform("\nChildren:") - topTree.children foreach (t => inform(" " + treeStatus(t, topTree))) - inform("=======") - throw new ValidateException(msg) + def apply(t: Tree): Unit = super.traverse(t) } - private[this] val posStartOrdering: Ordering[Tree] = new Ordering[Tree] { + private val posStartOrdering: Ordering[Tree] = new Ordering[Tree] { override def compare(x: Tree, y: Tree): Int = { - @inline def posOf(t: Tree): Int = { + def posOf(t: Tree): Int = { val pos = t.pos if (pos eq NoPosition) Int.MinValue else pos.start } Integer.compare(posOf(x), posOf(y)) } } + def validatePositions(tree: Tree): Unit = if (!useOffsetPositions) { + def reportTree(prefix: String, tree: Tree): Unit = { + val source = if (tree.pos.isDefined) tree.pos.source else "" + inform("== " + prefix + " tree [" + tree.id + "] of type " + tree.productPrefix + " at " + tree.pos.show + source) + inform("") + inform(treeStatus(tree)) + inform("") + } + + def positionError(topTree: Tree, msg: String)(body: => Unit): Unit = { + inform("======= Position error\n" + msg) + body + inform("\nWhile validating #" + topTree.id) + inform(treeStatus(topTree)) + inform("\nChildren:") + topTree.children foreach (t => inform(" " + treeStatus(t, topTree))) + inform("=======") + throw new ValidateException(msg) + } + object worker { val trace = settings.Yposdebug.value && settings.verbose.value val topTree = tree @@ -210,73 +217,70 @@ trait Positions extends api.Positions { self: SymbolTable => } } - def loop(tree: Tree, encltree: Tree): Unit = { - if (!tree.isEmpty && tree.canHaveAttrs) { - val treePos = tree.pos - if (trace) - inform("[%10s] %s".format("validate", treeStatus(tree, encltree))) - - if (!treePos.isDefined) - positionError(topTree, "Unpositioned tree #" + tree.id) { - inform("%15s %s".format("unpositioned", treeStatus(tree, encltree))) - inform("%15s %s".format("enclosing", treeStatus(encltree))) - encltree.children foreach (t => inform("%15s %s".format("sibling", treeStatus(t, encltree)))) - } + def loop(tree: Tree, encltree: Tree): Unit = if (!tree.isEmpty && tree.canHaveAttrs) { + val treePos = tree.pos + if (trace) + inform(f"[${"validate"}%10s] ${treeStatus(tree, encltree)}") - solidChildrenCollector(tree) - val numChildren = solidChildrenCollector.collectedSize + if (!treePos.isDefined) + positionError(topTree, s"Unpositioned tree #${tree.id}") { + inform("%15s %s".format("unpositioned", treeStatus(tree, encltree))) + inform("%15s %s".format("enclosing", treeStatus(encltree))) + encltree.children foreach (t => inform("%15s %s".format("sibling", treeStatus(t, encltree)))) + } - if (treePos.isRange) { - val enclPos = encltree.pos - if (!enclPos.isRange) - positionError(topTree, "Synthetic tree [" + encltree.id + "] contains nonsynthetic tree [" + tree.id + "]") { - reportTree("Enclosing", encltree) - reportTree("Enclosed", tree) - } - if (!(enclPos includes treePos)) - positionError(topTree, "Enclosing tree [" + encltree.id + "] does not include tree [" + tree.id + "]") { - reportTree("Enclosing", encltree) - reportTree("Enclosed", tree) - } + solidChildrenCollector(tree) + val numChildren = solidChildrenCollector.collectedSize - if (numChildren > 1) { - val childSolidDescendants = solidChildrenCollector.sortedArray - var t1 = childSolidDescendants(0) - var t1Pos = t1.pos - var i = 1 - while (i < numChildren) { - val t2 = childSolidDescendants(i) - val t2Pos = t2.pos - if (t1Pos.overlaps(t2Pos)) { - positionError(topTree, "Overlapping trees") { - reportTree("Ancestor", tree) - reportTree("First overlapping", t1) - reportTree("Second overlapping", t2) - } - } - //why only for range - if (t2Pos.isRange) { - t1 = t2 - t1Pos = t2Pos + if (treePos.isRange) { + val enclPos = encltree.pos + if (!enclPos.isRange) + positionError(topTree, "Synthetic tree [" + encltree.id + "] contains nonsynthetic tree [" + tree.id + "]") { + reportTree("Enclosing", encltree) + reportTree("Enclosed", tree) + } + if (!enclPos.includes(treePos)) + positionError(topTree, "Enclosing tree [" + encltree.id + "] does not include tree [" + tree.id + "]") { + reportTree("Enclosing", encltree) + reportTree("Enclosed", tree) + } + + if (numChildren > 1) { + val childSolidDescendants = solidChildrenCollector.sortedArray + var t1 = childSolidDescendants(0) + var t1Pos = t1.pos + var i = 1 + while (i < numChildren) { + val t2 = childSolidDescendants(i) + val t2Pos = t2.pos + if (t1Pos.overlaps(t2Pos)) { + positionError(topTree, "Overlapping trees") { + reportTree("Ancestor", tree) + reportTree("First overlapping", t1) + reportTree("Second overlapping", t2) } - i += 1 } + if (t2Pos.isRange) { // only ranges overlap, so check ranges pairwise + t1 = t2 + t1Pos = t2Pos + } + i += 1 } } - if (numChildren > 0) { - if (numChildren == 1) { - val first = solidChildrenCollector.child(0) - solidChildrenCollector.clear() - loop(first, tree) - } else { - val snap = solidChildrenCollector.borrowArray - var i = 0 - while (i < numChildren) { - loop(snap(i), tree) - i += 1 - } - solidChildrenCollector.spareArray(snap) + } + if (numChildren > 0) { + if (numChildren == 1) { + val first = solidChildrenCollector.child(0) + solidChildrenCollector.clear() + loop(first, tree) + } else { + val snap = solidChildrenCollector.borrowArray + var i = 0 + while (i < numChildren) { + loop(snap(i), tree) + i += 1 } + solidChildrenCollector.spareArray(snap) } } } @@ -305,7 +309,7 @@ trait Positions extends api.Positions { self: SymbolTable => def set(pos: Position, parent: Tree): Unit = { wrappingPosAccumulator.reset() this.pos = pos - try parent.foreachChild(this) + try parent.foreachChild(apply) finally { this.pos = null } @@ -313,7 +317,7 @@ trait Positions extends api.Positions { self: SymbolTable => def apply(tree: Tree): Boolean = { wrappingPosAccumulator.reset() if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { - tree.foreachChild(this) + tree.foreachChild(apply) tree.foreachChild(wrappingPosAccumulator) val wrappingPos = wrappingPosAccumulator.result(pos, focus = true) tree setPos wrappingPos @@ -396,23 +400,20 @@ trait Positions extends api.Positions { self: SymbolTable => /** Position a tree. * This means: Set position of a node and position all its unpositioned children. */ - def atPos[T <: Tree](pos: Position)(tree: T): T = { + def atPos[T <: Tree](pos: Position)(tree: T): tree.type = { if (useOffsetPositions || !pos.isOpaqueRange) { posAssigner.pos = pos posAssigner.traverse(tree) - tree } - else { - if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { - tree.setPos(pos) - tree.onlyChild match { - case EmptyTree => - setChildrenPos(pos, tree) - case only => - atPos(pos)(only) - } + else if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) { + tree.setPos(pos) + tree.onlyChild match { + case EmptyTree => + setChildrenPos(pos, tree) + case only => + atPos(pos)(only) } - tree } + tree } } diff --git a/src/reflect/scala/reflect/internal/Precedence.scala b/src/reflect/scala/reflect/internal/Precedence.scala index 0df567a7c3fa..c5e8d5432a3d 100644 --- a/src/reflect/scala/reflect/internal/Precedence.scala +++ b/src/reflect/scala/reflect/internal/Precedence.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 1ade076fde1e..3c46bd942237 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -31,7 +31,7 @@ trait Printers extends api.Printers { self: SymbolTable => def quotedName(name: Name, decode: Boolean): String = { val s = if (decode) name.decode else name.toString val term = name.toTermName - if (nme.keywords(term) && term != nme.USCOREkw) "`%s`" format s + if (nme.keywords(term) && term != nme.USCOREkw) s"`$s`" else s } def quotedName(name: Name): String = quotedName(name, decode = false) @@ -232,7 +232,7 @@ trait Printers extends api.Printers { self: SymbolTable => } protected def printValDef(tree: ValDef, resultName: => String)(printTypeSignature: => Unit)(printRhs: => Unit) = { - val ValDef(mods, name, tp, rhs) = tree + val ValDef(mods, _, _, _) = tree printAnnotations(tree) printModifiers(tree, mods) print(if (mods.isMutable) "var " else "val ", resultName) @@ -241,7 +241,7 @@ trait Printers extends api.Printers { self: SymbolTable => } protected def printDefDef(tree: DefDef, resultName: => String)(printTypeSignature: => Unit)(printRhs: => Unit) = { - val DefDef(mods, name, tparams, vparamss, tp, rhs) = tree + val DefDef(mods, _, tparams, vparamss, _, _) = tree printAnnotations(tree) printModifiers(tree, mods) print("def " + resultName) @@ -252,7 +252,7 @@ trait Printers extends api.Printers { self: SymbolTable => } protected def printTypeDef(tree: TypeDef, resultName: => String) = { - val TypeDef(mods, name, tparams, rhs) = tree + val TypeDef(mods, _, tparams, rhs) = tree if (mods hasFlag (PARAM | DEFERRED)) { printAnnotations(tree) printModifiers(tree, mods) @@ -268,13 +268,13 @@ trait Printers extends api.Printers { self: SymbolTable => } protected def printImport(tree: Import, resSelect: => String) = { - val Import(expr, selectors) = tree + val Import(_, selectors) = tree def selectorToString(s: ImportSelector): String = { def selectorName(n: Name): String = if (s.isWildcard) nme.WILDCARD.decoded else quotedName(n) - val from = selectorName(s.name) - if (s.isRename || s.isMask) from + "=>" + selectorName(s.rename) - else from + if (s.isGiven) s.rename.decoded + else if (s.isRename || s.isMask) s"${selectorName(s.name)}=>${selectorName(s.rename)}" + else selectorName(s.name) } print("import ", resSelect, ".") selectors match { @@ -291,17 +291,13 @@ trait Printers extends api.Printers { self: SymbolTable => protected def printCaseDef(tree: CaseDef) = { val CaseDef(pat, guard, body) = tree print("case ") - @tailrec def patConstr(pat: Tree): Tree = pat match { - case Apply(fn, args) => patConstr(fn) - case _ => pat - } - - print(pat); printOpt(" if ", guard) + print(pat) + printOpt(" if ", guard) print(" => ", body) } protected def printFunction(tree: Function)(printValueParams: => Unit) = { - val Function(vparams, body) = tree + val Function(_, body) = tree print("(") printValueParams print(" => ", body, ")") @@ -747,7 +743,6 @@ trait Printers extends api.Printers { self: SymbolTable => case _ => } printArgss(argss) - case _ => super.printTree(tree) } } @@ -828,7 +823,7 @@ trait Printers extends api.Printers { self: SymbolTable => case md @ ModuleDef(mods, name, impl) => printAnnotations(md) printModifiers(tree, mods) - val Template(parents, self, methods) = impl + val Template(parents, _, _) = impl val parWithoutAnyRef = removeDefaultClassesFromList(parents) print("object " + printedName(name), if (parWithoutAnyRef.nonEmpty) " extends " else "", impl) @@ -853,12 +848,12 @@ trait Printers extends api.Printers { self: SymbolTable => case LabelDef(name, params, rhs) => if (name.startsWith(nme.WHILE_PREFIX)) { - val If(cond, thenp, elsep) = rhs: @unchecked + val If(cond, thenp, _) = rhs: @unchecked print("while (", cond, ") ") - val Block(list, wh) = thenp: @unchecked + val Block(list, _) = thenp: @unchecked printColumn(list, "", ";", "") } else if (name.startsWith(nme.DO_WHILE_PREFIX)) { - val Block(bodyList, ifCond @ If(cond, thenp, elsep)) = rhs: @unchecked + val Block(bodyList, If(cond, _, _)) = rhs: @unchecked print("do ") printColumn(bodyList, "", ";", "") print(" while (", cond, ") ") diff --git a/src/reflect/scala/reflect/internal/PrivateWithin.scala b/src/reflect/scala/reflect/internal/PrivateWithin.scala index 50bf84588cd1..598c4a0c90bf 100644 --- a/src/reflect/scala/reflect/internal/PrivateWithin.scala +++ b/src/reflect/scala/reflect/internal/PrivateWithin.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala index caecff7da797..f480d229c266 100644 --- a/src/reflect/scala/reflect/internal/ReificationSupport.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Reporting.scala b/src/reflect/scala/reflect/internal/Reporting.scala index ebb31e712bc2..1c91a1177170 100644 --- a/src/reflect/scala/reflect/internal/Reporting.scala +++ b/src/reflect/scala/reflect/internal/Reporting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -122,8 +122,8 @@ abstract class Reporter { private def filteredInfo(pos: Position, msg: String, severity: Severity, actions: List[CodeAction]): Unit = { val f = filter(pos, msg, severity) - if (f <= 1) increment(severity) - if (f == 0) doReport(pos, msg, severity, actions) + if (f < Reporter.Suppress) increment(severity) + if (f == Reporter.Display) doReport(pos, msg, severity, actions) } def increment(severity: Severity): Unit = severity match { diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala index 74802ccdb5e1..74f757393913 100644 --- a/src/reflect/scala/reflect/internal/Scopes.scala +++ b/src/reflect/scala/reflect/internal/Scopes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index 6cee9a135dd4..fe9f22663010 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -160,7 +160,7 @@ trait StdAttachments { case object RootSelection extends PlainAttachment /** Marks a Typed tree with Unit tpt. */ - case object TypedExpectingUnitAttachment + case object TypedExpectingUnitAttachment extends PlainAttachment def explicitlyUnit(tree: Tree): Boolean = tree.hasAttachment[TypedExpectingUnitAttachment.type] /** For `val i = 42`, marks field as inferred so accessor (getter) can warn if implicit. */ @@ -176,4 +176,14 @@ trait StdAttachments { /** Not a named arg in an application. Used for suspicious literal booleans. */ case object UnnamedArg extends PlainAttachment + + /** Adapted under value discard at typer. */ + case object DiscardedValue extends PlainAttachment + /** Discarded pure expression observed at refchecks. */ + case object DiscardedExpr extends PlainAttachment + /** Anonymous parameter of `if (_)` may be inferred as Boolean. */ + case object BooleanParameterType extends PlainAttachment + + /** Force desugaring Match trees, don't emit switches. Attach to DefDef trees or their symbol. */ + case object ForceMatchDesugar extends PlainAttachment } diff --git a/src/reflect/scala/reflect/internal/StdCreators.scala b/src/reflect/scala/reflect/internal/StdCreators.scala index 789c9f0f9312..2ee80fd851ea 100644 --- a/src/reflect/scala/reflect/internal/StdCreators.scala +++ b/src/reflect/scala/reflect/internal/StdCreators.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 299889a2bdf8..9775fa7bcdc0 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -17,7 +17,7 @@ package internal import java.security.MessageDigest import Chars.isOperatorPart -import scala.annotation.{nowarn, switch} +import scala.annotation.switch import scala.collection.immutable import scala.io.Codec @@ -176,7 +176,6 @@ trait StdNames { // the early initializer. /** This should be the first trait in the linearization. */ // abstract class Keywords extends CommonNames { - @nowarn("cat=deprecation&msg=early initializers") abstract class Keywords extends { private[this] val kw = new KeywordSetBuilder @@ -421,6 +420,7 @@ trait StdNames { def isTraitSetterName(name: Name) = isSetterName(name) && (name containsName TRAIT_SETTER_SEPARATOR_STRING) def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME + def isFreshTermName(name: Name) = name.startsWith(FRESH_TERM_NAME_PREFIX) /** Is name a variable name? */ def isVariableName(name: Name): Boolean = { @@ -551,7 +551,12 @@ trait StdNames { case -1 => (name.toTermName, -1) case idx => (name.toTermName.take(idx), idx + DEFAULT_GETTER_STRING.length) } - if (i >= 0) (n, name.encoded.substring(i).toInt) else (n, -1) + if (i < 0) (n, -1) + else { + val j = name.indexOf('$', i) // f$default$7$extension + val idx = name.subSequence(i, if (j < 0) name.length else j) + (n, idx.toString.toInt) + } } def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">") @@ -769,6 +774,7 @@ trait StdNames { val copy: NameType = nameType("copy") val create: NameType = nameType("create") val currentMirror: NameType = nameType("currentMirror") + val curried: NameType = nameType("curried") val delayedInit: NameType = nameType("delayedInit") val delayedInitArg: NameType = nameType("delayedInit$body") val dollarScope: NameType = nameType("$scope") diff --git a/src/reflect/scala/reflect/internal/SymbolPairs.scala b/src/reflect/scala/reflect/internal/SymbolPairs.scala index 824fc1acb766..f0a6ed671039 100644 --- a/src/reflect/scala/reflect/internal/SymbolPairs.scala +++ b/src/reflect/scala/reflect/internal/SymbolPairs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index aa899afd4156..765a1dff4c8e 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -95,6 +95,8 @@ abstract class SymbolTable extends macros.Universe def settings: MutableSettings + def isSymbolLockTracingEnabled: Boolean = isDeveloper + /** Override with final implementation for inlining. */ def debuglog(msg: => String): Unit = if (settings.isDebug) log(msg) @@ -192,7 +194,6 @@ abstract class SymbolTable extends macros.Universe /** Dump each symbol to stdout after shutdown. */ final val traceSymbolActivity = System.getProperty("scalac.debug.syms") != null - @nowarn("cat=deprecation&msg=early initializers") object traceSymbols extends { val global: SymbolTable.this.type = SymbolTable.this } with util.TraceSymbolActivity @@ -460,7 +461,9 @@ abstract class SymbolTable extends macros.Universe def newSet[K]() = recordCache(mutable.HashSet.empty[K]) def newWeakSet[K <: AnyRef]() = recordCache(WeakHashSet.empty[K]) + @nowarn("cat=deprecation") def newAnyRefMap[K <: AnyRef, V]() = recordCache(mutable.AnyRefMap.empty[K, V]) + @nowarn("cat=deprecation") def newAnyRefMap[K <: AnyRef, V](default: K => V) = recordCache(mutable.AnyRefMap.withDefault[K, V](default)) /** diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 1c207a1d4394..57548f7b3ed5 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -18,12 +18,12 @@ package scala package reflect package internal -import scala.collection.immutable -import scala.collection.mutable.ListBuffer -import util.{ ReusableInstance, Statistics, shortClassOfInstance } -import Flags._ import scala.annotation.tailrec +import scala.collection.mutable.{ArrayBuffer, ListBuffer} import scala.reflect.io.{AbstractFile, NoAbstractFile} + +import util.{ReusableInstance, Statistics, shortClassOfInstance} +import Flags._ import Variance._ trait Symbols extends api.Symbols { self: SymbolTable => @@ -36,14 +36,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => protected def nextId() = { ids += 1; ids } /** Used to keep track of the recursion depth on locked symbols */ - private[this] var _recursionTable = immutable.Map.empty[Symbol, Int] + private[this] var _recursionTable = Map.empty[Symbol, Int] def recursionTable = _recursionTable - def recursionTable_=(value: immutable.Map[Symbol, Int]) = _recursionTable = value + def recursionTable_=(value: Map[Symbol, Int]) = _recursionTable = value private[this] var _lockedCount = 0 def lockedCount = this._lockedCount def lockedCount_=(i: Int) = _lockedCount = i + private[this] val _lockingTrace = ArrayBuffer.empty[Symbol] + private[this] val lockTracing: Boolean = self.isSymbolLockTracingEnabled @deprecated("Global existential IDs no longer used", "2.12.1") private[this] var existentialIds = 0 @@ -553,19 +555,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => // True if the symbol is unlocked. // True if the symbol is locked but still below the allowed recursion depth. // False otherwise - private[scala] def lockOK: Boolean = { - ((_rawflags & LOCKED) == 0L) || - ((settings.Yrecursion.value != 0) && - (recursionTable get this match { - case Some(n) => (n <= settings.Yrecursion.value) - case None => true })) - } + private[scala] def lockOK: Boolean = ( + (_rawflags & LOCKED) == 0L || { + val limit = settings.Yrecursion.value + limit != 0 && ( + recursionTable.get(this) match { + case Some(n) => n <= limit + case None => true + }) + } + ) // Lock a symbol, using the handler if the recursion depth becomes too great. private[scala] def lock(handler: => Unit): Boolean = { + if (lockTracing) _lockingTrace.addOne(this) if ((_rawflags & LOCKED) != 0L) { if (settings.Yrecursion.value != 0) { - recursionTable get this match { + recursionTable.get(this) match { case Some(n) => if (n > settings.Yrecursion.value) { handler @@ -578,7 +584,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => recursionTable += (this -> 1) true } - } else { handler; false } + } else { + handler + false + } } else { _rawflags |= LOCKED true @@ -586,13 +595,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => } // Unlock a symbol - private[scala] def unlock() = { + private[scala] def unlock(): Unit = if ((_rawflags & LOCKED) != 0L) { _rawflags &= ~LOCKED + if (lockTracing && !_lockingTrace.isEmpty) + _lockingTrace.remove(index = _lockingTrace.size - 1, count = 1) // dropRightInPlace(1) if (settings.Yrecursion.value != 0) recursionTable -= this } - } // ----- tests ---------------------------------------------------------------------- @@ -666,6 +676,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isLabel = false /** Package/package object tests */ + def isPackage = false def isPackageClass = false def isPackageObject = false def isPackageObjectClass = false @@ -1305,13 +1316,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def fullName(separator: Char): String = fullName(separator, "") private def fullName(separator: Char, suffix: CharSequence): String = { - var b: java.lang.StringBuffer = null + var b: StringBuilder = null def loop(size: Int, sym: Symbol): Unit = { val symName = sym.name val nSize = symName.length - (if (symName.endsWith(nme.LOCAL_SUFFIX_STRING)) 1 else 0) if (sym.isRoot || sym.isRootPackage || sym == NoSymbol || sym.owner.isEffectiveRoot) { val capacity = size + nSize - b = new java.lang.StringBuffer(capacity) + b = new StringBuilder(capacity) symName.appendTo(b, 0, nSize) } else { loop(size + nSize + 1, sym.effectiveOwner.enclClass) @@ -1319,7 +1330,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => symName.appendTo(b, 0, nSize) } } - loop(suffix.length(), this) + loop(suffix.length, this) b.append(suffix) b.toString } @@ -1553,9 +1564,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => if ((_rawflags & LOCKED) != 0L) { // rolled out once for performance lock { setInfo(ErrorType) - throw CyclicReference(this, tp) + val trace = + if (lockTracing) { + val t = _lockingTrace.toArray + _lockingTrace.clear() + t + } else CyclicReference.emptyTrace + throw CyclicReference(this, tp, trace) } } else { + if (lockTracing) _lockingTrace.addOne(this) _rawflags |= LOCKED } val current = phase @@ -1568,18 +1586,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => unlock() phase = current } - } else { - // In runtime reflection, there is only on phase, so don't mutate Global.phase which would lead to warnings - // of data races from when using TSAN to assess thread safety. - try { - tp.complete(this) - } finally { - unlock() - } } + else + // In runtime reflection, there is only one phase, so don't mutate Global.phase + // which would lead to warnings of data races from when using TSAN to assess thread safety. + try tp.complete(this) + finally unlock() } catch { case ex: CyclicReference => - devWarning("... hit cycle trying to complete " + this.fullLocationString) + devWarning(s"... hit cycle trying to complete $fullLocationString") throw ex } @@ -2136,8 +2151,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * argument in the first parameter list of the primary constructor. * The empty list for all other classes. * - * This list will be sorted to correspond to the declaration order - * in the constructor parameter + * This list will be sorted to correspond to the declaration order + * in the constructor parameter */ final def caseFieldAccessors: List[Symbol] = { // We can't rely on the ordering of the case field accessors within decls -- @@ -2148,22 +2163,26 @@ trait Symbols extends api.Symbols { self: SymbolTable => // // The slightly more principled approach of using the paramss of the // primary constructor leads to cycles in, for example, pos/t5084.scala. - val primaryNames = constrParamAccessors map (_.name.dropLocal) - def nameStartsWithOrigDollar(name: Name, prefix: Name) = - name.startsWith(prefix) && name.length > prefix.length + 1 && name.charAt(prefix.length) == '$' + val primaryNames = constrParamAccessors.map { p => + if (p.hasFlag(EXPANDEDNAME)) p.unexpandedName.dropLocal + else p.name.dropLocal + } - def rec(remaningAccessors: List[Symbol], foundAccessors: List[(Symbol, Int)], remainingNames: List[(Name, Int)]): List[Symbol] = { - remaningAccessors match { + def loop(remainingAccessors: List[Symbol], foundAccessors: List[(Symbol, Int)], remainingNames: List[(Name, Int)]): List[Symbol] = + remainingAccessors match { case Nil => foundAccessors.sortBy(_._2).map(_._1) - case acc :: tail => { - val i = remainingNames.collectFirst { case (name, i) if acc.name == name || nameStartsWithOrigDollar(acc.name, name) => i} - rec(tail, (acc, i.get) :: foundAccessors, remainingNames.filterNot { case (_, ii) => Some(ii) == i} ) - } + case acc :: remainingAccessors => + def nameStartsWithOrigDollar(name: Name, prefix: Name) = + name.startsWith(prefix) && name.length > prefix.length + 1 && name.charAt(prefix.length) == '$' + remainingNames.collectFirst { + case (name, i) if acc.name == name || nameStartsWithOrigDollar(acc.name, name) => i + } match { + case Some(i) => loop(remainingAccessors, (acc, i) :: foundAccessors, remainingNames.filter(_._2 != i)) + case x => throw new MatchError(x) + } } - } - - rec(caseFieldAccessorsUnsorted.sortBy(s => -s.name.length), Nil, primaryNames.zipWithIndex.sortBy{ case (n, _) => -n.length}) + loop(caseFieldAccessorsUnsorted.sortBy(-_.name.length), foundAccessors = Nil, primaryNames.zipWithIndex.sortBy(-_._1.length)) } private final def caseFieldAccessorsUnsorted: List[Symbol] = info.decls.toList.filter(_.isCaseAccessorMethod) @@ -2450,12 +2469,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * @param ofclazz is a subclass of this symbol's owner */ - final def overridingSymbol(ofclazz: Symbol): Symbol = ( - if (canMatchInheritedSymbols) - matchingSymbol(ofclazz, ofclazz.thisType) - else - NoSymbol - ) + final def overridingSymbol(ofclazz: Symbol): Symbol = + if (canMatchInheritedSymbols) matchingSymbol(ofclazz, ofclazz.thisType) else NoSymbol /** If false, this symbol cannot possibly participate in an override, * either as overrider or overridee. For internal use; you should consult @@ -2635,7 +2650,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => if ( (file eq NoAbstractFile) || { val path = file.path - path.endsWith(".class") || path.endsWith(".sig") + path.endsWith(".class") || path.endsWith(".sig") || path.endsWith(".tasty") }) null else file } @@ -2950,6 +2965,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isMixinConstructor = rawname == nme.MIXIN_CONSTRUCTOR override def isConstructor = isClassConstructor || isMixinConstructor + override def isPackage = hasFlag(PACKAGE) override def isPackageObject = isModule && (rawname == nme.PACKAGE) override def isExistentiallyBound = this hasFlag EXISTENTIAL @@ -3370,6 +3386,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isCaseClass = this hasFlag CASE override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR override def isModuleClass = this hasFlag MODULE + override def isPackage = hasFlag(PACKAGE) // i.e., isPackageClass override def isPackageClass = this hasFlag PACKAGE override def isTrait = this hasFlag TRAIT @@ -3835,10 +3852,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => else closestEnclMethod(from.owner) /** An exception for cyclic references of symbol definitions */ - case class CyclicReference(sym: Symbol, info: Type) - extends TypeError("illegal cyclic reference involving " + sym) { + case class CyclicReference(sym: Symbol, info: Type, trace: Array[Symbol] = CyclicReference.emptyTrace) + extends TypeError(s"illegal cyclic reference involving $sym") { if (settings.isDebug) printStackTrace() } + object CyclicReference { + val emptyTrace: Array[Symbol] = Array.empty[Symbol] + } /** A class for type histories */ private final case class TypeHistory protected (private var _validFrom: Period, private var _info: Type, private var _prev: TypeHistory) { diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 00daf416f6f4..d0e46d98de99 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,9 +15,10 @@ package reflect package internal import Flags._ -import util._ +import util.{FreshNameCreator, ListOfNil} import scala.annotation.tailrec import scala.collection.mutable.ListBuffer +import scala.util.chaining._ abstract class TreeGen { val global: SymbolTable @@ -423,11 +424,8 @@ abstract class TreeGen { if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit) vparamss1 = List() :: vparamss1 val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass - // this requires knowing which of the parents is a type macro and which is not - // and that's something that cannot be found out before typer - // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon) // this means that we don't know what will be the arguments of the super call - // therefore here we emit a dummy which gets populated when the template is named and typechecked + // here we emit a dummy which gets populated when the template is named and typechecked Some( atPos(wrappingPos(superPos, lvdefs ::: vparamss1.flatten).makeTransparent) ( DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), mkLiteralUnit)))) @@ -633,18 +631,18 @@ abstract class TreeGen { * 4. * * for (P <- G; E; ...) ... - * => + * ==> * for (P <- G.filter (P => E); ...) ... * * 5. For N < MaxTupleArity: * - * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...) + * for (P_1 <- G; P_2 = E_2; P_N = E_N; ...) * ==> * for (TupleN(P_1, P_2, ... P_N) <- * for (x_1 @ P_1 <- G) yield { * val x_2 @ P_2 = E_2 * ... - * val x_N & P_N = E_N + * val x_N @ P_N = E_N * TupleN(x_1, ..., x_N) * } ...) * @@ -666,13 +664,20 @@ abstract class TreeGen { * the limits given by pat and body. */ def makeClosure(pos: Position, pat: Tree, body: Tree): Tree = { - def wrapped = wrappingPos(List(pat, body)) - def splitpos = (if (pos != NoPosition) wrapped.withPoint(pos.point) else pos).makeTransparent + val splitpos = { + val wrapped = wrappingPos(List(pat, body)) + // ignore proposed point if not in range + val res = + if (pos != NoPosition && wrapped.start <= pos.point && pos.point < wrapped.end) wrapped.withPoint(pos.point) + else pos + res.makeTransparent + } matchVarPattern(pat) match { case Some((name, tpt)) => - Function( - List(atPos(pat.pos) { ValDef(Modifiers(PARAM), name.toTermName, tpt, EmptyTree) }), - body) setPos splitpos + val p = atPos(pat.pos) { + ValDef(Modifiers(PARAM), name.toTermName, tpt, EmptyTree) + }.tap(propagatePatVarDefAttachments(pat, _)) + Function(List(p), body).setPos(splitpos) case None => atPos(splitpos) { mkVisitor(List(CaseDef(pat, EmptyTree, body)), checkExhaustive = false) @@ -685,23 +690,28 @@ abstract class TreeGen { def makeCombination(pos: Position, meth: TermName, qual: Tree, pat: Tree, body: Tree): Tree = // ForAttachment on the method selection is used to differentiate // result of for desugaring from a regular method call - Apply(Select(qual, meth) setPos qual.pos updateAttachment ForAttachment, - List(makeClosure(pos, pat, body))) setPos pos + Apply(Select(qual, meth).setPos(qual.pos).updateAttachment(ForAttachment), + List(makeClosure(pos, pat, body))).setPos(pos) - /* If `pat` is not yet a `Bind` wrap it in one with a fresh name */ - def makeBind(pat: Tree): Tree = pat match { - case Bind(_, _) => pat - case _ => Bind(freshTermName(), pat) setPos pat.pos + /* If `pat` is not yet a `Bind` wrap it in one with a fresh name. + * If the fresh patvar is for tupling in the desugared expression, + * it receives the transparent position of the pattern, so it is never warned about. + * Otherwise, add NoWarnAttachment. + */ + def makeBind(pat: Tree): Bind = pat match { + case pat: Bind => pat + case _ => Bind(freshTermName(), pat).setPos(pat.pos) + .tap(bind => if (!bind.pos.isTransparent) bind.updateAttachment(NoWarnAttachment)) } /* A reference to the name bound in Bind `pat`. */ - def makeValue(pat: Tree): Tree = pat match { - case Bind(name, _) => Ident(name) setPos pat.pos.focus - case x => throw new MatchError(x) + def makeValue(pat: Bind): Ident = pat match { + case Bind(name, _) => Ident(name).setPos(pat.pos.focus) } - /* The position of the closure that starts with generator at position `genpos`. */ - def closurePos(genpos: Position) = + // The position of the closure that starts with generator at position `genpos`. + // This position is carried by ValFrom. + def closurePos(genpos: Position): Position = if (genpos == NoPosition) NoPosition else { val end = body.pos match { @@ -715,53 +725,72 @@ abstract class TreeGen { case (t @ ValFrom(pat, rhs)) :: Nil => makeCombination(closurePos(t.pos), mapName, rhs, pat, body) case (t @ ValFrom(pat, rhs)) :: (rest @ (ValFrom(_, _) :: _)) => - makeCombination(closurePos(t.pos), flatMapName, rhs, pat, - mkFor(rest, sugarBody)) + makeCombination(closurePos(t.pos), flatMapName, rhs, pat, body = mkFor(rest, sugarBody)) case (t @ ValFrom(pat, rhs)) :: Filter(test) :: rest => - mkFor(ValFrom(pat, makeCombination(rhs.pos union test.pos, nme.withFilter, rhs, pat.duplicate, test)).setPos(t.pos) :: rest, sugarBody) + mkFor(ValFrom(pat, makeCombination(rhs.pos | test.pos, nme.withFilter, rhs, pat.duplicate, test)).setPos(t.pos) :: rest, sugarBody) case (t @ ValFrom(pat, rhs)) :: rest => - val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile { ValEq.unapply(_).nonEmpty } + val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile(ValEq.unapply(_).nonEmpty) assert(!valeqs.isEmpty, "Missing ValEq") val rest1 = rest.drop(valeqs.length) val (pats, rhss) = valeqs.map(ValEq.unapply(_).get).unzip val defpat1 = makeBind(pat) - val defpats = pats map makeBind - val pdefs = defpats.lazyZip(rhss).flatMap(mkPatDef) - val ids = (defpat1 :: defpats) map makeValue + val defpats = pats.map(makeBind) + val pdefs = defpats.lazyZip(rhss).flatMap((p, r) => mkPatDef(Modifiers(0), p, r, r.pos, forFor = true)) + val tupled = { + val ids = (defpat1 :: defpats).map(makeValue) + atPos(wrappingPos(ids))(mkTuple(ids).updateAttachment(ForAttachment)) + } val rhs1 = mkFor( List(ValFrom(defpat1, rhs).setPos(t.pos)), - Yield(Block(pdefs, atPos(wrappingPos(ids)) { mkTuple(ids) }) setPos wrappingPos(pdefs))) - val allpats = (pat :: pats) map (_.duplicate) + Yield(Block(pdefs, tupled).setPos(wrappingPos(pdefs))) + ) + val untupled = { + val allpats = (pat :: pats).map(_.duplicate) + atPos(wrappingPos(allpats))(mkTuple(allpats).updateAttachment(ForAttachment)) + } val pos1 = if (t.pos == NoPosition) NoPosition else rangePos(t.pos.source, t.pos.start, t.pos.point, rhs1.pos.end) - val vfrom1 = ValFrom(atPos(wrappingPos(allpats)) { mkTuple(allpats) }, rhs1).setPos(pos1) + val vfrom1 = ValFrom(untupled, rhs1).setPos(pos1) mkFor(vfrom1 :: rest1, sugarBody) case _ => EmptyTree //may happen for erroneous input - } } - /** Create tree for pattern definition */ - def mkPatDef(pat: Tree, rhs: Tree)(implicit fresh: FreshNameCreator): List[ValDef] = - mkPatDef(Modifiers(0), pat, rhs) - + // Fresh terms are not warnable. Bindings written `x@_` may be deemed unwarnable. private def propagateNoWarnAttachment(from: Tree, to: ValDef): to.type = if (isPatVarWarnable && from.hasAttachment[NoWarnAttachment.type]) to.updateAttachment(NoWarnAttachment) else to - // Keep marker for `x@_`, add marker for `val C(x) = ???` to distinguish from ordinary `val x = ???`. + // Distinguish patvar in pattern `val C(x) = ???` from `val x = ???`. Also `for (P(x) <- G)`. private def propagatePatVarDefAttachments(from: Tree, to: ValDef): to.type = propagateNoWarnAttachment(from, to).updateAttachment(PatVarDefAttachment) + /** Create tree for pattern definition */ + def mkPatDef(pat: Tree, rhs: Tree)(implicit fresh: FreshNameCreator): List[ValDef] = + mkPatDef(Modifiers(0), pat, rhs, rhs.pos) + /** Create tree for pattern definition */ - def mkPatDef(mods: Modifiers, pat: Tree, rhs: Tree)(implicit fresh: FreshNameCreator): List[ValDef] = mkPatDef(mods, pat, rhs, rhs.pos)(fresh) - def mkPatDef(mods: Modifiers, pat: Tree, rhs: Tree, rhsPos: Position)(implicit fresh: FreshNameCreator): List[ValDef] = matchVarPattern(pat) match { + def mkPatDef(mods: Modifiers, pat: Tree, rhs: Tree)(implicit fresh: FreshNameCreator): List[ValDef] = mkPatDef(mods, pat, rhs, rhs.pos) + + def mkPatDef(mods: Modifiers, pat: Tree, rhs: Tree, rhsPos: Position)(implicit fresh: FreshNameCreator): List[ValDef] = mkPatDef(mods, pat, rhs, rhsPos, forFor = false) + + private def mkPatDef(mods: Modifiers, pat: Tree, rhs: Tree, rhsPos: Position, forFor: Boolean)(implicit fresh: FreshNameCreator): List[ValDef] = matchVarPattern(pat) match { case Some((name, tpt)) => - List(atPos(pat.pos union rhsPos) { - propagateNoWarnAttachment(pat, ValDef(mods, name.toTermName, tpt, rhs)) - }) + atPos(pat.pos | rhsPos) { + ValDef(mods, name.toTermName, tpt, rhs) + .tap { vd => + val namePos = pat match { + case id @ Ident(_) => id.pos + case Typed(id @ Ident(_), _) => id.pos + case pat => pat.pos + } + vd.updateAttachment(NamePos(namePos)) + if (forFor) propagatePatVarDefAttachments(pat, vd) + else propagateNoWarnAttachment(pat, vd) + } + } :: Nil case None => // in case there is exactly one variable x_1 in pattern @@ -787,42 +816,47 @@ abstract class TreeGen { case Typed(expr, tpt) if !expr.isInstanceOf[Ident] => val rhsTypedUnchecked = if (tpt.isEmpty) rhsUnchecked - else Typed(rhsUnchecked, tpt) setPos (rhsPos union tpt.pos) + else Typed(rhsUnchecked, tpt).setPos(rhsPos | tpt.pos) (expr, rhsTypedUnchecked) case ok => (ok, rhsUnchecked) } val vars = getVariables(pat1) - val matchExpr = atPos((pat1.pos union rhsPos).makeTransparent) { + val matchExpr = atPos((pat1.pos | rhsPos).makeTransparent) { Match( rhs1, List( atPos(pat1.pos) { - CaseDef(pat1, EmptyTree, mkTuple(vars map (_._1) map Ident.apply)) + val args = vars.map { + case (name, _, pos, _) => Ident(name).setPos(pos.makeTransparent) // cf makeValue + } + CaseDef(pat1, EmptyTree, mkTuple(args).updateAttachment(ForAttachment)) } )) } vars match { - case List((vname, tpt, pos, original)) => - List(atPos(pat.pos union pos union rhsPos) { - propagatePatVarDefAttachments(original, ValDef(mods, vname.toTermName, tpt, matchExpr)) - }) + case (vname, tpt, pos, original) :: Nil => + atPos(pat.pos | pos | rhsPos) { + ValDef(mods, vname.toTermName, tpt, matchExpr) + .updateAttachment(NamePos(pos)) + .tap(propagatePatVarDefAttachments(original, _)) + } :: Nil case _ => val tmp = freshTermName() - val firstDef = - atPos(matchExpr.pos) { - val v = ValDef(Modifiers(PrivateLocal | SYNTHETIC | ARTIFACT | (mods.flags & LAZY)), tmp, TypeTree(), matchExpr) - if (vars.isEmpty) { - v.updateAttachment(PatVarDefAttachment) // warn later if this introduces a Unit-valued field + val firstDef = atPos(matchExpr.pos) { + ValDef(Modifiers(PrivateLocal | SYNTHETIC | ARTIFACT | (mods.flags & LAZY)), tmp, TypeTree(), matchExpr) + .tap(vd => if (vars.isEmpty) { + vd.updateAttachment(PatVarDefAttachment) // warn later if this introduces a Unit-valued field if (mods.isImplicit) currentRun.reporting.deprecationWarning(matchExpr.pos, "Implicit pattern definition binds no variables", since="2.13", "", "") - } - v - } + }) + } var cnt = 0 val restDefs = for ((vname, tpt, pos, original) <- vars) yield atPos(pos) { cnt += 1 - propagatePatVarDefAttachments(original, ValDef(mods, vname.toTermName, tpt, Select(Ident(tmp), TermName("_" + cnt)))) + ValDef(mods, vname.toTermName, tpt, Select(Ident(tmp), TermName(s"_$cnt"))) + .updateAttachment(NamePos(pos)) + .tap(propagatePatVarDefAttachments(original, _)) } firstDef :: restDefs } @@ -830,24 +864,16 @@ abstract class TreeGen { /** Create tree for for-comprehension generator */ def mkGenerator(pos: Position, pat: Tree, valeq: Boolean, rhs: Tree)(implicit fresh: FreshNameCreator): Tree = { - val pat1 = patvarTransformerForFor.transform(pat) + val pat1 = patvarTransformer.transform(pat) if (valeq) ValEq(pat1, rhs).setPos(pos) else ValFrom(pat1, mkCheckIfRefutable(pat1, rhs)).setPos(pos) } - private def unwarnable(pat: Tree): Tree = { - pat foreach { - case b @ Bind(_, _) => b updateAttachment NoWarnAttachment - case _ => - } - pat - } - def mkCheckIfRefutable(pat: Tree, rhs: Tree)(implicit fresh: FreshNameCreator) = if (treeInfo.isVarPatternDeep(pat)) rhs else { val cases = List( - CaseDef(unwarnable(pat.duplicate), EmptyTree, Literal(Constant(true))), + CaseDef(pat.duplicate, EmptyTree, Literal(Constant(true))), CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))) ) val visitor = mkVisitor(cases, checkExhaustive = false, nme.CHECK_IF_REFUTABLE_STRING) @@ -883,34 +909,36 @@ abstract class TreeGen { * synthetic for all nodes that contain a variable position. */ class GetVarTraverser extends Traverser { - val buf = new ListBuffer[(Name, Tree, Position, Tree)] + val buf = ListBuffer.empty[(Name, Tree, Position, Bind)] def namePos(tree: Tree, name: Name): Position = if (!tree.pos.isRange || name.containsName(nme.raw.DOLLAR)) tree.pos.focus else { val start = tree.pos.start val end = start + name.decode.length - rangePos(tree.pos.source, start, start, end) + rangePos(tree.pos.source, start = start, point = start, end = end) // Bind should get NamePos in parser } override def traverse(tree: Tree): Unit = { - def seenName(name: Name) = buf exists (_._1 == name) - def add(name: Name, t: Tree) = if (!seenName(name)) buf += ((name, t, namePos(tree, name), tree)) + def add(name: Name, t: Tree, b: Bind) = { + val seenName = buf.exists(_._1 == name) + if (!seenName) buf.addOne((name, t, namePos(tree, name), b)) + } val bl = buf.length tree match { - case Bind(nme.WILDCARD, _) => + case Bind(nme.WILDCARD, _) => super.traverse(tree) - case Bind(name, Typed(tree1, tpt)) => + case tree @ Bind(name, Typed(tree1, tpt)) => val newTree = if (treeInfo.mayBeTypePat(tpt)) TypeTree() else tpt.duplicate - add(name, newTree) + add(name, newTree, tree) traverse(tree1) - case Bind(name, tree1) => + case tree @ Bind(name, tree1) => // can assume only name range as position, as otherwise might overlap // with binds embedded in pattern tree1 - add(name, TypeTree()) + add(name, TypeTree(), tree) traverse(tree1) case _ => @@ -934,19 +962,15 @@ abstract class TreeGen { * x becomes x @ _ * x: T becomes x @ (_: T) */ - class PatvarTransformer(forFor: Boolean) extends Transformer { + class PatvarTransformer extends Transformer { override def transform(tree: Tree): Tree = tree match { case Ident(name) if treeInfo.isVarPattern(tree) && name != nme.WILDCARD => atPos(tree.pos) { - val b = Bind(name, atPos(tree.pos.focus) (Ident(nme.WILDCARD))) - if (forFor && isPatVarWarnable) b updateAttachment NoWarnAttachment - else b + Bind(name, atPos(tree.pos.focus) { Ident(nme.WILDCARD) }) } case Typed(id @ Ident(name), tpt) if treeInfo.isVarPattern(id) && name != nme.WILDCARD => atPos(tree.pos.withPoint(id.pos.point)) { - Bind(name, atPos(tree.pos.withStart(tree.pos.point)) { - Typed(Ident(nme.WILDCARD), tpt) - }) + Bind(name, atPos(tree.pos.withStart(tree.pos.point)) { Typed(Ident(nme.WILDCARD), tpt) }) } case Apply(fn @ Apply(_, _), args) => treeCopy.Apply(tree, transform(fn), transformTrees(args)) @@ -970,10 +994,7 @@ abstract class TreeGen { def isVarDefWarnable: Boolean = false /** Not in for comprehensions, whether to warn unused pat vars depends on flag. */ - object patvarTransformer extends PatvarTransformer(forFor = false) - - /** Tag pat vars in for comprehensions. */ - object patvarTransformerForFor extends PatvarTransformer(forFor = true) + object patvarTransformer extends PatvarTransformer // annotate the expression with @unchecked def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) { diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 29d6dc28b7d2..74409540ba79 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -53,7 +53,7 @@ abstract class TreeInfo { case EmptyTree => true case Import(_, _) => true case TypeDef(_, _, _, _) => true - case DefDef(mods, _, _, _, _, __) => mods.isDeferred + case DefDef(mods, _, _, _, _, _) => mods.isDeferred case ValDef(mods, _, _, _) => mods.isDeferred case _ => false } @@ -360,7 +360,7 @@ abstract class TreeInfo { tree.tpe match { case ThisType(sym) => sym == receiver.symbol - case SingleType(p, sym) => + case SingleType(_, sym) => sym == receiver.symbol || argss.exists(_.exists(sym == _.symbol)) case _ => def checkSingle(sym: Symbol): Boolean = @@ -524,7 +524,7 @@ abstract class TreeInfo { case _ => false } case md: MemberDef => !md.mods.isSynthetic - case tree => true + case _ => true } def lazyValDefRhs(body: Tree) = @@ -545,7 +545,7 @@ abstract class TreeInfo { copyValDef(vd)(mods = vdMods, name = dname, rhs = vdRhs) }.getOrElse(vd) // for abstract and some lazy val/vars - case dd @ DefDef(mods, name, _, _, tpt, rhs) if mods.hasAccessorFlag => + case DefDef(mods, name, _, _, tpt, rhs) if mods.hasAccessorFlag => // transform getter mods to field val vdMods = (if (!mods.hasStableFlag) mods | Flags.MUTABLE else mods &~ Flags.STABLE) &~ Flags.ACCESSOR ValDef(vdMods, name, tpt, rhs) @@ -688,7 +688,7 @@ abstract class TreeInfo { def catchesThrowable(cdef: CaseDef) = ( cdef.guard.isEmpty && (unbind(cdef.pat) match { case Ident(nme.WILDCARD) => true - case i@Ident(name) => hasNoSymbol(i) + case i@Ident(_) => hasNoSymbol(i) case _ => false }) ) @@ -788,6 +788,7 @@ abstract class TreeInfo { case Apply(f, _) => hasExplicitUnit(f) case TypeApply(f, _) => hasExplicitUnit(f) case AppliedTypeTree(f, _) => hasExplicitUnit(f) + case Block(_, expr) => hasExplicitUnit(expr) case _ => false } } @@ -910,6 +911,19 @@ abstract class TreeInfo { unapply(dissectApplied(tree)) } + /** + * Deconstructs an application into fun (typically a Select), targs and argss. + * Unlike `Applied`, only matches if the tree is actually an application (Apply and / or TypeApply). + */ + object Application { + def unapply(tree: Tree): Option[(Tree, List[Tree], List[List[Tree]])] = { + val ap = new Applied(tree) + val core = ap.core + if (core eq tree) None + else Some((core, ap.targs, ap.argss)) + } + } + /** Does list of trees start with a definition of * a class or module with given name (ignoring imports) */ @@ -1001,8 +1015,8 @@ abstract class TreeInfo { case _ => EmptyTree } - def unapply(tree: Tree) = refPart(tree) match { - case ref: RefTree => { + def unapply(tree: Tree): Option[(Boolean, Boolean, Symbol, Symbol, List[Tree])] = refPart(tree) match { + case ref: RefTree => val qual = ref.qualifier val isBundle = definitions.isMacroBundleType(qual.tpe) val isBlackbox = @@ -1018,8 +1032,7 @@ abstract class TreeInfo { if (qualSym.isModule) qualSym.moduleClass else qualSym } Some((isBundle, isBlackbox, owner, ref.symbol, dissectApplied(tree).targs)) - } - case _ => None + case _ => None } } @@ -1027,7 +1040,7 @@ abstract class TreeInfo { final def isNullaryInvocation(tree: Tree): Boolean = tree.symbol != null && tree.symbol.isMethod && (tree match { case TypeApply(fun, _) => isNullaryInvocation(fun) - case tree: RefTree => true + case _: RefTree => true case _ => false }) @@ -1093,7 +1106,7 @@ trait MacroAnnotionTreeInfo { self: TreeInfo => } yield AnnotationZipper(ann, vparam1, PatchedSyntacticClassDef(mods, name, tparams, constrMods, vparamss1, earlyDefs, parents, selfdef, body)) czippers ++ tzippers ++ vzippers } - case SyntacticTraitDef(mods, name, tparams, earlyDefs, parents, selfdef, body) => + case SyntacticTraitDef(mods, name@_, tparams, earlyDefs@_, parents@_, selfdef@_, body@_) => val tdef = tree.asInstanceOf[ClassDef] val czippers = mods.annotations.map(ann => { val annottee = tdef.copy(mods = mods.mapAnnotations(_ diff List(ann))) diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 13f95efd0dbf..cc1f6b7eccaf 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -509,23 +509,37 @@ trait Trees extends api.Trees { } } + /** A selector in an import clause `import x.name as rename`. + * For a normal import, name and rename are the same. + * For a rename, they are different. + * A wildcard import has name `_` and null rename. + * A "masking" import has rename `_` (where name is not `_`). + * + * The unhappy special cases are: + * - import member named `_` has rename `_` like normal. (backward compat) + * - import given members is a wildcard but rename `given`. (forward compat) + * + * Client must distinguish isWildcard and isGiven. + */ case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) extends ImportSelectorApi { assert(isWildcard || rename != null, s"Bad import selector $name => $rename") def isWildcard = name == nme.WILDCARD && rename == null - def isMask = name != nme.WILDCARD && rename == nme.WILDCARD - def isSpecific = !isWildcard - def isRename = rename != null && rename != nme.WILDCARD && name != rename + def isGiven = name == nme.WILDCARD && rename == nme.`given` + def isMask = name != nme.WILDCARD && rename == nme.WILDCARD + def isRename = name != rename && rename != null && rename != nme.WILDCARD && name != nme.WILDCARD + def isSpecific = if (name == nme.WILDCARD) rename == nme.WILDCARD else rename != nme.WILDCARD private def isLiteralWildcard = name == nme.WILDCARD && rename == nme.WILDCARD private def sameName(name: Name, other: Name) = (name eq other) || (name ne null) && name.start == other.start && name.length == other.length def hasName(other: Name) = sameName(name, other) def introduces(target: Name) = if (target == nme.WILDCARD) isLiteralWildcard - else target != null && sameName(rename, target) + else target != null && !isGiven && sameName(rename, target) } object ImportSelector extends ImportSelectorExtractor { private val wild = ImportSelector(nme.WILDCARD, -1, null, -1) val wildList = List(wild) // OPT This list is shared for performance. Used for unpositioned synthetic only. def wildAt(pos: Int) = ImportSelector(nme.WILDCARD, pos, null, -1) + def givenAt(pos: Int) = ImportSelector(nme.WILDCARD, pos, nme.`given`, -1) def mask(name: Name) = ImportSelector(name, -1, nme.WILDCARD, -1) } @@ -537,6 +551,16 @@ trait Trees extends api.Trees { traverser.traverse(expr) selectors foreach traverser.traverseImportSelector } + def posOf(sel: ImportSelector): Position = { + val pos0 = this.pos + val start = sel.namePos + if (start >= 0 && selectors.contains(sel)) { + val hasRename = sel.rename != null && sel.renamePos >= 0 // !sel.isWildcard + val end = if (hasRename) sel.renamePos + sel.rename.length else start + sel.name.length + pos0.copyRange(start, start, end) + } + else pos0 + } } object Import extends ImportExtractor @@ -608,7 +632,8 @@ trait Trees extends api.Trees { case class UnApply(fun: Tree, args: List[Tree]) extends TermTree with UnApplyApi { override def transform(transformer: Transformer): Tree = - transformer.treeCopy.UnApply(this, transformer.transform(fun), transformer.transformTrees(args)) // bq: see test/.../unapplyContexts2.scala + transformer.treeCopy.UnApply(this, transformer.transform(fun), transformer.transformTrees(args)) + // bq: see test/.../unapplyContexts2.scala override def traverse(traverser: Traverser): Unit = { traverser.traverse(fun) traverser.traverseTrees(args) diff --git a/src/reflect/scala/reflect/internal/TypeDebugging.scala b/src/reflect/scala/reflect/internal/TypeDebugging.scala index 6adab6fbe87e..ed99069fda2e 100644 --- a/src/reflect/scala/reflect/internal/TypeDebugging.scala +++ b/src/reflect/scala/reflect/internal/TypeDebugging.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 5f3d1439481e..aac8d2f7ee63 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,10 +15,9 @@ package reflect package internal import java.util.Objects - import scala.collection.mutable import scala.ref.WeakReference -import mutable.{ListBuffer, LinkedHashSet} +import mutable.{LinkedHashSet, ListBuffer} import Flags._ import scala.util.control.ControlThrowable import scala.annotation.{tailrec, unused} @@ -27,6 +26,7 @@ import util.ThreeValues._ import Variance._ import Depth._ import TypeConstants._ +import scala.util.chaining._ /* A standard type pattern match: case ErrorType => @@ -152,7 +152,6 @@ trait Types override def params = underlying.params override def paramTypes = underlying.paramTypes override def termSymbol = underlying.termSymbol - override def termSymbolDirect = underlying.termSymbolDirect override def typeParams = underlying.typeParams override def typeSymbol = underlying.typeSymbol override def typeSymbolDirect = underlying.typeSymbolDirect @@ -330,10 +329,6 @@ trait Types */ def typeSymbol: Symbol = NoSymbol - /** The term symbol ''directly'' associated with the type. - */ - def termSymbolDirect: Symbol = termSymbol - /** The type symbol ''directly'' associated with the type. * In other words, no normalization is performed: if this is an alias type, * the symbol returned is that of the alias, not the underlying type. @@ -982,7 +977,7 @@ trait Types def load(sym: Symbol): Unit = {} private def findDecl(name: Name, excludedFlags: Long): Symbol = { - var alts: List[Symbol] = List() + var alts: List[Symbol] = Nil var sym: Symbol = NoSymbol var e: ScopeEntry = decls.lookupEntry(name) while (e ne null) { @@ -996,7 +991,7 @@ trait Types e = decls.lookupNextEntry(e) } if (alts.isEmpty) sym - else (baseClasses.head.newOverloaded(this, alts)) + else baseClasses.head.newOverloaded(this, alts) } /** Find all members meeting the flag requirements. @@ -2580,7 +2575,6 @@ trait Types override def prefix = pre override def prefixDirect = pre override def termSymbol = super.termSymbol - override def termSymbolDirect = super.termSymbol override def typeArgs = args override def typeOfThis = relativize(sym.typeOfThis) override def typeSymbol = sym @@ -2936,8 +2930,10 @@ trait Types object MethodType extends MethodTypeExtractor - // TODO: rename so it's more appropriate for the type that is for a method without argument lists - // ("nullary" erroneously implies it has an argument list with zero arguments, it actually has zero argument lists) + /** A method without parameter lists. + * + * Note: a MethodType with paramss that is a ListOfNil is called "nilary", to disambiguate. + */ case class NullaryMethodType(override val resultType: Type) extends Type with NullaryMethodTypeApi { override def isTrivial = resultType.isTrivial && (resultType eq resultType.withoutAnnotations) override def prefix: Type = resultType.prefix @@ -2958,7 +2954,6 @@ trait Types else NullaryMethodType(result1) } override def foldOver(folder: TypeFolder): Unit = folder(resultType) - } object NullaryMethodType extends NullaryMethodTypeExtractor @@ -3818,7 +3813,11 @@ trait Types override def isTrivial: Boolean = underlying.isTrivial && annotations.forall(_.isTrivial) - override def safeToString = annotations.mkString(underlying.toString + " @", " @", "") + override def safeToString = { + val wrap = isShowAsInfixType || isFunctionTypeDirect(this) + val ul = underlying.toString.pipe(s => if (wrap) s"($s)" else s) + annotations.mkString(ul + " @", " @", "") + } override def filterAnnotations(p: AnnotationInfo => Boolean): Type = { val (yes, no) = annotations partition p @@ -4033,13 +4032,13 @@ trait Types private[this] val copyRefinedTypeSSM: ReusableInstance[SubstSymMap] = ReusableInstance[SubstSymMap](SubstSymMap(), enabled = isCompilerUniverse) - def copyRefinedType(original: RefinedType, parents: List[Type], decls: Scope) = - if ((parents eq original.parents) && (decls eq original.decls)) original + def copyRefinedType(original: RefinedType, parents: List[Type], decls: Scope, owner: Symbol = null) = + if ((parents eq original.parents) && (decls eq original.decls) && (owner eq null)) original else { - val owner = original.typeSymbol.owner + val newOwner = if (owner != null) owner else original.typeSymbol.owner val result = if (isIntersectionTypeForLazyBaseType(original)) intersectionTypeForLazyBaseType(parents) - else refinedType(parents, owner) + else refinedType(parents, newOwner) if (! decls.isEmpty){ val syms1 = decls.toList for (sym <- syms1) diff --git a/src/reflect/scala/reflect/internal/Variance.scala b/src/reflect/scala/reflect/internal/Variance.scala index eb939c6eec6a..34b65d58091e 100644 --- a/src/reflect/scala/reflect/internal/Variance.scala +++ b/src/reflect/scala/reflect/internal/Variance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index 1435a0ae25b6..41faa069c242 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/annotations/package.scala b/src/reflect/scala/reflect/internal/annotations/package.scala index 46cdb8914554..a4b022f876d0 100644 --- a/src/reflect/scala/reflect/internal/annotations/package.scala +++ b/src/reflect/scala/reflect/internal/annotations/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala b/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala index 71139ff97595..b9333a920f3a 100644 --- a/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala +++ b/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/pickling/ByteCodecs.scala b/src/reflect/scala/reflect/internal/pickling/ByteCodecs.scala index dabcdd337f45..098e5d93587a 100644 --- a/src/reflect/scala/reflect/internal/pickling/ByteCodecs.scala +++ b/src/reflect/scala/reflect/internal/pickling/ByteCodecs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/pickling/PickleBuffer.scala b/src/reflect/scala/reflect/internal/pickling/PickleBuffer.scala index 6f019ea2ebd7..27b4aba29d18 100644 --- a/src/reflect/scala/reflect/internal/pickling/PickleBuffer.scala +++ b/src/reflect/scala/reflect/internal/pickling/PickleBuffer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/pickling/PickleFormat.scala b/src/reflect/scala/reflect/internal/pickling/PickleFormat.scala index 3b2f2cff7f4f..fdc616558d0c 100644 --- a/src/reflect/scala/reflect/internal/pickling/PickleFormat.scala +++ b/src/reflect/scala/reflect/internal/pickling/PickleFormat.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/pickling/Translations.scala b/src/reflect/scala/reflect/internal/pickling/Translations.scala index 025aadeed05a..366fbbadd140 100644 --- a/src/reflect/scala/reflect/internal/pickling/Translations.scala +++ b/src/reflect/scala/reflect/internal/pickling/Translations.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index f7230abbc97c..bf51c0009f17 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -526,15 +526,6 @@ abstract class UnPickler { @inline def all[T](body: => T): List[T] = until(end, () => body) @inline def rep[T](body: => T): List[T] = times(readNat(), () => body) - // !!! What is this doing here? - def fixApply(tree: Apply, tpe: Type): Apply = { - val Apply(fun, args) = tree - if (fun.symbol.isOverloaded) { - fun setType fun.symbol.info - inferMethodAlternative(fun, args map (_.tpe), tpe) - } - tree - } def ref() = readTreeRef() def caseRef() = readCaseDefRef() def modsRef() = readModifiersRef() @@ -553,13 +544,25 @@ abstract class UnPickler { } def selectorsRef() = all(ImportSelector(nameRef(), -1, nameRef(), -1)) + // For ASTs we pickle the `tpe` and the `symbol`. References to symbols (`EXTref`) are pickled as owner + name, + // which means overloaded symbols cannot be resolved. + // This method works around that by selecting the overload based on the tree type. + def fixOverload(t: Tree, tpe: Type): Unit = t match { + case sel: Select => + if (sel.symbol.isOverloaded) { + val qt = sel.qualifier.tpe + sel.symbol.alternatives.find(alt => qt.memberType(alt).matches(tpe)).foreach(sel.setSymbol) + } + case _ => + } + /* A few of the most popular trees have been pulled to the top for * switch efficiency purposes. */ - def readTree(tpe: Type): Tree = (tag: @switch) match { + def readTree(): Tree = (tag: @switch) match { case IDENTtree => Ident(nameRef()) case SELECTtree => Select(ref(), nameRef()) - case APPLYtree => fixApply(Apply(ref(), all(ref())), tpe) // !!! + case APPLYtree => Apply(ref(), all(ref())) case BINDtree => Bind(nameRef(), ref()) case BLOCKtree => all(ref()) match { case stats :+ expr => Block(stats, expr) case x => throw new MatchError(x) } case IFtree => If(ref(), ref(), ref()) @@ -603,10 +606,10 @@ abstract class UnPickler { val tpe = readTypeRef() val sym = if (isTreeSymbolPickled(tag)) readSymbolRef() else null - val result = readTree(tpe) + val result = readTree() - if (sym ne null) result setSymbol sym - result setType tpe + if (sym ne null) fixOverload(result.setSymbol(sym), tpe) + result.setType(tpe) } /* Read an abstract syntax tree */ @@ -700,8 +703,6 @@ abstract class UnPickler { protected def errorBadSignature(msg: String) = throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg) - def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type): Unit = {} // can't do it; need a compiler for that. - def newLazyTypeRef(i: Int): LazyType = new LazyTypeRef(i) def newLazyTypeRefAndAlias(i: Int, j: Int): LazyType = new LazyTypeRefAndAlias(i, j) diff --git a/src/reflect/scala/reflect/internal/settings/AbsSettings.scala b/src/reflect/scala/reflect/internal/settings/AbsSettings.scala index 1bfb561cabcb..a964b9967728 100644 --- a/src/reflect/scala/reflect/internal/settings/AbsSettings.scala +++ b/src/reflect/scala/reflect/internal/settings/AbsSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala index 5896b4bb2390..56ff2990a36c 100644 --- a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala +++ b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/tpe/CommonOwners.scala b/src/reflect/scala/reflect/internal/tpe/CommonOwners.scala index 543827b2c10c..d97fb426a5d5 100644 --- a/src/reflect/scala/reflect/internal/tpe/CommonOwners.scala +++ b/src/reflect/scala/reflect/internal/tpe/CommonOwners.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/tpe/FindMembers.scala b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala index 7cc3f799430a..d131bcddcd27 100644 --- a/src/reflect/scala/reflect/internal/tpe/FindMembers.scala +++ b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala index eb55afff8c47..eb57d1cf1d64 100644 --- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala +++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala index 6420d7af5053..0d46744d614f 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala index 6d74d05d47a5..40f8a2e59541 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index 570b04424b6c..09bb8fb7bd34 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -244,7 +244,7 @@ private[internal] trait TypeMaps { annots foreach foldOver def foldOver(annot: AnnotationInfo): Unit = { - val AnnotationInfo(atp, args, assocs) = annot + val AnnotationInfo(atp, args, _) = annot atp.foldOver(this) foldOverAnnotArgs(args) } @@ -817,6 +817,10 @@ private[internal] trait TypeMaps { case SingleType(pre, sym) if pre ne NoPrefix => val newSym = substFor(sym) (if (sym eq newSym) tpe else singleType(pre, newSym)).mapOver(this) + case tp: RefinedType => + val owner = tpe.typeSymbol.owner + val newOwner = substFor(owner) + (if (newOwner eq owner) tpe else copyRefinedType(tp, tp.parents, tp.decls, newOwner)).mapOver(this) case _ => super.apply(tpe) } @@ -1105,9 +1109,6 @@ private[internal] trait TypeMaps { } override protected def pred(sym1: Symbol): Boolean = sym1 == sym } - class ContainsAnyCollector(syms: List[Symbol]) extends ExistsTypeRefCollector { - override protected def pred(sym1: Symbol): Boolean = syms.contains(sym1) - } class ContainsAnyKeyCollector(symMap: mutable.HashMap[Symbol, _]) extends ExistsTypeRefCollector { override protected def pred(sym1: Symbol): Boolean = symMap.contains(sym1) } diff --git a/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala b/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala index 8a8540df3cea..4c4a7a3f34c7 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index 96e27e74c075..ae599366c1b1 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -134,8 +134,10 @@ trait Erasure { def apply(tp: Type): Type = tp match { case FoldableConstantType(ct) => // erase classOf[List[_]] to classOf[List]. special case for classOf[Unit], avoid erasing to classOf[BoxedUnit]. - if (ct.tag == ClazzTag && ct.typeValue.typeSymbol != UnitClass) ConstantType(Constant(apply(ct.typeValue))) - else tp + if (ct.tag == ClazzTag) + if (ct.typeValue.typeSymbol == UnitClass) tp + else ConstantType(Constant(apply(ct.typeValue))) + else ct.tpe case st: ThisType if st.sym.isPackageClass => tp case st: SubType => @@ -253,7 +255,7 @@ trait Erasure { else scalaErasure } - /** This is used as the Scala erasure during the erasure phase itself + /** This is used as the Scala erasure during the erasure phase itself. * It differs from normal erasure in that value classes are erased to ErasedValueTypes which * are then later converted to the underlying parameter type in phase posterasure. */ @@ -262,11 +264,10 @@ trait Erasure { erasure(sym)(tp) else if (sym.isClassConstructor) specialConstructorErasure(sym.owner, tp) - else { + else specialScalaErasureFor(sym)(tp) - } - def specialConstructorErasure(clazz: Symbol, tpe: Type): Type = { + def specialConstructorErasure(clazz: Symbol, tpe: Type): Type = tpe match { case PolyType(tparams, restpe) => specialConstructorErasure(clazz, restpe) @@ -282,7 +283,6 @@ trait Erasure { assert(clazz == ArrayClass || tp.isError, s"unexpected constructor erasure $tp for $clazz") specialScalaErasureFor(clazz)(tp) } - } /** Scala's more precise erasure than java's is problematic as follows: * @@ -530,7 +530,7 @@ trait Erasure { ErasedValueType(tref.sym, erasedValueClassArg(tref)) } - /** This is used as the Scala erasure during the erasure phase itself + /** This is used as the Scala erasure during the erasure phase itself. * It differs from normal erasure in that value classes are erased to ErasedValueTypes which * are then later unwrapped to the underlying parameter type in phase posterasure. */ @@ -541,10 +541,9 @@ trait Erasure { */ object specialScala3Erasure extends Scala3ErasureMap with SpecialScalaErasure - def specialScalaErasureFor(sym: Symbol): ErasureMap = { + def specialScalaErasureFor(sym: Symbol): ErasureMap = if (sym.isScala3Defined) specialScala3Erasure else specialScalaErasure - } object javaErasure extends JavaErasureMap diff --git a/src/reflect/scala/reflect/internal/transform/PostErasure.scala b/src/reflect/scala/reflect/internal/transform/PostErasure.scala index 31450817b2a8..2420acb61b00 100644 --- a/src/reflect/scala/reflect/internal/transform/PostErasure.scala +++ b/src/reflect/scala/reflect/internal/transform/PostErasure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/transform/Transforms.scala b/src/reflect/scala/reflect/internal/transform/Transforms.scala index eecc286f2044..37874253adb9 100644 --- a/src/reflect/scala/reflect/internal/transform/Transforms.scala +++ b/src/reflect/scala/reflect/internal/transform/Transforms.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,7 +15,6 @@ package reflect package internal package transform -import scala.annotation.nowarn import scala.language.existentials trait Transforms { self: SymbolTable => @@ -36,9 +35,9 @@ trait Transforms { self: SymbolTable => } } - private[this] val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry): @nowarn("cat=deprecation&msg=early initializers") - private[this] val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure): @nowarn("cat=deprecation&msg=early initializers") - private[this] val postErasureLazy = new Lazy(new { val global: Transforms.this.type = self } with PostErasure): @nowarn("cat=deprecation&msg=early initializers") + private[this] val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry) + private[this] val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure) + private[this] val postErasureLazy = new Lazy(new { val global: Transforms.this.type = self } with PostErasure) def uncurry = uncurryLazy.force def erasure = erasureLazy.force diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala index a6cfbed7ea8d..afc1a5e4f37b 100644 --- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala +++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -99,11 +99,10 @@ trait UnCurry { // while processing one of its superclasses (such as java.lang.Object). Since we // don't need the more precise `matches` semantics, we only check the symbol, which // is anyway faster and safer - for (decl <- decls if decl.annotations.exists(_.symbol == VarargsClass)) { - if (mexists(decl.paramss)(sym => definitions.isRepeatedParamType(sym.tpe))) { - varargOverloads += varargForwarderSym(clazz, decl, exitingPhase(phase)(decl.info)) - } - } + for (decl <- decls) + if (decl.annotations.exists(_.symbol == VarargsClass) + && mexists(decl.paramss)(sym => definitions.isRepeatedParamType(sym.tpe))) + varargOverloads += varargForwarderSym(clazz, decl) if ((parents1 eq parents) && varargOverloads.isEmpty) tp else { val newDecls = decls.cloneScope @@ -120,11 +119,9 @@ trait UnCurry { } } - private def varargForwarderSym(currentClass: Symbol, origSym: Symbol, newInfo: Type): Symbol = { + private def varargForwarderSym(currentClass: Symbol, origSym: Symbol): Symbol = { val forwSym = origSym.cloneSymbol(currentClass, VARARGS | SYNTHETIC | origSym.flags & ~DEFERRED, origSym.name.toTermName).withoutAnnotations - // we are using `origSym.info`, which contains the type *before* the transformation - // so we still see repeated parameter types (uncurry replaces them with Seq) def toArrayType(tp: Type, newParam: Symbol): Type = { val arg = elementType(SeqClass, tp) val elem = if (arg.typeSymbol.isTypeParameterOrSkolem && !(arg <:< AnyRefTpe)) { @@ -146,6 +143,8 @@ trait UnCurry { arrayType(elem) } + // we are using `origSym.info`, which contains the type *before* the transformation + // so we still see repeated parameter types (uncurry replaces them with Seq) foreach2(forwSym.paramss, origSym.info.paramss){ (fsps, origPs) => foreach2(fsps, origPs){ (p, sym) => if (definitions.isRepeatedParamType(sym.tpe)) diff --git a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala index 28062740a315..9c35289a9805 100644 --- a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala +++ b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/AlmostFinalValue.java b/src/reflect/scala/reflect/internal/util/AlmostFinalValue.java index f9bb24f00a85..1a816210d8e2 100644 --- a/src/reflect/scala/reflect/internal/util/AlmostFinalValue.java +++ b/src/reflect/scala/reflect/internal/util/AlmostFinalValue.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/ChromeTrace.scala b/src/reflect/scala/reflect/internal/util/ChromeTrace.scala index 88e4189b650c..b7ea49c901b2 100644 --- a/src/reflect/scala/reflect/internal/util/ChromeTrace.scala +++ b/src/reflect/scala/reflect/internal/util/ChromeTrace.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/CodeAction.scala b/src/reflect/scala/reflect/internal/util/CodeAction.scala index 26724b461dc3..70ca144f4d8a 100644 --- a/src/reflect/scala/reflect/internal/util/CodeAction.scala +++ b/src/reflect/scala/reflect/internal/util/CodeAction.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/Collections.scala b/src/reflect/scala/reflect/internal/util/Collections.scala index 6b762c1eb42c..7d3adff49f06 100644 --- a/src/reflect/scala/reflect/internal/util/Collections.scala +++ b/src/reflect/scala/reflect/internal/util/Collections.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/FileUtils.scala b/src/reflect/scala/reflect/internal/util/FileUtils.scala index 89e2941ec8ce..b2fe3a5b0132 100644 --- a/src/reflect/scala/reflect/internal/util/FileUtils.scala +++ b/src/reflect/scala/reflect/internal/util/FileUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala index 248e15b9edf5..79186346b255 100644 --- a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala +++ b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/HashSet.scala b/src/reflect/scala/reflect/internal/util/HashSet.scala index c5f0c2301298..8176b83a32aa 100644 --- a/src/reflect/scala/reflect/internal/util/HashSet.scala +++ b/src/reflect/scala/reflect/internal/util/HashSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/JavaClearable.scala b/src/reflect/scala/reflect/internal/util/JavaClearable.scala index faa7e7388d13..4132ad49e926 100644 --- a/src/reflect/scala/reflect/internal/util/JavaClearable.scala +++ b/src/reflect/scala/reflect/internal/util/JavaClearable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/Origins.scala b/src/reflect/scala/reflect/internal/util/Origins.scala index 69dd2f9732e5..ec581d3fd424 100644 --- a/src/reflect/scala/reflect/internal/util/Origins.scala +++ b/src/reflect/scala/reflect/internal/util/Origins.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/OwnerOnlyChmod.scala b/src/reflect/scala/reflect/internal/util/OwnerOnlyChmod.scala index bb28549f13bc..eb7728b2cf10 100644 --- a/src/reflect/scala/reflect/internal/util/OwnerOnlyChmod.scala +++ b/src/reflect/scala/reflect/internal/util/OwnerOnlyChmod.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala index 66d339182f3f..4387c83d67a2 100644 --- a/src/reflect/scala/reflect/internal/util/Position.scala +++ b/src/reflect/scala/reflect/internal/util/Position.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -37,9 +37,12 @@ object Position { final val tabInc = 8 private def validate[T <: Position](pos: T): T = { - if (pos.isRange) - assert(pos.start <= pos.end, s"bad position: ${pos.show}") - + if (pos.isRange) { + import pos.{pos => _, _} + assert(start <= end, s"bad position: ${pos.show}") + //assert(start <= point && point <= end, s"bad position: point $point out of range $start..$end: ${pos.show}") + //assert(start <= point && point <= end, s"bad position: point $point out of range $start..$end: ${pos.show}\n${pos.lineContent}\n${pos.lineCaret}") + } pos } @@ -66,8 +69,10 @@ class OffsetPosition(sourceIn: SourceFile, pointIn: Int) extends DefinedPosition override def start = point override def end = point } -class RangePosition(sourceIn: SourceFile, startIn: Int, pointIn: Int, endIn: Int) extends OffsetPosition(sourceIn, pointIn) { +class RangePosition(sourceIn: SourceFile, startIn: Int, pointIn: Int, endIn: Int) extends DefinedPosition { override def isRange = true + override def source = sourceIn + override def point = pointIn override def start = startIn override def end = endIn } @@ -130,13 +135,26 @@ private[util] trait InternalPositionImpl { final def makeTransparentIf(cond: Boolean): Position = if (cond && isOpaqueRange) Position.transparent(source, start, point, end) else this - /** Copy a range position with a changed value. - */ - def withStart(start: Int): Position = copyRange(start = start) - def withPoint(point: Int): Position = if (isRange) copyRange(point = point) else Position.offset(source, point) - def withEnd(end: Int): Position = copyRange(end = end) - def withSource(source: SourceFile): Position = copyRange(source = source) - def withShift(shift: Int): Position = Position.range(source, start + shift, point + shift, end + shift) + /* Copy a range position with a changed value. */ + /* Note: the result is validated (start <= end), use `copyRange` to update both at the same time. */ + /** If start differs, copy a range position or promote an offset. */ + def withStart(start: Int): Position = if (isDefined && this.start != start) copyRange(start = start) else this + /** If point differs, copy a range position or return an offset. */ + def withPoint(point: Int): Position = + if (!isDefined || this.point == point) this else if (isRange) copyRange(point = point) else asOffset(point) + /** If end differs, copy a range position or promote an offset. */ + def withEnd(end: Int): Position = if (isDefined && this.end != end) copyRange(end = end) else this + def withSource(source: SourceFile): Position = + if (isRange) copyRange(source = source) + else if (isDefined) Position.offset(source, point) + else this + def withShift(shift: Int): Position = + if (isRange) Position.range(source, start + shift, point + shift, end + shift) + else if (isDefined) asOffset(point + shift) + else this + + def copyRange(start: Int = start, point: Int = point, end: Int = end, source: SourceFile = source) = + Position.range(source, start, point, end) /** Convert a range position to a simple offset. */ @@ -144,6 +162,13 @@ private[util] trait InternalPositionImpl { def focus: Position = if (this.isRange) asOffset(point) else this def focusEnd: Position = if (this.isRange) asOffset(end) else this + /** Convert an offset position to a degenerate range. + * + * Note that withPoint does not promote to range, but withStart and withEnd may do so. + * It would be more disciplined to require explicit promotion with toRange. + */ + def toRange: Position = if (this.isRange) this else copyRange() + /** If you have it in for punctuation you might not like these methods. * However I think they're aptly named. * @@ -158,11 +183,21 @@ private[util] trait InternalPositionImpl { def |^(that: Position): Position = (this | that) ^ that.point def ^|(that: Position): Position = (this | that) ^ this.point - def union(pos: Position): Position = ( - if (!pos.isRange) this - else if (this.isRange) copyRange(start = start min pos.start, end = end max pos.end) - else pos - ) + /** Widen a range to include the other operand. + * If this position is a range, preserve its point; otherwise, the point of the other operand. + * Note that NoPosition | offset is not promoted to an offset position. + * Nor is offset | offset promoted to range. + */ + def union(pos: Position): Position = { + def ranged(point: Int) = Position.range(source, start = start.min(pos.start), point = point, end = end.max(pos.end)) + if (pos.isRange) { + if (this.isRange) ranged(point) + else if (this.isDefined) ranged(pos.point) + else pos + } + else if (this.isRange && pos.isDefined && !this.includes(pos)) ranged(point) + else this + } def includes(pos: Position): Boolean = isRange && pos.isDefined && start <= pos.start && pos.end <= end def properlyIncludes(pos: Position): Boolean = includes(pos) && (start < pos.start || pos.end < end) @@ -198,7 +233,7 @@ private[util] trait InternalPositionImpl { buf.toString } @deprecated("use `lineCaret`", since="2.11.0") - def lineCarat: String = lineCaret + def lineCarat: String = lineCaret def showError(msg: String): String = { def escaped(s: String) = { @@ -230,8 +265,6 @@ private[util] trait InternalPositionImpl { that.isDefined && this.point == that.point && this.source.file == that.source.file private def asOffset(point: Int): Position = Position.offset(source, point) - private def copyRange(source: SourceFile = source, start: Int = start, point: Int = point, end: Int = end): Position = - Position.range(source, start, point, end) private def hasSource = source ne NoSourceFile private def bothRanges(that: Position) = isRange && that.isRange private def bothDefined(that: Position) = isDefined && that.isDefined diff --git a/src/reflect/scala/reflect/internal/util/ReusableInstance.scala b/src/reflect/scala/reflect/internal/util/ReusableInstance.scala index 8853e7d72242..69625315e59f 100644 --- a/src/reflect/scala/reflect/internal/util/ReusableInstance.scala +++ b/src/reflect/scala/reflect/internal/util/ReusableInstance.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala index 0a8b79922ec0..0e67fa7d3c52 100644 --- a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala +++ b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -51,17 +51,28 @@ final class RichClassLoader(private val self: JClassLoader) extends AnyVal { tryToInitializeClass[AnyRef](path).map(_.getConstructor().newInstance()).orNull /** Create an instance with ctor args, or invoke errorFn before throwing. */ - def create[T <: AnyRef : ClassTag](path: String, errorFn: String => Unit)(args: AnyRef*): T = { + def create[T <: AnyRef : ClassTag](path: String, errorFn: String => Unit)(args: Any*): T = { def fail(msg: String) = error(msg, new IllegalArgumentException(msg)) - def error(msg: String, e: Throwable) = { errorFn(msg) ; throw e } + def error(msg: String, e: Throwable) = { errorFn(msg); throw e } try { val clazz = Class.forName(path, /*initialize =*/ true, /*loader =*/ self) - if (classTag[T].runtimeClass isAssignableFrom clazz) { + if (classTag[T].runtimeClass.isAssignableFrom(clazz)) { val ctor = { - val maybes = clazz.getConstructors filter (c => c.getParameterCount == args.size && - (c.getParameterTypes zip args).forall { case (k, a) => k isAssignableFrom a.getClass }) + val bySize = clazz.getConstructors.filter(_.getParameterCount == args.size) + if (bySize.isEmpty) fail(s"No constructor takes ${args.size} parameters.") + def isAssignable(k: Class[?], a: Any): Boolean = + if (k == classOf[Int]) a.isInstanceOf[Integer] + else if (k == classOf[Boolean]) a.isInstanceOf[java.lang.Boolean] + else if (k == classOf[Long]) a.isInstanceOf[java.lang.Long] + else k.isAssignableFrom(a.getClass) + val maybes = bySize.filter(c => c.getParameterTypes.zip(args).forall { case (k, a) => isAssignable(k, a) }) if (maybes.size == 1) maybes.head - else fail(s"Constructor must accept arg list (${args map (_.getClass.getName) mkString ", "}): ${path}") + else if (bySize.size == 1) + fail(s"One constructor takes ${args.size} parameters but ${ + bySize.head.getParameterTypes.zip(args).collect { case (k, a) if !isAssignable(k, a) => s"$k != ${a.getClass}" }.mkString("; ") + }.") + else + fail(s"Constructor must accept arg list (${args.map(_.getClass.getName).mkString(", ")}): ${path}") } (ctor.newInstance(args: _*)).asInstanceOf[T] } else { diff --git a/src/reflect/scala/reflect/internal/util/Set.scala b/src/reflect/scala/reflect/internal/util/Set.scala index 4728f7ddc339..2880020cfcd1 100644 --- a/src/reflect/scala/reflect/internal/util/Set.scala +++ b/src/reflect/scala/reflect/internal/util/Set.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala index 1c17168196fe..3daf337db3a5 100644 --- a/src/reflect/scala/reflect/internal/util/SourceFile.scala +++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala index ce12b1c7a159..4736c2a7add2 100644 --- a/src/reflect/scala/reflect/internal/util/Statistics.scala +++ b/src/reflect/scala/reflect/internal/util/Statistics.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/StatisticsStatics.java b/src/reflect/scala/reflect/internal/util/StatisticsStatics.java index 76c1644e18bf..937a3471c4da 100644 --- a/src/reflect/scala/reflect/internal/util/StatisticsStatics.java +++ b/src/reflect/scala/reflect/internal/util/StatisticsStatics.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/StringOps.scala b/src/reflect/scala/reflect/internal/util/StringOps.scala index e68a25b0062d..8b439b563d91 100644 --- a/src/reflect/scala/reflect/internal/util/StringOps.scala +++ b/src/reflect/scala/reflect/internal/util/StringOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala b/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala index 5ef032b94cc5..e81e5260479f 100644 --- a/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala +++ b/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -41,7 +41,7 @@ trait StripMarginInterpolator { final def sm(args: Any*): String = impl('|', args: _*) private final def impl(sep: Char, args: Any*): String = { - def isLineBreak(c: Char) = c == '\n' || c == '\f' // compatible with StringOps#isLineBreak + def isLineBreak(c: Char) = c == Chars.LF || c == Chars.FF // compatible with CharArrayReader def stripTrailingPart(s: String) = { val (pre, post) = s.span(c => !isLineBreak(c)) pre + post.stripMargin(sep) diff --git a/src/reflect/scala/reflect/internal/util/TableDef.scala b/src/reflect/scala/reflect/internal/util/TableDef.scala index 9a65dccf146c..6661cbbfee25 100644 --- a/src/reflect/scala/reflect/internal/util/TableDef.scala +++ b/src/reflect/scala/reflect/internal/util/TableDef.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/ThreeValues.scala b/src/reflect/scala/reflect/internal/util/ThreeValues.scala index bbc75dc1e0a4..298721941c7c 100644 --- a/src/reflect/scala/reflect/internal/util/ThreeValues.scala +++ b/src/reflect/scala/reflect/internal/util/ThreeValues.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala index 27d765dfc380..c92979d3b1ec 100644 --- a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala +++ b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/TriState.scala b/src/reflect/scala/reflect/internal/util/TriState.scala index 2ee3d0a7df06..ff3722cc22d2 100644 --- a/src/reflect/scala/reflect/internal/util/TriState.scala +++ b/src/reflect/scala/reflect/internal/util/TriState.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala index 2cb12edb89e4..c8d6f031dcc8 100644 --- a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala +++ b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -424,7 +424,8 @@ object WeakHashSet { val defaultInitialCapacity = 16 val defaultLoadFactor = .75 - def apply[A <: AnyRef](initialCapacity: Int = WeakHashSet.defaultInitialCapacity, loadFactor: Double = WeakHashSet.defaultLoadFactor) = new WeakHashSet[A](initialCapacity, defaultLoadFactor) + def apply[A <: AnyRef](initialCapacity: Int = defaultInitialCapacity, loadFactor: Double = defaultLoadFactor) = + new WeakHashSet[A](initialCapacity, loadFactor) def empty[A <: AnyRef]: WeakHashSet[A] = new WeakHashSet[A]() } diff --git a/src/reflect/scala/reflect/internal/util/package.scala b/src/reflect/scala/reflect/internal/util/package.scala index 92086cb6c0b1..2c48816cba09 100644 --- a/src/reflect/scala/reflect/internal/util/package.scala +++ b/src/reflect/scala/reflect/internal/util/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/AbstractFile.scala b/src/reflect/scala/reflect/io/AbstractFile.scala index 72736bfb2f26..8463a4a076d0 100644 --- a/src/reflect/scala/reflect/io/AbstractFile.scala +++ b/src/reflect/scala/reflect/io/AbstractFile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/Directory.scala b/src/reflect/scala/reflect/io/Directory.scala index b8b521555e13..d02bdb239424 100644 --- a/src/reflect/scala/reflect/io/Directory.scala +++ b/src/reflect/scala/reflect/io/Directory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/File.scala b/src/reflect/scala/reflect/io/File.scala index ea80c208f3f2..95f66ffb68d7 100644 --- a/src/reflect/scala/reflect/io/File.scala +++ b/src/reflect/scala/reflect/io/File.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/FileOperationException.scala b/src/reflect/scala/reflect/io/FileOperationException.scala index 49430c6428cb..72c74be68873 100644 --- a/src/reflect/scala/reflect/io/FileOperationException.scala +++ b/src/reflect/scala/reflect/io/FileOperationException.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/NoAbstractFile.scala b/src/reflect/scala/reflect/io/NoAbstractFile.scala index 3183a1d53e39..0ce3ef39f7dd 100644 --- a/src/reflect/scala/reflect/io/NoAbstractFile.scala +++ b/src/reflect/scala/reflect/io/NoAbstractFile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/Path.scala b/src/reflect/scala/reflect/io/Path.scala index 361805ba8955..ec7076ffe02a 100644 --- a/src/reflect/scala/reflect/io/Path.scala +++ b/src/reflect/scala/reflect/io/Path.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -233,13 +233,13 @@ class Path private[io] (val jfile: JFile) { // creations def createDirectory(force: Boolean = true, failIfExists: Boolean = false): Directory = { val res = if (force) jfile.mkdirs() else jfile.mkdir() - if (!res && failIfExists && exists) fail("Directory '%s' already exists." format name) + if (!res && failIfExists && exists) fail(s"Directory '$name' already exists.") else if (isDirectory) toDirectory else new Directory(jfile) } def createFile(failIfExists: Boolean = false): File = { val res = jfile.createNewFile() - if (!res && failIfExists && exists) fail("File '%s' already exists." format name) + if (!res && failIfExists && exists) fail(s"File '$name' already exists.") else if (isFile) toFile else new File(jfile) } diff --git a/src/reflect/scala/reflect/io/PlainFile.scala b/src/reflect/scala/reflect/io/PlainFile.scala index b585c9d41902..8b1535c77ebd 100644 --- a/src/reflect/scala/reflect/io/PlainFile.scala +++ b/src/reflect/scala/reflect/io/PlainFile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/RootPath.scala b/src/reflect/scala/reflect/io/RootPath.scala index fd5ec96c79d9..9f160fd42b09 100644 --- a/src/reflect/scala/reflect/io/RootPath.scala +++ b/src/reflect/scala/reflect/io/RootPath.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/Streamable.scala b/src/reflect/scala/reflect/io/Streamable.scala index 3f1fec984f7a..8d652aadcb0b 100644 --- a/src/reflect/scala/reflect/io/Streamable.scala +++ b/src/reflect/scala/reflect/io/Streamable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/VirtualDirectory.scala b/src/reflect/scala/reflect/io/VirtualDirectory.scala index 6a30b93b177e..39db28815418 100644 --- a/src/reflect/scala/reflect/io/VirtualDirectory.scala +++ b/src/reflect/scala/reflect/io/VirtualDirectory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/VirtualFile.scala b/src/reflect/scala/reflect/io/VirtualFile.scala index be09c47c93f9..90b3ab7a541b 100644 --- a/src/reflect/scala/reflect/io/VirtualFile.scala +++ b/src/reflect/scala/reflect/io/VirtualFile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/io/ZipArchive.scala b/src/reflect/scala/reflect/io/ZipArchive.scala index b8cdbbacc1b1..3964030b0190 100644 --- a/src/reflect/scala/reflect/io/ZipArchive.scala +++ b/src/reflect/scala/reflect/io/ZipArchive.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -276,8 +276,11 @@ final class FileZipArchive(file: JFile, release: Option[String]) extends ZipArch } } } finally { - if (!ZipArchive.closeZipFile) + if (ZipArchive.closeZipFile) { + zipFile.close() + } else { zipFilePool.release(zipFile) + } } root } diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala index b03a7067e1ca..e39a1987fb3b 100644 --- a/src/reflect/scala/reflect/macros/Aliases.scala +++ b/src/reflect/scala/reflect/macros/Aliases.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Attachments.scala b/src/reflect/scala/reflect/macros/Attachments.scala index 0aa73581387f..a85ac8f948f6 100644 --- a/src/reflect/scala/reflect/macros/Attachments.scala +++ b/src/reflect/scala/reflect/macros/Attachments.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -133,9 +133,11 @@ private final class SingleAttachment[P >: Null](override val pos: P, val att: An override def all = Set.empty[Any] + att override def contains[T](implicit tt: ClassTag[T]) = tt.runtimeClass.isInstance(att) override def get[T](implicit tt: ClassTag[T]) = if (contains(tt)) Some(att.asInstanceOf[T]) else None - override def update[T](newAtt: T)(implicit tt: ClassTag[T]) = + override def update[T](newAtt: T)(implicit tt: ClassTag[T]) = { + //assert(tt ne classTag[Any]) if (contains(tt)) new SingleAttachment[P](pos, newAtt) else new NonemptyAttachments[P](pos, Set.empty[Any] + att + newAtt) + } override def remove[T](implicit tt: ClassTag[T]) = if (contains(tt)) pos.asInstanceOf[Attachments { type Pos = P }] else this override def toString = s"SingleAttachment at $pos: $att" diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala index fd24e90f5b24..915b230267a3 100644 --- a/src/reflect/scala/reflect/macros/Enclosures.scala +++ b/src/reflect/scala/reflect/macros/Enclosures.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Evals.scala b/src/reflect/scala/reflect/macros/Evals.scala index 311b10244c70..21337a6d3cfc 100644 --- a/src/reflect/scala/reflect/macros/Evals.scala +++ b/src/reflect/scala/reflect/macros/Evals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/ExprUtils.scala b/src/reflect/scala/reflect/macros/ExprUtils.scala index 6cd146627867..9827c7999246 100644 --- a/src/reflect/scala/reflect/macros/ExprUtils.scala +++ b/src/reflect/scala/reflect/macros/ExprUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/FrontEnds.scala b/src/reflect/scala/reflect/macros/FrontEnds.scala index ab59cf1dca43..71a6c5c1cd74 100644 --- a/src/reflect/scala/reflect/macros/FrontEnds.scala +++ b/src/reflect/scala/reflect/macros/FrontEnds.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala index d61e26040a04..b56d868460ed 100644 --- a/src/reflect/scala/reflect/macros/Infrastructure.scala +++ b/src/reflect/scala/reflect/macros/Infrastructure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Internals.scala b/src/reflect/scala/reflect/macros/Internals.scala index fae9d3b5ddb9..dc9e493da4b6 100644 --- a/src/reflect/scala/reflect/macros/Internals.scala +++ b/src/reflect/scala/reflect/macros/Internals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Names.scala b/src/reflect/scala/reflect/macros/Names.scala index 79a3d90c44a3..ed9c35b9b25b 100644 --- a/src/reflect/scala/reflect/macros/Names.scala +++ b/src/reflect/scala/reflect/macros/Names.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Parsers.scala b/src/reflect/scala/reflect/macros/Parsers.scala index 5a5a10e4e2fd..bffa9529431e 100644 --- a/src/reflect/scala/reflect/macros/Parsers.scala +++ b/src/reflect/scala/reflect/macros/Parsers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala index c2cf2e3bdcd2..aaae39fad258 100644 --- a/src/reflect/scala/reflect/macros/Reifiers.scala +++ b/src/reflect/scala/reflect/macros/Reifiers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala index e702f21ebbb1..44ba1ac89708 100644 --- a/src/reflect/scala/reflect/macros/Typers.scala +++ b/src/reflect/scala/reflect/macros/Typers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala index fc829949235b..909c2c984160 100644 --- a/src/reflect/scala/reflect/macros/Universe.scala +++ b/src/reflect/scala/reflect/macros/Universe.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/blackbox/Context.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala index 319bd2ad1ddc..52b48e74014b 100644 --- a/src/reflect/scala/reflect/macros/blackbox/Context.scala +++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/package.scala b/src/reflect/scala/reflect/macros/package.scala index 3a48c76a4ddd..6a741287bb8b 100644 --- a/src/reflect/scala/reflect/macros/package.scala +++ b/src/reflect/scala/reflect/macros/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/macros/whitebox/Context.scala b/src/reflect/scala/reflect/macros/whitebox/Context.scala index 35accd470b73..2850c7b45ffe 100644 --- a/src/reflect/scala/reflect/macros/whitebox/Context.scala +++ b/src/reflect/scala/reflect/macros/whitebox/Context.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/Gil.scala b/src/reflect/scala/reflect/runtime/Gil.scala index 3443fbe722be..36e64a628316 100644 --- a/src/reflect/scala/reflect/runtime/Gil.scala +++ b/src/reflect/scala/reflect/runtime/Gil.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 4a034f9cb2f1..4bca1d19a934 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index 7f9dd853d140..c66f58ccf498 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -88,7 +88,6 @@ class JavaUniverse extends InternalSymbolTable with JavaUniverseForce with Refle } // can't put this in runtime.Trees since that's mixed with Global in ReflectGlobal, which has the definition from internal.Trees - @nowarn("cat=deprecation&msg=early initializers") object treeInfo extends { val global: JavaUniverse.this.type = JavaUniverse.this } with TreeInfo diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 714af26d4c70..9f40ceff66a5 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -88,6 +88,10 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.PermittedSubclassSymbols this.NamePos this.UnnamedArg + this.DiscardedValue + this.DiscardedExpr + this.BooleanParameterType + this.ForceMatchDesugar this.noPrint this.typeDebug // inaccessible: this.posAssigner @@ -295,6 +299,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.PredefModule definitions.SpecializableModule definitions.ScalaRunTimeModule + definitions.MurmurHash3Module definitions.SymbolModule definitions.ScalaNumberClass definitions.DelayedInitClass @@ -467,6 +472,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.BeanPropertyAttr definitions.BooleanBeanPropertyAttr definitions.CompileTimeOnlyAttr + definitions.DefaultArgAttr definitions.DeprecatedAttr definitions.DeprecatedNameAttr definitions.DeprecatedInheritanceAttr @@ -477,6 +483,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.SerialVersionUIDAttr definitions.SerialVersionUIDAnnotation definitions.SpecializedClass + definitions.SuperArgAttr + definitions.SuperFwdArgAttr definitions.ThrowsClass definitions.TransientAttr definitions.UncheckedClass diff --git a/src/reflect/scala/reflect/runtime/ReflectSetup.scala b/src/reflect/scala/reflect/runtime/ReflectSetup.scala index abf259d8b558..6e243c72fcd9 100644 --- a/src/reflect/scala/reflect/runtime/ReflectSetup.scala +++ b/src/reflect/scala/reflect/runtime/ReflectSetup.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index 820cad5c9b0b..48566676840a 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/Settings.scala b/src/reflect/scala/reflect/runtime/Settings.scala index f3d731aad48b..550d4b461b7b 100644 --- a/src/reflect/scala/reflect/runtime/Settings.scala +++ b/src/reflect/scala/reflect/runtime/Settings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 643300abd554..30082e218cee 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/SymbolTable.scala b/src/reflect/scala/reflect/runtime/SymbolTable.scala index 5811932dbed0..c97b852931df 100644 --- a/src/reflect/scala/reflect/runtime/SymbolTable.scala +++ b/src/reflect/scala/reflect/runtime/SymbolTable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index 2922f13798da..4fd122ac0110 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 5cc4dc139578..3ae4826d596b 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala index 63e758127122..70b28f6f16f0 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala b/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala index 8665b7cccffe..6212ee594538 100644 --- a/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala +++ b/src/reflect/scala/reflect/runtime/ThreadLocalStorage.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/TwoWayCache.scala b/src/reflect/scala/reflect/runtime/TwoWayCache.scala index fb72c4d77f27..c031317fff2b 100644 --- a/src/reflect/scala/reflect/runtime/TwoWayCache.scala +++ b/src/reflect/scala/reflect/runtime/TwoWayCache.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala index c4170fd5af9f..ec2856eb0774 100644 --- a/src/reflect/scala/reflect/runtime/TwoWayCaches.scala +++ b/src/reflect/scala/reflect/runtime/TwoWayCaches.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala index 1b3fc8bc0768..0933df1fdd5b 100644 --- a/src/reflect/scala/reflect/runtime/package.scala +++ b/src/reflect/scala/reflect/runtime/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/Interpreter.scala b/src/repl-frontend/scala/tools/nsc/Interpreter.scala index 4909ce292f5d..7cd6da4091ea 100644 --- a/src/repl-frontend/scala/tools/nsc/Interpreter.scala +++ b/src/repl-frontend/scala/tools/nsc/Interpreter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -115,6 +115,7 @@ class InterpreterLoop { } // for 2.8 compatibility + @annotation.unused final class Compat { def bindValue(id: String, value: Any) = interpreter.bind(id, value.asInstanceOf[AnyRef].getClass.getName, value) diff --git a/src/repl-frontend/scala/tools/nsc/MainGenericRunner.scala b/src/repl-frontend/scala/tools/nsc/MainGenericRunner.scala index 96151010f317..9e4e24d080b1 100644 --- a/src/repl-frontend/scala/tools/nsc/MainGenericRunner.scala +++ b/src/repl-frontend/scala/tools/nsc/MainGenericRunner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/InteractiveReader.scala b/src/repl-frontend/scala/tools/nsc/interpreter/InteractiveReader.scala index f5c3fb219523..c350c0ceb919 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/InteractiveReader.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/InteractiveReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/jline/Reader.scala b/src/repl-frontend/scala/tools/nsc/interpreter/jline/Reader.scala index 0bc37ec1f374..204800159094 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/jline/Reader.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/jline/Reader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,7 +14,6 @@ package scala.tools.nsc.interpreter package jline import org.jline.builtins.InputRC -import org.jline.keymap.KeyMap import org.jline.reader.Parser.ParseContext import org.jline.reader._ import org.jline.reader.impl.{CompletionMatcherImpl, DefaultParser, LineReaderImpl} @@ -101,7 +100,7 @@ object Reader { } lazy val inputrcFileContents: Option[Array[Byte]] = inputrcFileUrl().map(in => urlByteArray(in)) - val jlineTerminal = TerminalBuilder.builder().jna(true).build() + val jlineTerminal = TerminalBuilder.builder().build() val completer = new Completion(completion) val parser = new ReplParser(repl) val history = new DefaultHistory @@ -150,8 +149,6 @@ object Reader { case NonFatal(_) => } //ignore - val keyMap = reader.getKeyMaps.get("main") - object ScalaShowType { val Name = "scala-show-type" private var lastInvokeLocation: Option[(String, Int)] = None @@ -180,13 +177,6 @@ object Reader { } reader.getWidgets().put(ScalaShowType.Name, () => ScalaShowType()) - locally { - import LineReader._ - // VIINS, VICMD, EMACS - val keymap = if (config.viMode) VIINS else EMACS - reader.getKeyMaps.put(MAIN, reader.getKeyMaps.get(keymap)); - keyMap.bind(new Reference(ScalaShowType.Name), KeyMap.alt(KeyMap.ctrl('t'))) - } def secure(p: java.nio.file.Path): Unit = { try scala.reflect.internal.util.OwnerOnlyChmod.chmodFileOrCreateEmpty(p) catch { case scala.util.control.NonFatal(e) => diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Completion.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Completion.scala index 389dd194e824..628d3a3fb8cc 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Completion.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Completion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/History.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/History.scala index 8de352cf9185..c7e45b98be24 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/History.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/History.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/IBindings.java b/src/repl-frontend/scala/tools/nsc/interpreter/shell/IBindings.java index 0f2b50641334..a97a968b955d 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/IBindings.java +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/IBindings.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/ILoop.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/ILoop.scala index d34487a5c4ca..aff002e9f187 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/ILoop.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/ILoop.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -10,8 +10,6 @@ * additional information regarding copyright ownership. */ -// Copyright 2005-2017 LAMP/EPFL and Lightbend, Inc. - package scala.tools.nsc.interpreter package shell @@ -158,7 +156,7 @@ class ILoop(config: ShellConfig, inOverride: BufferedReader = null, } /** Show the history */ - lazy val historyCommand = new LoopCommand("history", "show the history (optional num is commands to show)", None) { + lazy val historyCommand: LoopCommand = new LoopCommand("history", "show the history (optional num is commands to show)", None) { override def usage = "[num]" def defaultLines = 20 diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/InteractiveReader.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/InteractiveReader.scala index e84d24d63ac1..3542a08a5fe7 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/InteractiveReader.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/InteractiveReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavacTool.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavacTool.scala index bb69be3ff822..f4d6b2bc9660 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavacTool.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavacTool.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala index d2fde1dee2ad..4da845d3ca68 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/JavapClass.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Logger.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Logger.scala index 8525332a55c6..2c1f45807096 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Logger.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Logger.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/LoopCommands.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/LoopCommands.scala index ad7f0f3f510d..b706d16f1c9e 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/LoopCommands.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/LoopCommands.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Parsed.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Parsed.scala index e8f99d249579..5f9b52e769f1 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Parsed.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Parsed.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Pasted.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Pasted.scala index fecda6b509aa..929787736020 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Pasted.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Pasted.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/ReplCompletion.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/ReplCompletion.scala index 638e6d7cfc21..ecb911bc8c72 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/ReplCompletion.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/ReplCompletion.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Reporter.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Reporter.scala index 753aed47058e..e2457b658c5d 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Reporter.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Reporter.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala index eb0d5dcf9e4f..ab7f3f0cd96d 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Scripted.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/ShellConfig.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/ShellConfig.scala index 4d051bff1278..5d0a4ef4180e 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/ShellConfig.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/ShellConfig.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -38,9 +38,8 @@ object ShellConfig { val batchText: String = if (settings.execute.isSetByUser) settings.execute.value else "" val batchMode: Boolean = batchText.nonEmpty val doCompletion: Boolean = !(settings.noCompletion.value || batchMode) - val haveInteractiveConsole: Boolean = settings.Xjline.value != "off" - override val viMode = super.viMode || settings.Xjline.value == "vi" - @nowarn def xsource: String = if (settings.isScala3.value) settings.source.value.versionString else "" + val haveInteractiveConsole: Boolean = !settings.Xnojline.value + def xsource: String = if (settings.isScala3: @nowarn) settings.source.value.versionString else "" } case _ => new ShellConfig { val filesToPaste: List[String] = Nil @@ -48,9 +47,8 @@ object ShellConfig { val batchText: String = "" val batchMode: Boolean = false val doCompletion: Boolean = !settings.noCompletion.value - val haveInteractiveConsole: Boolean = settings.Xjline.value != "off" - override val viMode = super.viMode || settings.Xjline.value == "vi" - @nowarn def xsource: String = if (settings.isScala3.value) settings.source.value.versionString else "" + val haveInteractiveConsole: Boolean = !settings.Xnojline.value + def xsource: String = if (settings.isScala3: @nowarn) settings.source.value.versionString else "" } } } @@ -62,7 +60,6 @@ trait ShellConfig { def batchMode: Boolean def doCompletion: Boolean def haveInteractiveConsole: Boolean - def viMode: Boolean = envOrNone("SHELLOPTS").map(_.split(":").contains("vi")).getOrElse(false) // source compatibility, i.e., -Xsource def xsource: String diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleHistory.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleHistory.scala index ab13a0ee397d..1f8810a5baa1 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleHistory.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleHistory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleReader.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleReader.scala index b92c8f7e7051..50bb4d65ff01 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleReader.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/SimpleReader.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Tabulators.scala b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Tabulators.scala index d93cb973f1cd..3b864eb10d75 100644 --- a/src/repl-frontend/scala/tools/nsc/interpreter/shell/Tabulators.scala +++ b/src/repl-frontend/scala/tools/nsc/interpreter/shell/Tabulators.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala b/src/repl/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala index 3044eec2c8a9..0be1ce5ce6d3 100644 --- a/src/repl/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala +++ b/src/repl/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala index ed808c56d6cd..71b3927477f8 100644 --- a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala +++ b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index afd23b48992d..102e83c02ab1 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -10,8 +10,6 @@ * additional information regarding copyright ownership. */ -// Copyright 2005-2017 LAMP/EPFL and Lightbend, Inc. - package scala.tools.nsc.interpreter import java.io.{Closeable, PrintWriter, StringWriter} @@ -19,9 +17,9 @@ import java.net.URL import scala.collection.mutable, mutable.ListBuffer import scala.language.implicitConversions import scala.reflect.{ClassTag, classTag} +import scala.reflect.internal.{FatalError, Flags, MissingRequirementError, NoPhase, Precedence} import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader import scala.reflect.internal.util.{AbstractFileClassLoader, BatchSourceFile, ListOfNil, Position, ReplBatchSourceFile, SourceFile} -import scala.reflect.internal.{FatalError, Flags, MissingRequirementError, NoPhase} import scala.reflect.runtime.{universe => ru} import scala.tools.nsc.{Global, Settings} import scala.tools.nsc.interpreter.Results.{Error, Incomplete, Result, Success} @@ -362,10 +360,7 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade } } private def makeClassLoader(): AbstractFileClassLoader = - new TranslatingClassLoader({ - _runtimeClassLoader = new URLClassLoader(compilerClasspath, parentClassLoader) - _runtimeClassLoader - }) + new TranslatingClassLoader(new URLClassLoader(compilerClasspath, parentClassLoader).tap(_runtimeClassLoader_=)) def allDefinedNames: List[Name] = exitingTyper(replScope.toList.map(_.name).sorted) def unqualifiedIds: List[String] = allDefinedNames.map(_.decode).sorted @@ -400,9 +395,7 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade replScope enter sym } - def recordRequest(req: Request): Unit = { - if (req == null) - return + def recordRequest(req: Request): Unit = if (req != null) { prevRequests += req @@ -621,16 +614,14 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade override lazy val power = new Power(this, new StdReplVals(this))(tagOfStdReplVals, classTag[StdReplVals]) /** Here is where we: - * - * 1) Read some source code, and put it in the "read" object. - * 2) Evaluate the read object, and put the result in the "eval" object. - * 3) Create a String for human consumption, and put it in the "print" object. - * - * Read! Eval! Print! Some of that not yet centralized here. - */ - class ReadEvalPrint(val lineId: Int) { - def this() = this(freshLineId()) - + * + * 1) Read some source code, and put it in the "read" object. + * 2) Evaluate the read object, and put the result in the "eval" object. + * 3) Create a String for human consumption, and put it in the "print" object. + * + * Read! Eval! Print! Some of that not yet centralized here. + */ + class ReadEvalPrint(val lineId: Int = freshLineId()) { val packageName = sessionNames.packageName(lineId) val readName = sessionNames.read val evalName = sessionNames.eval @@ -813,6 +804,7 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade case init :+ tree => def loop(scrut: Tree): Tree = scrut match { case _: Assign => tree + case Apply(Select(_, op), _) if Precedence(op.decoded).level == 0 => tree case _: RefTree | _: TermTree => storeInVal(tree) case Annotated(_, arg) => loop(arg) case _ => tree @@ -823,7 +815,7 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade } /** handlers for each tree in this request */ - val handlers: List[MemberHandler] = trees map (memberHandlers chooseHandler _) + val handlers: List[MemberHandler] = trees.map(memberHandlers.chooseHandler(_)) val definesValueClass = handlers.exists(_.definesValueClass) val isClassBased = IMain.this.isClassBased && !definesValueClass @@ -967,11 +959,21 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade /** Compile the object file. Returns whether the compilation succeeded. - * If all goes well, the "types" map is computed. */ + * If all goes well, the "types" map is computed. + */ def compile: Boolean = { + val compiledOK = + if (origTrees.forall(_.isInstanceOf[Import])) { + //settings.Wconf.value ::= "cat=unused-imports:s" // alternatively, suppression is effective + val saved = settings.warnUnused.value + settings.warnUnused.value -= settings.UnusedWarnings.Imports + try lineRep.compile(mkUnit) + finally settings.warnUnused.value = saved + } + else lineRep.compile(mkUnit) // compile the object containing the user's code - lineRep.compile(mkUnit) && { + compiledOK && { // extract and remember types typeOf typesOfDefinedTerms @@ -1100,11 +1102,11 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade } /** It's a bit of a shotgun approach, but for now we will gain in - * robustness. Try a symbol-producing operation at phase typer, and - * if that is NoSymbol, try again at phase flatten. I'll be able to - * lose this and run only from exitingTyper as soon as I figure out - * exactly where a flat name is sneaking in when calculating imports. - */ + * robustness. Try a symbol-producing operation at phase typer, and + * if that is NoSymbol, try again at phase flatten. I'll be able to + * lose this and run only from exitingTyper as soon as I figure out + * exactly where a flat name is sneaking in when calculating imports. + */ def tryTwice(op: => Symbol): Symbol = exitingTyper(op) orElse exitingFlatten(op) def symbolOfIdent(id: String): Symbol = symbolOfType(id) orElse symbolOfTerm(id) diff --git a/src/repl/scala/tools/nsc/interpreter/Imports.scala b/src/repl/scala/tools/nsc/interpreter/Imports.scala index ed82330d9da1..b562e79ecf7b 100644 --- a/src/repl/scala/tools/nsc/interpreter/Imports.scala +++ b/src/repl/scala/tools/nsc/interpreter/Imports.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/Interface.scala b/src/repl/scala/tools/nsc/interpreter/Interface.scala index efd1ed7487c8..65d02e1e34d7 100644 --- a/src/repl/scala/tools/nsc/interpreter/Interface.scala +++ b/src/repl/scala/tools/nsc/interpreter/Interface.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -10,8 +10,6 @@ * additional information regarding copyright ownership. */ -// Copyright 2002-2017 LAMP/EPFL and Lightbend, Inc. - package scala.tools.nsc.interpreter import java.io.PrintWriter import java.net.URL diff --git a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala index 9bcd6f81af41..4c31f411bae4 100644 --- a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,6 +15,7 @@ package scala.tools.nsc.interpreter import scala.language.implicitConversions import scala.collection.mutable +import scala.reflect.internal.Precedence trait MemberHandlers { val intp: IMain @@ -77,7 +78,9 @@ trait MemberHandlers { case member: ModuleDef => new ModuleHandler(member) case member: ClassDef => new ClassHandler(member) case member: TypeDef => new TypeAliasHandler(member) - case member: Assign => new AssignHandler(member) + case member: Assign => AssignHandler(member) + case member @ Apply(Select(_, op), _) + if Precedence(op.decoded).level == 0 => AssignHandler(member) case member: Import => new ImportHandler(member.duplicate) // duplicate because the same tree will be type checked (which loses info) case DocDef(_, documented) => chooseHandler(documented) case member => new GenericHandler(member) @@ -175,9 +178,16 @@ trait MemberHandlers { def notification(req: Request) = s"def ${req.defTypeOf(name)}" } - class AssignHandler(member: Assign) extends MemberHandler(member) { + class AssignHandler private (member: Tree, lhs: Tree) extends MemberHandler(member) { override def resultExtractionCode(req: Request) = - codegenln(s"// mutated ${member.lhs}") + codegenln(s"// mutated $lhs") + } + object AssignHandler { + def apply(member: Assign) = new AssignHandler(member, member.lhs) + def apply(member: Apply) = member match { + case Apply(Select(qual, op), _) if Precedence(op.decoded).level == 0 => new AssignHandler(member, qual) + case _ => new GenericHandler(member) + } } class ModuleHandler(module: ModuleDef) extends MemberDefHandler(module) { diff --git a/src/repl/scala/tools/nsc/interpreter/NamedParam.scala b/src/repl/scala/tools/nsc/interpreter/NamedParam.scala index 709c5f2723e2..bb8939dba85b 100644 --- a/src/repl/scala/tools/nsc/interpreter/NamedParam.scala +++ b/src/repl/scala/tools/nsc/interpreter/NamedParam.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/Naming.scala b/src/repl/scala/tools/nsc/interpreter/Naming.scala index 5b6dab253480..160aeb31e61d 100644 --- a/src/repl/scala/tools/nsc/interpreter/Naming.scala +++ b/src/repl/scala/tools/nsc/interpreter/Naming.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/Phased.scala b/src/repl/scala/tools/nsc/interpreter/Phased.scala index 3364a3ffd5a0..97d33fcbcd6f 100644 --- a/src/repl/scala/tools/nsc/interpreter/Phased.scala +++ b/src/repl/scala/tools/nsc/interpreter/Phased.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/Power.scala b/src/repl/scala/tools/nsc/interpreter/Power.scala index a0199a407220..18245ace5cf5 100644 --- a/src/repl/scala/tools/nsc/interpreter/Power.scala +++ b/src/repl/scala/tools/nsc/interpreter/Power.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala b/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala index bc04c6a2968e..5296d83e3673 100644 --- a/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala +++ b/src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/ReplDir.scala b/src/repl/scala/tools/nsc/interpreter/ReplDir.scala index fd0232c7ab95..36774710408f 100644 --- a/src/repl/scala/tools/nsc/interpreter/ReplDir.scala +++ b/src/repl/scala/tools/nsc/interpreter/ReplDir.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala b/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala index 28d77c090a30..552395fd47f1 100644 --- a/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala +++ b/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/ReplStrings.scala b/src/repl/scala/tools/nsc/interpreter/ReplStrings.scala index 606938af8cec..43cff93e8cf1 100644 --- a/src/repl/scala/tools/nsc/interpreter/ReplStrings.scala +++ b/src/repl/scala/tools/nsc/interpreter/ReplStrings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/ReplVals.scala b/src/repl/scala/tools/nsc/interpreter/ReplVals.scala index 1213c99c117f..0a7816f5443f 100644 --- a/src/repl/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/repl/scala/tools/nsc/interpreter/ReplVals.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/Results.scala b/src/repl/scala/tools/nsc/interpreter/Results.scala index e8eccd0ccb65..71085d89fbd4 100644 --- a/src/repl/scala/tools/nsc/interpreter/Results.scala +++ b/src/repl/scala/tools/nsc/interpreter/Results.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/Scripted.scala b/src/repl/scala/tools/nsc/interpreter/Scripted.scala index 02c7af78f689..618ec57b16f4 100644 --- a/src/repl/scala/tools/nsc/interpreter/Scripted.scala +++ b/src/repl/scala/tools/nsc/interpreter/Scripted.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/repl/scala/tools/nsc/interpreter/StdReplTags.scala b/src/repl/scala/tools/nsc/interpreter/StdReplTags.scala index 5ee32ffe8d6a..270ea4c439cc 100644 --- a/src/repl/scala/tools/nsc/interpreter/StdReplTags.scala +++ b/src/repl/scala/tools/nsc/interpreter/StdReplTags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/API.scala b/src/sbt-bridge/scala/tools/xsbt/API.scala index dea7d40aad0a..2932813cae37 100644 --- a/src/sbt-bridge/scala/tools/xsbt/API.scala +++ b/src/sbt-bridge/scala/tools/xsbt/API.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/AbstractZincFile.scala b/src/sbt-bridge/scala/tools/xsbt/AbstractZincFile.scala index 35a388beacd4..c776e6276bd4 100644 --- a/src/sbt-bridge/scala/tools/xsbt/AbstractZincFile.scala +++ b/src/sbt-bridge/scala/tools/xsbt/AbstractZincFile.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,7 +16,6 @@ package scala.tools package xsbt import xsbti.{ PathBasedFile, VirtualFile } -import scala.reflect.io.Streamable private trait AbstractZincFile extends scala.reflect.io.AbstractFile { def underlying: VirtualFile @@ -29,7 +28,22 @@ private final class ZincPlainFile private[xsbt] (val underlying: PathBasedFile) private final class ZincVirtualFile private[xsbt] (val underlying: VirtualFile) extends scala.reflect.io.VirtualFile(underlying.name, underlying.id) with AbstractZincFile { - Streamable.closing(output)(_.write(Streamable.bytes(underlying.input))) // fill in the content + val buffer = new Array[Byte](4096) + + val in = underlying.input() + val output0 = output + + try { + var readBytes = in.read(buffer) + + while (readBytes != -1) { + output0.write(buffer, 0, readBytes) + readBytes = in.read(buffer) + } + } finally { + in.close() + output0.close() + } } private object AbstractZincFile { diff --git a/src/sbt-bridge/scala/tools/xsbt/Analyzer.scala b/src/sbt-bridge/scala/tools/xsbt/Analyzer.scala index fc7975bcade8..703b4d89c253 100644 --- a/src/sbt-bridge/scala/tools/xsbt/Analyzer.scala +++ b/src/sbt-bridge/scala/tools/xsbt/Analyzer.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/CallbackGlobal.scala b/src/sbt-bridge/scala/tools/xsbt/CallbackGlobal.scala index dab656c1fbcd..03c8104ec669 100644 --- a/src/sbt-bridge/scala/tools/xsbt/CallbackGlobal.scala +++ b/src/sbt-bridge/scala/tools/xsbt/CallbackGlobal.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,7 +15,7 @@ package scala.tools package xsbt -import xsbti.{AnalysisCallback, Severity} +import xsbti.{AnalysisCallback, AnalysisCallback3, Severity} import xsbti.compile._ import scala.tools.nsc._ @@ -23,6 +23,7 @@ import io.AbstractFile import java.nio.file.{Files, Path} import scala.reflect.NameTransformer import scala.reflect.io.PlainFile +import scala.reflect.internal.util.BatchSourceFile /** Defines the interface of the incremental compiler hiding implementation details. */ sealed abstract class CallbackGlobal( @@ -82,6 +83,23 @@ sealed class ZincCompiler(settings: Settings, dreporter: DelegatingReporter, out extends CallbackGlobal(settings, dreporter, output) with ZincGlobalCompat { + // AnalysisCallback3 only exists in recent Zinc + private lazy val callback3Opt = + try Some(callback.asInstanceOf[AnalysisCallback3]) + catch { + case _: NoClassDefFoundError => + None + } + + override def getSourceFile(f: AbstractFile): BatchSourceFile = { + val file = (f, callback3Opt) match { + case (plainFile: PlainFile, Some(callback3)) => + AbstractZincFile(callback3.toVirtualFile(plainFile.file.toPath)) + case _ => f + } + super.getSourceFile(file) + } + final class ZincRun(compileProgress: CompileProgress) extends Run { override def informUnitStarting(phase: Phase, unit: CompilationUnit): Unit = { compileProgress.startUnit(phase.name, unit.source.path) diff --git a/src/sbt-bridge/scala/tools/xsbt/ClassName.scala b/src/sbt-bridge/scala/tools/xsbt/ClassName.scala index 910c1f389317..404ee8269427 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ClassName.scala +++ b/src/sbt-bridge/scala/tools/xsbt/ClassName.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/Compat.scala b/src/sbt-bridge/scala/tools/xsbt/Compat.scala index 167d0b1fffd7..92694286313a 100644 --- a/src/sbt-bridge/scala/tools/xsbt/Compat.scala +++ b/src/sbt-bridge/scala/tools/xsbt/Compat.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/CompilerBridge.scala b/src/sbt-bridge/scala/tools/xsbt/CompilerBridge.scala index 2495699061c8..f1bd21e9e32e 100644 --- a/src/sbt-bridge/scala/tools/xsbt/CompilerBridge.scala +++ b/src/sbt-bridge/scala/tools/xsbt/CompilerBridge.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/ConsoleBridge.scala b/src/sbt-bridge/scala/tools/xsbt/ConsoleBridge.scala index 5cfd6321362e..b7f2cce74c38 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ConsoleBridge.scala +++ b/src/sbt-bridge/scala/tools/xsbt/ConsoleBridge.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/DelegatingReporter.scala b/src/sbt-bridge/scala/tools/xsbt/DelegatingReporter.scala index 62bf0fda6d19..2c1811a1549f 100644 --- a/src/sbt-bridge/scala/tools/xsbt/DelegatingReporter.scala +++ b/src/sbt-bridge/scala/tools/xsbt/DelegatingReporter.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/Dependency.scala b/src/sbt-bridge/scala/tools/xsbt/Dependency.scala index 38b4c548a918..9bf03b4addba 100644 --- a/src/sbt-bridge/scala/tools/xsbt/Dependency.scala +++ b/src/sbt-bridge/scala/tools/xsbt/Dependency.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/ExtractAPI.scala b/src/sbt-bridge/scala/tools/xsbt/ExtractAPI.scala index bc36237f98d0..2d4d26fb435a 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ExtractAPI.scala +++ b/src/sbt-bridge/scala/tools/xsbt/ExtractAPI.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/ExtractUsedNames.scala b/src/sbt-bridge/scala/tools/xsbt/ExtractUsedNames.scala index 135a5069652f..11e388f644c4 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ExtractUsedNames.scala +++ b/src/sbt-bridge/scala/tools/xsbt/ExtractUsedNames.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/GlobalHelpers.scala b/src/sbt-bridge/scala/tools/xsbt/GlobalHelpers.scala index 5c1a4eb5fce6..2096a368dcf6 100644 --- a/src/sbt-bridge/scala/tools/xsbt/GlobalHelpers.scala +++ b/src/sbt-bridge/scala/tools/xsbt/GlobalHelpers.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleBridge.scala b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleBridge.scala index 7e033cf14594..357fd844d86b 100644 --- a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleBridge.scala +++ b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleBridge.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleFactoryBridge.scala b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleFactoryBridge.scala index af5ee88bd3ec..9b21dcbf03d5 100644 --- a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleFactoryBridge.scala +++ b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleFactoryBridge.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleHelper.scala b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleHelper.scala index 159dc024c09f..04d3b24b6245 100644 --- a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleHelper.scala +++ b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleHelper.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleResponse.scala b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleResponse.scala index bbb6288b01a1..389ff6e28e65 100644 --- a/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleResponse.scala +++ b/src/sbt-bridge/scala/tools/xsbt/InteractiveConsoleResponse.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/JarUtils.scala b/src/sbt-bridge/scala/tools/xsbt/JarUtils.scala index 0a0253faf5d9..f07b04937818 100644 --- a/src/sbt-bridge/scala/tools/xsbt/JarUtils.scala +++ b/src/sbt-bridge/scala/tools/xsbt/JarUtils.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/JavaUtils.scala b/src/sbt-bridge/scala/tools/xsbt/JavaUtils.scala index b71d126379f2..bc8092757676 100644 --- a/src/sbt-bridge/scala/tools/xsbt/JavaUtils.scala +++ b/src/sbt-bridge/scala/tools/xsbt/JavaUtils.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/LocalToNonLocalClass.scala b/src/sbt-bridge/scala/tools/xsbt/LocalToNonLocalClass.scala index a8a500703e13..a4bd28a98423 100644 --- a/src/sbt-bridge/scala/tools/xsbt/LocalToNonLocalClass.scala +++ b/src/sbt-bridge/scala/tools/xsbt/LocalToNonLocalClass.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/LocateClassFile.scala b/src/sbt-bridge/scala/tools/xsbt/LocateClassFile.scala index 0edb4c4cd5de..ec19940628dd 100644 --- a/src/sbt-bridge/scala/tools/xsbt/LocateClassFile.scala +++ b/src/sbt-bridge/scala/tools/xsbt/LocateClassFile.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/Log.scala b/src/sbt-bridge/scala/tools/xsbt/Log.scala index 713849714c3b..d5699fbdfd02 100644 --- a/src/sbt-bridge/scala/tools/xsbt/Log.scala +++ b/src/sbt-bridge/scala/tools/xsbt/Log.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/Message.scala b/src/sbt-bridge/scala/tools/xsbt/Message.scala index 9b3a2088eaa0..2227bb806aed 100644 --- a/src/sbt-bridge/scala/tools/xsbt/Message.scala +++ b/src/sbt-bridge/scala/tools/xsbt/Message.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/ReflectAccess.java b/src/sbt-bridge/scala/tools/xsbt/ReflectAccess.java index 9a21a9b76108..c34f46061020 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ReflectAccess.java +++ b/src/sbt-bridge/scala/tools/xsbt/ReflectAccess.java @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/ScaladocBridge.scala b/src/sbt-bridge/scala/tools/xsbt/ScaladocBridge.scala index a17cd55b43c3..4fdf0d8b4252 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ScaladocBridge.scala +++ b/src/sbt-bridge/scala/tools/xsbt/ScaladocBridge.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/sbt-bridge/scala/tools/xsbt/ZincCompat.scala b/src/sbt-bridge/scala/tools/xsbt/ZincCompat.scala index 625e79256fc4..846d7cb1b490 100644 --- a/src/sbt-bridge/scala/tools/xsbt/ZincCompat.scala +++ b/src/sbt-bridge/scala/tools/xsbt/ZincCompat.scala @@ -1,9 +1,9 @@ /* * Zinc - The incremental compiler for Scala. - * Copyright Scala Center, Lightbend, and Mark Harrah + * Copyright Scala Center, Lightbend dba Akka, and Mark Harrah * * Scala (https://www.scala-lang.org) - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/ScalaDoc.scala b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala index 3ddbe03c9b35..03abcfbee897 100644 --- a/src/scaladoc/scala/tools/nsc/ScalaDoc.scala +++ b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -21,35 +21,38 @@ import scala.reflect.internal.util.{FakePos, Position} * that generates documentation from source files. */ class ScalaDoc { + import ScalaDoc._ val versionMsg = s"Scaladoc ${Properties.versionString} -- ${Properties.copyrightString}" def process(args: Array[String]): Boolean = { var reporter: ScalaDocReporter = null - val docSettings = new doc.Settings(msg => reporter.error(FakePos("scaladoc"), msg + "\n scaladoc -help gives more information"), + val docSettings = new doc.Settings(msg => reporter.error(NoDocPos, s"$msg\n scaladoc -help gives more information"), msg => reporter.echo(msg), DefaultPathFactory) reporter = new ScalaDocReporter(docSettings) - val command = new ScalaDoc.Command(args.toList, docSettings) + val command = new Command(args.toList, docSettings) def hasFiles = command.files.nonEmpty || docSettings.uncompilableFiles.nonEmpty - if (docSettings.version.value) + if (!command.ok) + () + else if (docSettings.version.value) reporter.echo(versionMsg) else if (docSettings.Xhelp.value) reporter.echo(command.xusageMsg) else if (docSettings.Yhelp.value) reporter.echo(command.yusageMsg) else if (docSettings.showPlugins.value) - reporter.warning(null, "Plugins are not available when using Scaladoc") + reporter.warning(NoDocPos, "Plugins are not available when using Scaladoc") else if (docSettings.showPhases.value) - reporter.warning(null, "Phases are restricted when using Scaladoc") + reporter.warning(NoDocPos, s"Phases are restricted when using Scaladoc.\n${new DocFactory(reporter, docSettings).compiler.phaseDescriptions}") else if (docSettings.help.value || !hasFiles) reporter.echo(command.usageMsg) else - try { new DocFactory(reporter, docSettings) document command.files } + try new DocFactory(reporter, docSettings).document(command.files) catch { case ex @ FatalError(msg) => if (docSettings.isDebug) ex.printStackTrace() - reporter.error(null, "fatal error: " + msg) + reporter.error(NoDocPos, s"fatal error: $msg") } finally reporter.finish() @@ -86,13 +89,14 @@ class ScalaDocReporter(settings: Settings) extends ConsoleReporter(settings) { } object ScalaDoc extends ScalaDoc { + val NoDocPos = FakePos("scaladoc") + class Command(arguments: List[String], settings: doc.Settings) extends CompilerCommand(arguments, settings) { override def cmdName = "scaladoc" - override def usageMsg = ( - createUsageMsg("where possible scaladoc", explain = false)(x => x.isStandard && settings.isScaladocSpecific(x.name)) + - "\n\nStandard scalac options also available:" + - optionsMessage(x => x.isStandard && !settings.isScaladocSpecific(x.name)) - ) + override def usageMsg = + sm"""${createUsageMsg("where possible scaladoc", explain = false)(x => x.isStandard && settings.isScaladocSpecific(x.name))} + |Standard scalac options also available: + |${optionsMessage(x => x.isStandard && !settings.isScaladocSpecific(x.name))}""" } def main(args: Array[String]): Unit = { diff --git a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala index b818882f51e8..66ef684eb00c 100644 --- a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/DocParser.scala b/src/scaladoc/scala/tools/nsc/doc/DocParser.scala index e23b33e1f8c6..099fb17465be 100644 --- a/src/scaladoc/scala/tools/nsc/doc/DocParser.scala +++ b/src/scaladoc/scala/tools/nsc/doc/DocParser.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -15,6 +15,7 @@ package nsc package doc import scala.reflect.internal.util._ +import scala.tools.nsc.backend.JavaPlatform import scala.tools.nsc.doc.DocParser.Parsed import scala.tools.nsc.reporters.{ConsoleReporter, Reporter} @@ -23,13 +24,24 @@ import scala.tools.nsc.reporters.{ConsoleReporter, Reporter} * otherwise cause the compiler to go haywire. */ class DocParser(settings: nsc.Settings, reporter: Reporter) extends Global(settings, reporter) with ScaladocGlobalTrait { + self => def this(settings: Settings) = this(settings, new ConsoleReporter(settings)) def this() = this(new Settings(Console println _)) // the usual global initialization locally { new Run() } - override protected def computeInternalPhases(): Unit = phasesSet += syntaxAnalyzer + override protected def computeInternalPhases(): Unit = { + phasesSet += syntaxAnalyzer + phasesSet += terminal + } + override protected def computePluginPhases(): Unit = () + + override lazy val platform: ThisPlatform = + new JavaPlatform { + lazy val global: self.type = self + override def platformPhases = Nil // used by computePlatformPhases + } /** Returns a list of `DocParser.Parseds`, which hold the DocDefs found * in the given code along with the surrounding trees. diff --git a/src/scaladoc/scala/tools/nsc/doc/Index.scala b/src/scaladoc/scala/tools/nsc/doc/Index.scala index 27896013ddcd..62563eca587c 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Index.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Index.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala index e361e7299010..22cec6c99f0e 100644 --- a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala index 3f1bbf1701fd..da39d3adee61 100644 --- a/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -13,6 +13,7 @@ package scala.tools.nsc package doc +import scala.tools.nsc.backend.JavaPlatform import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.typechecker.MacroAnnotationNamers @@ -30,6 +31,7 @@ trait ScaladocGlobalTrait extends Global { override lazy val syntaxAnalyzer = new ScaladocSyntaxAnalyzer[outer.type](outer) { val runsAfter = List[String]() val runsRightAfter = None + override val initial = true } override lazy val loaders = new { @@ -46,12 +48,21 @@ trait ScaladocGlobalTrait extends Global { // takes a `Reporter`, not `FilteringReporter` for sbt compatibility class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends Global(settings, reporter) with ScaladocGlobalTrait { + self => override protected def computeInternalPhases(): Unit = { phasesSet += syntaxAnalyzer phasesSet += analyzer.namerFactory phasesSet += analyzer.packageObjects phasesSet += analyzer.typerFactory + phasesSet += terminal } + + override lazy val platform: ThisPlatform = + new JavaPlatform { + lazy val global: self.type = self + override def platformPhases = Nil // used by computePlatformPhases + } + override def createJavadoc = if (settings.docNoJavaComments.value) false else true override lazy val analyzer = diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index e66cba52b850..8a4e1fa0af33 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -59,7 +59,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_), val docfooter = StringSetting ( "-doc-footer", "footer", - "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", + "A footer on every Scaladoc page, by default the EPFL/Akka copyright notice. Can be overridden with a custom footer.", "" ) @@ -249,8 +249,8 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_), ) // For improved help output. - def scaladocSpecific = Set[Settings#Setting]( - docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator, docRootContent, + def scalaDocSpecific = Set[Settings#Setting]( + outdir, docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator, docRootContent, docExternalDoc, docAuthor, docDiagrams, docDiagramsDebug, docDiagramsDotPath, docDiagramsDotTimeout, docDiagramsDotRestart, @@ -258,8 +258,8 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_), docDiagramsMaxNormalClasses, docDiagramsMaxImplicitClasses, docNoPrefixes, docNoLinkWarnings, docRawOutput, docSkipPackages, docExpandAllTypes, docGroups, docNoJavaComments - ).map(s => s.withAbbreviation("-" + s.name)) - val isScaladocSpecific: String => Boolean = scaladocSpecific map (_.name) + ).map(s => s.withAbbreviation(s"-${s.name}")) + val isScaladocSpecific: String => Boolean = scalaDocSpecific.map(_.name) override def isScaladoc = true diff --git a/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala b/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala index 6494a3d49008..c3b30b0de692 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/Universe.scala b/src/scaladoc/scala/tools/nsc/doc/Universe.scala index c6c6aa645304..afcae5acb74b 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Universe.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Universe.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala index 2c2c689bfa41..bbcec528860c 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala index 7703c4711d0f..54c06fe0fa9a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala index 4a5c6bf7662b..87f10c724709 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala index 5a4384812ef6..1c86ab6339b2 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala index 657a8b67a696..c32121363798 100644 --- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala index 3e920268cd7a..a6e8e524af77 100644 --- a/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala index 7c7cda7bc7de..6cf0d4945a08 100644 --- a/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala index 2e1d196a0294..54689128094a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala index ade33a465d0c..a3a31bf8dc5c 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala index abf91216d1cc..acaf4c2c8a20 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlTags.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlTags.scala index 55792f6ad941..f954cf64a39e 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlTags.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlTags.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala index bfbe2fea7626..b7d18227388a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/Page.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala index 7d48ce2e656e..80540b08172b 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala index aac43180d071..87200be1e7fa 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Entity.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -341,7 +341,7 @@ trait EntityPage extends HtmlPage { val postamble = List(Div(id = "tooltip"), if (Set("epfl", "EPFL").contains(tpl.universe.settings.docfooter.value)) - Div(id = "footer", elems = Txt("Scala programming documentation. Copyright (c) 2002-2024 ") :: A(href = "https://www.epfl.ch", target = "_top", elems = Txt("EPFL")) :: Txt(" and ") :: A(href = "https://www.lightbend.com", target = "_top", elems = Txt("Lightbend")) :: Txt(".")) + Div(id = "footer", elems = Txt("Scala programming documentation. Copyright (c) 2002-2025 ") :: A(href = "https://www.epfl.ch", target = "_top", elems = Txt("EPFL")) :: Txt(" and ") :: A(href = "https://akka.io", target = "_top", elems = Txt("Akka")) :: Txt(".")) else Div(id = "footer", elems = Txt(tpl.universe.settings.docfooter.value))) @@ -687,10 +687,10 @@ trait EntityPage extends HtmlPage { val exceptions: Elems = orEmpty(comment.throws) { dt("Exceptions thrown") :: - Dd(elems= { + Dd(elems = { val exceptionsXml: List[Elems] = - for((name, body) <- comment.throws.toList.sortBy(_._1) ) yield - Span(`class`= "cmt", elems= bodyToHtml(body)) :: NoElems + for ((name@_, body) <- comment.throws.toList.sortBy(_._1)) + yield Span(`class` = "cmt", elems = bodyToHtml(body)) :: NoElems exceptionsXml.reduceLeft(_ ++ Txt("") ++ _) }) } @@ -698,8 +698,10 @@ trait EntityPage extends HtmlPage { val todo: Elems = orEmpty(comment.todo) { dt("To do") :: - Dd(elems= { - val todoXml: List[Elems] = for(todo <- comment.todo ) yield Span(`class`= "cmt", elems= bodyToHtml(todo)) :: NoElems + Dd(elems = { + val todoXml: List[Elems] = + for (todo <- comment.todo) + yield Span(`class` = "cmt", elems = bodyToHtml(todo)) :: NoElems todoXml.reduceLeft(_ ++ _) }) } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala index ee8c63842166..eb32bf1dfaa1 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala index 786e0628f848..2070531c6e4a 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/JSON.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala index b1b76370a1ca..5c65d55c152c 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala index b39af56ec0f4..4a0177c5f690 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala index 948203ef80c9..3360743a94ff 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css index 129744778421..c58d25dd0d94 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css @@ -321,10 +321,6 @@ dl.attributes > dd { font-style: italic; } -#inheritedMembers > div.parent > h3 * { - color: white; -} - #inheritedMembers > div.conversion > h3 { height: 2em; padding: 1em; diff --git a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala index 94f9afd42f4f..4979bde28288 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala index 6bc2b15a5ea5..6059a1d9bbeb 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala index 171d85f95e6c..7bafff6e9701 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala index 404a10216cdf..997844fe6338 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -62,7 +62,7 @@ trait MemberLookup extends base.MemberLookupBase { else sym classpathEntryFor(sym1) flatMap { path => if (isJDK(sym1)) { - Some(LinkToExternalTpl(name, jdkUrl(path), makeTemplate(sym))) + Some(LinkToExternalTpl(name, jdkUrl(path, sym1), makeTemplate(sym))) } else { settings.extUrlMapping get path map { url => @@ -100,11 +100,35 @@ trait MemberLookup extends base.MemberLookupBase { private def isJDK(sym: Symbol) = sym.associatedFile.underlyingSource.map(f => isChildOf(f, (sys.props("java.home")))).getOrElse(false) - def jdkUrl(path: String): String = { - if (path.endsWith(".jmod")) { + // ISSUE-12820 + import scala.util.Try + private lazy val classGetModule = Try { + val clazz = Class.forName("java.lang.Class") + clazz.getMethod("getModule") + }.toOption + private lazy val moduleGetName = Try { + val clazz = Class.forName("java.lang.Module") + clazz.getMethod("getName") + }.toOption + + def jdkUrl(path: String, sym: Symbol): String = { + if (path.endsWith(".jmod") && javaVersion >= 11) { val tokens = path.split(java.io.File.separatorChar) val module = tokens.last.stripSuffix(".jmod") s"$jdkUrl/$module" + } else if (path.endsWith("ct.sym") && javaVersion >= 11) { + (for { + clazz <- Try(Class.forName(sym.javaClassName)).toOption + getModule <- classGetModule + module <- Try(getModule.invoke(clazz)).toOption + getModuleName <- moduleGetName + moduleName <- + Try(getModuleName.invoke(module)).toOption + .map(Option(_)) + .flatten + } yield { + s"$jdkUrl/$moduleName" + }).getOrElse(jdkUrl) } else { jdkUrl @@ -128,11 +152,15 @@ trait MemberLookup extends base.MemberLookupBase { } lazy val javaVersion: Int = - System.getProperty("java.specification.version").split('.').take(2).map(_.toIntOption) match { - case Array(Some(1), Some(n)) => n // example: 1.8.0_242 - case Array(Some(n)) => n // example: 14 - case Array(Some(n), _) => n // example: 11.0.7 - case _ => 8 // shrug! + global.settings.releaseValue + .getOrElse(scala.util.Properties.javaSpecVersion) + .split('.') + .take(2) + .map(_.toIntOption) match { + case Array(Some(1), Some(n)) => n // example: 1.8.0_242 + case Array(Some(n)) => n // example: 14 + case Array(Some(n), _) => n // example: 11.0.7 + case _ => 8 // shrug! } override def warnNoLink = !settings.docNoLinkWarnings.value diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index 2f15618b6e7e..fa0efbb1f381 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index b39d0ffcd8d3..8dd03c2144ba 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala index 5354fb4d175f..76b24c60e8df 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala index 843dc2916d80..f03c21e4473c 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala index 491f3fc3c084..4bd809056812 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala b/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala index b640c24a4e43..ef585a45e275 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala b/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala index 8f5f090fc40c..628a5ff5dbf6 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala b/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala index 35aff9afcf50..90f09e65232f 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala index 6116d945700d..d098913e0174 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala index 8c88a619c7a0..53a894a37cdc 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala index efcbba780fb4..775e260c9d80 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/decoder.properties b/src/scalap/decoder.properties index e27b29c0e13d..4d93c411f774 100644 --- a/src/scalap/decoder.properties +++ b/src/scalap/decoder.properties @@ -1,2 +1,2 @@ version.number=2.0.1 -copyright.string=(c) 2002-2024 LAMP/EPFL +copyright.string=(c) 2002-2025 LAMP/EPFL diff --git a/src/scalap/scala/tools/scalap/Arguments.scala b/src/scalap/scala/tools/scalap/Arguments.scala index e404fb7fbe04..a9a26036ffb9 100644 --- a/src/scalap/scala/tools/scalap/Arguments.scala +++ b/src/scalap/scala/tools/scalap/Arguments.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/ByteArrayReader.scala b/src/scalap/scala/tools/scalap/ByteArrayReader.scala index 4d26588fecc8..c52e32c25d22 100644 --- a/src/scalap/scala/tools/scalap/ByteArrayReader.scala +++ b/src/scalap/scala/tools/scalap/ByteArrayReader.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/Classfile.scala b/src/scalap/scala/tools/scalap/Classfile.scala index 2511bf6a4ba4..9e2f4d5b9d89 100644 --- a/src/scalap/scala/tools/scalap/Classfile.scala +++ b/src/scalap/scala/tools/scalap/Classfile.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/Classfiles.scala b/src/scalap/scala/tools/scalap/Classfiles.scala index df3403b46079..5796596080c2 100644 --- a/src/scalap/scala/tools/scalap/Classfiles.scala +++ b/src/scalap/scala/tools/scalap/Classfiles.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/CodeWriter.scala b/src/scalap/scala/tools/scalap/CodeWriter.scala index 4c6097f30720..1e36aaad5d10 100644 --- a/src/scalap/scala/tools/scalap/CodeWriter.scala +++ b/src/scalap/scala/tools/scalap/CodeWriter.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/Decode.scala b/src/scalap/scala/tools/scalap/Decode.scala index ccde1fa888a0..0de24ec93ccd 100644 --- a/src/scalap/scala/tools/scalap/Decode.scala +++ b/src/scalap/scala/tools/scalap/Decode.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/JavaWriter.scala b/src/scalap/scala/tools/scalap/JavaWriter.scala index 916303d657d3..ef15bfb5697d 100644 --- a/src/scalap/scala/tools/scalap/JavaWriter.scala +++ b/src/scalap/scala/tools/scalap/JavaWriter.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala index dacc8a1f8ac0..8e51efabd766 100644 --- a/src/scalap/scala/tools/scalap/Main.scala +++ b/src/scalap/scala/tools/scalap/Main.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/MetaParser.scala b/src/scalap/scala/tools/scalap/MetaParser.scala index 331a7a97e8f3..9f70acd15359 100644 --- a/src/scalap/scala/tools/scalap/MetaParser.scala +++ b/src/scalap/scala/tools/scalap/MetaParser.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/Properties.scala b/src/scalap/scala/tools/scalap/Properties.scala index 5058d9d5932b..3203f8833baa 100644 --- a/src/scalap/scala/tools/scalap/Properties.scala +++ b/src/scalap/scala/tools/scalap/Properties.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala index bd958c2ab221..8f54c291c53d 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala index e7b7c78a901f..ff03e1e399ec 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala index cbc0b53960f5..b61c416d2026 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala index 9358bc813d07..99618177a4d0 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala index 8b5616b36923..c2ac2b3d965a 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala index 99da9bd207ec..bb8e5d78af89 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala index 85bf97543c8e..79e603c6f4f8 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala @@ -1,7 +1,7 @@ /* * Scala classfile decoder (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/ClasspathOps.scala b/src/tastytest/scala/tools/tastytest/ClasspathOps.scala index 70db68865b7e..6a7fbb9dc7d2 100644 --- a/src/tastytest/scala/tools/tastytest/ClasspathOps.scala +++ b/src/tastytest/scala/tools/tastytest/ClasspathOps.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Classpaths.scala b/src/tastytest/scala/tools/tastytest/Classpaths.scala index 112a54ba3bf5..716aa218f163 100644 --- a/src/tastytest/scala/tools/tastytest/Classpaths.scala +++ b/src/tastytest/scala/tools/tastytest/Classpaths.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Diff.scala b/src/tastytest/scala/tools/tastytest/Diff.scala index 2454af964b82..f3240ffa00d0 100644 --- a/src/tastytest/scala/tools/tastytest/Diff.scala +++ b/src/tastytest/scala/tools/tastytest/Diff.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -16,8 +16,18 @@ import scala.jdk.CollectionConverters._ import com.github.difflib.{DiffUtils, UnifiedDiffUtils} object Diff { + def removeTrailing(str: String): String = { + val lastWhitespace = str.reverseIterator.indexWhere(!_.isWhitespace) + if (lastWhitespace == -1) str + else str.dropRight(lastWhitespace) + } + + def splitIntoLines(string: String): Seq[String] = - string.trim.linesIterator.toSeq + string.linesIterator.map(removeTrailing).toSeq + + def splitIntoLines(stream: java.util.stream.Stream[String]): Seq[String] = + stream.map(removeTrailing).iterator().asScala.toSeq def compareContents(output: String, check: String): String = compareContents(splitIntoLines(output), splitIntoLines(check)) diff --git a/src/tastytest/scala/tools/tastytest/Dotc.scala b/src/tastytest/scala/tools/tastytest/Dotc.scala index 3cb28d6202f1..ec460a1215e9 100644 --- a/src/tastytest/scala/tools/tastytest/Dotc.scala +++ b/src/tastytest/scala/tools/tastytest/Dotc.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -81,10 +81,14 @@ object Dotc extends Script.Command { private def makeConsoleReporter(stream: OutputStream)(implicit cl: Dotc.ClassLoader): Try[AnyRef] = Try { val consoleReporterCls = loadClass("dotty.tools.dotc.reporting.ConsoleReporter") - val ctor = consoleReporterCls.getConstructor(classOf[BufferedReader], classOf[PrintWriter]) + val ctor = consoleReporterCls.getConstructor( + /* reader: BufferedReader */classOf[BufferedReader], + /* writer: PrintWriter */classOf[PrintWriter], + /* echoer: PrintWriter */classOf[PrintWriter] // since 3.5.0-RC2 + ) val pwriter = new PrintWriter(stream, true) inClassloader[AnyRef] { - ctor.newInstance(Console.in, pwriter) + ctor.newInstance(/* reader = */Console.in, /* writer = */pwriter, /* echoer= */pwriter) } } diff --git a/src/tastytest/scala/tools/tastytest/DotcDecompiler.scala b/src/tastytest/scala/tools/tastytest/DotcDecompiler.scala index f9d049c61c6e..c74257648e67 100644 --- a/src/tastytest/scala/tools/tastytest/DotcDecompiler.scala +++ b/src/tastytest/scala/tools/tastytest/DotcDecompiler.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Files.scala b/src/tastytest/scala/tools/tastytest/Files.scala index 89c1b7f3e101..c465663fb1a1 100644 --- a/src/tastytest/scala/tools/tastytest/Files.scala +++ b/src/tastytest/scala/tools/tastytest/Files.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -78,14 +78,12 @@ object Files { } def processLines[A](file: String)(op: ju.stream.Stream[String] => A): A = { - var stream: java.util.stream.Stream[String] = null - try { - stream = JFiles.lines(JPaths.get(file)) + val stream: java.util.stream.Stream[String] = JFiles.lines(JPaths.get(file)) + try op(stream) - } - finally if (stream != null) { + finally stream.close() - } + } def use[T](resource: String)(op: jl.Iterable[String] => Try[T]): Try[T] = Try { diff --git a/src/tastytest/scala/tools/tastytest/Javac.scala b/src/tastytest/scala/tools/tastytest/Javac.scala index a9183800be4a..4d0c38884ada 100644 --- a/src/tastytest/scala/tools/tastytest/Javac.scala +++ b/src/tastytest/scala/tools/tastytest/Javac.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/PrintTasty.scala b/src/tastytest/scala/tools/tastytest/PrintTasty.scala index ef276b804cf6..14ad9e8c399c 100644 --- a/src/tastytest/scala/tools/tastytest/PrintTasty.scala +++ b/src/tastytest/scala/tools/tastytest/PrintTasty.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Runner.scala b/src/tastytest/scala/tools/tastytest/Runner.scala index 1727770a241f..be52726a1c2e 100644 --- a/src/tastytest/scala/tools/tastytest/Runner.scala +++ b/src/tastytest/scala/tools/tastytest/Runner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Scalac.scala b/src/tastytest/scala/tools/tastytest/Scalac.scala index 1c8e4db00eb7..a503e7ee3f29 100644 --- a/src/tastytest/scala/tools/tastytest/Scalac.scala +++ b/src/tastytest/scala/tools/tastytest/Scalac.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Scaladoc.scala b/src/tastytest/scala/tools/tastytest/Scaladoc.scala new file mode 100644 index 000000000000..be5a900a98d3 --- /dev/null +++ b/src/tastytest/scala/tools/tastytest/Scaladoc.scala @@ -0,0 +1,76 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.tools.tastytest + +import scala.collection.immutable.ArraySeq +import scala.util.{ Try, Success, chaining }, chaining._ +import scala.tools.nsc.{ reporters}, reporters.{Reporter, ConsoleReporter} +import java.io.OutputStream +import java.io.PrintWriter + +import scala.tools.nsc.{ScalaDoc => RealScaladoc, doc} +import scala.reflect.internal.util.NoPosition + +object Scaladoc extends Script.Command { + + def scaladoc(out: String, additionalSettings: Seq[String], sources: String*): Try[Boolean] = + scaladoc(Console.out, out, additionalSettings, sources:_*) + + def scaladoc(writer: OutputStream, out: String, additionalSettings: Seq[String], sources: String*) = { + + def setup(args: Seq[String]): (Reporter, doc.Settings, RealScaladoc.Command) = { + lazy val (reporter: Reporter, docSettings) = { + val docSettings = new doc.Settings(msg => reporter.error(NoPosition, msg), msg => reporter.echo(msg)) + val pwriter = new PrintWriter(writer, true) + (new ConsoleReporter(docSettings, Console.in, pwriter).tap(_.shortname = true), docSettings) + } + (reporter, docSettings, new RealScaladoc.Command(args.toList, docSettings)) + } + + def compile(args: String*): Try[Boolean] = { + val (reporter, docSettings, command) = setup(args) + Try { + assert(command.files.nonEmpty, "no files to compile") + try { new doc.DocFactory(reporter, docSettings).document(command.files) } + finally reporter.finish() + }.map(_ => !reporter.hasErrors) + } + + if (sources.isEmpty) { + Success(true) + } + else { + val settings = Array( + "-d", out, + "-classpath", out, + "-deprecation", + "-Xfatal-warnings", + "-usejavacp" + ) ++ additionalSettings ++ sources + compile(ArraySeq.unsafeWrapArray(settings):_*) + } + } + + val commandName: String = "scaladoc" + val describe: String = s"$commandName " + + def process(args: String*): Int = { + if (args.length < 2) { + println(red(s"please provide at least 2 arguments in sub-command: $describe")) + return 1 + } + val Seq(out, src, additionalArgs @ _*) = args: @unchecked + val success = scaladoc(out, additionalArgs, src).get + if (success) 0 else 1 + } +} diff --git a/src/tastytest/scala/tools/tastytest/Script.scala b/src/tastytest/scala/tools/tastytest/Script.scala index bd12e7f0fd10..2c65019a6832 100644 --- a/src/tastytest/scala/tools/tastytest/Script.scala +++ b/src/tastytest/scala/tools/tastytest/Script.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/SourceFile.scala b/src/tastytest/scala/tools/tastytest/SourceFile.scala index ff7abeb06a07..f24abc0216ba 100644 --- a/src/tastytest/scala/tools/tastytest/SourceFile.scala +++ b/src/tastytest/scala/tools/tastytest/SourceFile.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/SourceKind.scala b/src/tastytest/scala/tools/tastytest/SourceKind.scala index ecffefbdddb3..4e9454058e2b 100644 --- a/src/tastytest/scala/tools/tastytest/SourceKind.scala +++ b/src/tastytest/scala/tools/tastytest/SourceKind.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/TastyTest.scala b/src/tastytest/scala/tools/tastytest/TastyTest.scala index 32777413ca8f..540d6b8fa915 100644 --- a/src/tastytest/scala/tools/tastytest/TastyTest.scala +++ b/src/tastytest/scala/tools/tastytest/TastyTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -99,7 +99,21 @@ object TastyTest { _ <- scalacPos(out, individualCapable=true, sourceRoot=srcRoot/src/"src-2", additionalSettings, src2:_*) } yield () - /**Simulates a Scala 2 application that depends on a Scala 3 library, and is expected to fail compilation. + + /**Simulates running scaladoc on a Scala 2 library that depends on a Scala 3 library. + * Steps: + * 1) compile all Scala files in `src-3` with scala 3 to `out`, with `out` as the classpath + * 2) compile all Scala files in `src-2` with scaladoc (scala 2) to `out`, with `out` as the classpath + */ + def posDocSuite(src: String, srcRoot: String, pkgName: String, outDir: Option[String], additionalSettings: Seq[String], additionalDottySettings: Seq[String])(implicit cl: Dotc.ClassLoader): Try[Unit] = for { + (src2, src3) <- get2And3Sources(srcRoot/src, src2Filters = Set(Scala), src3Filters = Set(Scala)) + _ = log(s"Sources to compile under test: ${src2.map(cyan).mkString(", ")}") + out <- outDir.fold(tempDir(pkgName))(dir) + _ <- dotcPos(out, sourceRoot=srcRoot/src/"src-3", additionalDottySettings, src3:_*) + _ <- scaladoc(out, sourceRoot=srcRoot/src/"src-2", additionalSettings, src2:_*) + } yield () + + /**Simulates a Scala 2 application that depends on a Scala 3 library, and is expected to fail compilation. * Steps: * 1) compile all Scala files in `src-3` with scala 3 to `out` * 2) attempt to compile all Scala files in `src-2` with scala 2 to `out`, with `out` as the classpath. @@ -225,6 +239,12 @@ object TastyTest { successWhen(res)("scalac failed to compile sources.") } + private def scaladoc(out: String, sourceRoot: String, additionalSettings: Seq[String], sources: String*): Try[Unit] = { + log(s"compiling sources in ${yellow(sourceRoot)} with scalac.") + val res = Scaladoc.scaladoc(out, "-Ytasty-reader" +: additionalSettings, sources:_*) + successWhen(res)("scaladoc failed to compile resources") + } + private def scalacNeg(out: String, additionalSettings: Seq[String], files: String*): Try[Unit] = scalacNeg(out, extraCp = None, additionalSettings, files:_*) @@ -248,6 +268,7 @@ object TastyTest { private def negTestImpl(compile: String => (String, Try[Boolean]))(files: String*): Try[Unit] = { val errors = mutable.ArrayBuffer.empty[String] val unexpectedFail = mutable.ArrayBuffer.empty[String] + val crashes = mutable.ArrayBuffer.empty[String] val failMap: Map[String, (Option[String], Option[String])] = { val (sources, rest) = files.partition(ScalaFail.permits) sources.map({ s => @@ -277,51 +298,61 @@ object TastyTest { } compile(source) } - if (compiled.getOrElse(false)) { - if (failMap.contains(source)) { - errors += source - printerrln(s"ERROR: $source successfully compiled.") - } - } - else { - failMap.get(source) match { - case None => - unexpectedFail += source - System.err.println(output) - printerrln(s"ERROR: $source did not compile when expected to. Perhaps it should match (**/*${ScalaFail.name})") - case Some((Some(checkFile), _)) if Check.permits(checkFile) => - processLines(checkFile) { stream => - val checkLines = stream.iterator().asScala.toSeq - val outputLines = Diff.splitIntoLines(output) - val diff = Diff.compareContents(outputLines, checkLines) - if (diff.nonEmpty) { + compiled match { + case Failure(exception) => + crashes += source + printerrln(s"ERROR: fatal error running compiler for $source: $exception") + case Success(true) => + if (failMap.contains(source)) { + errors += source + printerrln(s"ERROR: $source successfully compiled when expected to fail.") + } + case Success(false) => + failMap.get(source) match { + case None => + unexpectedFail += source + System.err.println(output) + printerrln(s"ERROR: $source did not compile when expected to. Perhaps it should match (**/*${ScalaFail.name})") + case Some((Some(checkFile), _)) if Check.permits(checkFile) => + processLines(checkFile) { stream => + val checkLines = Diff.splitIntoLines(stream) + val outputLines = Diff.splitIntoLines(output) + assert(outputLines.filterNot(_.isEmpty()).nonEmpty, s"outputLines should not be empty: $outputLines") + val diff = Diff.compareContents(outputLines, checkLines) + if (diff.nonEmpty) { + errors += source + printerrln(s"ERROR: $source failed, unexpected output.\n$diff") + } + } + case Some((Some(skipCheckFile), _)) => + printwarnln(s"warning: skipping check on ${skipCheckFile.stripSuffix(SkipCheck.name)}") + case Some((None, _)) => + if (output.nonEmpty) { errors += source - printerrln(s"ERROR: $source failed, unexpected output.\n$diff") + val diff = Diff.compareContents(output, "") + printerrln(s"ERROR: $source failed, no check file found for unexpected output.\n$diff") } - } - case Some((Some(skipCheckFile), _)) => - printwarnln(s"warning: skipping check on ${skipCheckFile.stripSuffix(SkipCheck.name)}") - case Some((None, _)) => - if (output.nonEmpty) { - errors += source - val diff = Diff.compareContents(output, "") - printerrln(s"ERROR: $source failed, no check file found for unexpected output.\n$diff") - } - } + } } } val sources = files.filter(Scala.permits).filterNot(ScalaPre.permits) sources.foreach(negCompile) - successWhen(errors.isEmpty && unexpectedFail.isEmpty) { - if (unexpectedFail.nonEmpty) { + successWhen(errors.isEmpty && unexpectedFail.isEmpty && crashes.isEmpty) { + var msgs = List.empty[String] + if (crashes.nonEmpty) { + val str = if (crashes.size == 1) "file" else "files" + msgs ::= s"${crashes.length} $str fatally crashed the compiler: ${crashes.mkString(", ")}." + } + else if (unexpectedFail.nonEmpty) { val str = if (unexpectedFail.size == 1) "file" else "files" - s"${unexpectedFail.length} $str did not compile when expected to: ${unexpectedFail.mkString(", ")}." + msgs ::= s"${unexpectedFail.length} $str did not compile when expected to: ${unexpectedFail.mkString(", ")}." } - else { + else if (errors.nonEmpty) { val str = if (errors.size == 1) "error" else "errors" - s"${errors.length} $str. These sources either compiled or had an incorrect or missing check file: ${errors.mkString(", ")}." + msgs ::= s"Found ${errors.length} $str. These sources either compiled or had an incorrect or missing check file: ${errors.mkString(", ")}." } + msgs.mkString(System.lineSeparator()) } } @@ -334,7 +365,7 @@ object TastyTest { } private def pipelineDottyOpts(tastyJar: String): Seq[String] = - Seq("-Yjava-tasty", "-Yjava-tasty-output", tastyJar) + Seq("-Xjava-tasty", "-Xearly-tasty-output", tastyJar) private def dotcNeg(out: String, additionalSettings: Seq[String], files: String*)(implicit cl: Dotc.ClassLoader): Try[Unit] = { def compile(source: String, writer: OutputStream) = { diff --git a/src/tastytest/scala/tools/tastytest/TestFailure.scala b/src/tastytest/scala/tools/tastytest/TestFailure.scala index 1e907c15d2c1..1ac1511e26c3 100644 --- a/src/tastytest/scala/tools/tastytest/TestFailure.scala +++ b/src/tastytest/scala/tools/tastytest/TestFailure.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/Tests.scala b/src/tastytest/scala/tools/tastytest/Tests.scala index 385022b49ef2..aaa060890e8f 100644 --- a/src/tastytest/scala/tools/tastytest/Tests.scala +++ b/src/tastytest/scala/tools/tastytest/Tests.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/internal/Runner.scala b/src/tastytest/scala/tools/tastytest/internal/Runner.scala index 72d9a290b56c..aa4db6db914c 100644 --- a/src/tastytest/scala/tools/tastytest/internal/Runner.scala +++ b/src/tastytest/scala/tools/tastytest/internal/Runner.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/tastytest/scala/tools/tastytest/package.scala b/src/tastytest/scala/tools/tastytest/package.scala index 690c4ac2abe5..b9c99cc6e640 100644 --- a/src/tastytest/scala/tools/tastytest/package.scala +++ b/src/tastytest/scala/tools/tastytest/package.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/ASMConverters.scala b/src/testkit/scala/tools/testkit/ASMConverters.scala index da627c448b5b..73fdcb605c92 100644 --- a/src/testkit/scala/tools/testkit/ASMConverters.scala +++ b/src/testkit/scala/tools/testkit/ASMConverters.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/AllocationTest.scala b/src/testkit/scala/tools/testkit/AllocationTest.scala index 6cbb7fe899bf..2071b4610fea 100644 --- a/src/testkit/scala/tools/testkit/AllocationTest.scala +++ b/src/testkit/scala/tools/testkit/AllocationTest.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -57,7 +57,7 @@ object AllocationTest { } private def costOf[T](fn: => T, tpe: String): Long = { - val cost = coster.calcAllocationInfo(fn, 0, "", false).min + val cost = coster.calcAllocationInfo(fn, 0, "", ignoreEqualCheck = false).min println(s"cost of tracking allocations - cost of $tpe = $cost") cost } diff --git a/src/testkit/scala/tools/testkit/AssertUtil.scala b/src/testkit/scala/tools/testkit/AssertUtil.scala index ffdd141c7c5b..97e24211474c 100644 --- a/src/testkit/scala/tools/testkit/AssertUtil.scala +++ b/src/testkit/scala/tools/testkit/AssertUtil.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -14,6 +14,7 @@ package scala.tools.testkit import org.junit.Assert.{assertEquals, assertNotEquals} import org.junit.Assert.{assertFalse, assertTrue} +import org.junit.Assume.{assumeFalse, assumeTrue} import scala.annotation.nowarn import scala.collection.mutable @@ -22,6 +23,7 @@ import scala.reflect.ClassTag import scala.runtime.BoxesRunTime import scala.runtime.ScalaRunTime.stringOf import scala.util.{Failure, Success, Try} +import scala.util.Properties.isWin import scala.util.chaining._ import scala.util.control.{ControlThrowable, NonFatal} import java.lang.ref.{Reference, ReferenceQueue, SoftReference} @@ -45,14 +47,19 @@ object AssertUtil { // junit fail is Unit def fail(message: String): Nothing = throw new AssertionError(message) + def noWin(message: String = "skipping test on Windows")(body: => Unit) = { + assumeFalse(message, isWin) + body + } + private val Bail = new ControlThrowable {} def bail(): Nothing = throw Bail - // maybe there is a way to communicate that the test was skipped + // if the test bails out, communicate a violated assumption def bailable(name: String)(test: => Unit): Unit = try test - catch { case _: Bail.type => println(s"$name skipped bail!") } + catch { case _: Bail.type => assumeTrue(s"$name skipped bail!", false) } private val printable = raw"\p{Print}".r @@ -85,8 +92,6 @@ object AssertUtil { def assertNotEqualsAny(message: => String, expected: Any, actual: Any): Unit = if (BoxesRunTime.equals(expected, actual)) assertNotEquals(message, expected, actual) - private final val timeout = 60 * 1000L // wait a minute - private implicit class `ref helper`[A <: AnyRef](val r: Reference[A]) extends AnyVal { def isEmpty: Boolean = r.get == null // r.refersTo(null) to avoid influencing collection def nonEmpty: Boolean = !isEmpty diff --git a/src/testkit/scala/tools/testkit/BytecodeTesting.scala b/src/testkit/scala/tools/testkit/BytecodeTesting.scala index ca851b283af6..b5ee4fc57e6b 100644 --- a/src/testkit/scala/tools/testkit/BytecodeTesting.scala +++ b/src/testkit/scala/tools/testkit/BytecodeTesting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). @@ -181,6 +181,9 @@ object BytecodeTesting { } def makeSourceFile(code: String, filename: String): BatchSourceFile = new BatchSourceFile(filename, code) + private var fileCount = 0 + private def fileN = { val n = fileCount; fileCount += 1; if (n == 0) "" else n.toString } + def SourceFile(code: String*): List[BatchSourceFile] = code.map(makeSourceFile(_, s"UnitTestSource$fileN")).toList def getGeneratedClassfiles(outDir: AbstractFile): List[(String, Array[Byte])] = { def files(dir: AbstractFile): List[(String, Array[Byte])] = { diff --git a/src/testkit/scala/tools/testkit/ClearAfterClass.java b/src/testkit/scala/tools/testkit/ClearAfterClass.java index b754d9e0b5e1..96574cfcdc99 100644 --- a/src/testkit/scala/tools/testkit/ClearAfterClass.java +++ b/src/testkit/scala/tools/testkit/ClearAfterClass.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/CompileTime.scala b/src/testkit/scala/tools/testkit/CompileTime.scala index 07ce45c2f1ea..3669312fa79f 100644 --- a/src/testkit/scala/tools/testkit/CompileTime.scala +++ b/src/testkit/scala/tools/testkit/CompileTime.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/ReflectUtil.scala b/src/testkit/scala/tools/testkit/ReflectUtil.scala index 6a4f10c0cbe3..e85b7fe1d204 100644 --- a/src/testkit/scala/tools/testkit/ReflectUtil.scala +++ b/src/testkit/scala/tools/testkit/ReflectUtil.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/Resource.java b/src/testkit/scala/tools/testkit/Resource.java index f6ed5d37fb12..ee9f443356e2 100644 --- a/src/testkit/scala/tools/testkit/Resource.java +++ b/src/testkit/scala/tools/testkit/Resource.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/RunTesting.scala b/src/testkit/scala/tools/testkit/RunTesting.scala index 9581693e8e25..5d81962b993c 100644 --- a/src/testkit/scala/tools/testkit/RunTesting.scala +++ b/src/testkit/scala/tools/testkit/RunTesting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/TempDir.scala b/src/testkit/scala/tools/testkit/TempDir.scala index 183f84769578..61242e6a7856 100644 --- a/src/testkit/scala/tools/testkit/TempDir.scala +++ b/src/testkit/scala/tools/testkit/TempDir.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/VirtualCompilerTesting.scala b/src/testkit/scala/tools/testkit/VirtualCompilerTesting.scala index d2c6e836f152..116fefc08d6b 100644 --- a/src/testkit/scala/tools/testkit/VirtualCompilerTesting.scala +++ b/src/testkit/scala/tools/testkit/VirtualCompilerTesting.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/XMLTesting.scala b/src/testkit/scala/tools/testkit/XMLTesting.scala new file mode 100644 index 000000000000..cddbcf6e4dbb --- /dev/null +++ b/src/testkit/scala/tools/testkit/XMLTesting.scala @@ -0,0 +1,66 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. dba Akka + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.tools.testkit + +object XMLTesting { + object xml { + val code = """ +import collection.{immutable, mutable}, mutable.ArrayBuffer + +package scala.xml { + trait MetaData + //def key: String + //def value: Seq[Node] + //def next: MetaData + trait NamespaceBinding + object TopScope extends NamespaceBinding + object Null extends MetaData + abstract class Node extends immutable.Seq[Node] { + def label: String + def child: Seq[Node] = Nil + override def toString = label + child.mkString + + def iterator: Iterator[Node] = ??? // implements `def iterator: Iterator[A]` + // Members declared in scala.collection.SeqOps + def apply(i: Int): Node = ??? // implements `def apply(i: Int): A` + def length: Int = ??? + } + class Elem(prefix: String, val label: String, attributes1: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, override val child: Node*) extends Node + class NodeBuffer extends Seq[Node] { + val nodes = ArrayBuffer.empty[Node] + def &+(o: Any): this.type = + o match { + case n: Node => nodes.addOne(n); this + case _ => throw new MatchError(o) + } + // Members declared in scala.collection.IterableOnce + def iterator: Iterator[scala.xml.Node] = nodes.iterator + // Members declared in scala.collection.SeqOps + def apply(i: Int): scala.xml.Node = nodes(i) + def length: Int = nodes.length + } + case class Text(text: String) extends Node { + def label = text + } + case class Atom(t: Text) extends Node { + def label = t.text + } + trait Attribute extends MetaData + class PrefixedAttribute(pre: String, key: String, value: Seq[Node], next1: MetaData) extends Attribute + class UnprefixedAttribute(key: String, value: Seq[Node], next1: MetaData) extends Attribute { + def this(key: String, value: String, next1: MetaData) = this(key, Text(value), next1) + } +} +""" + } +} diff --git a/src/testkit/scala/tools/testkit/async/Async.scala b/src/testkit/scala/tools/testkit/async/Async.scala index 27b508f2ef9c..9d618e072626 100644 --- a/src/testkit/scala/tools/testkit/async/Async.scala +++ b/src/testkit/scala/tools/testkit/async/Async.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/src/testkit/scala/tools/testkit/async/AsyncStateMachine.scala b/src/testkit/scala/tools/testkit/async/AsyncStateMachine.scala index be38a9612997..8a0796f4e743 100644 --- a/src/testkit/scala/tools/testkit/async/AsyncStateMachine.scala +++ b/src/testkit/scala/tools/testkit/async/AsyncStateMachine.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/test/async/jvm/anf.scala b/test/async/jvm/anf.scala index 63e6aa8053ca..357651fc70f6 100644 --- a/test/async/jvm/anf.scala +++ b/test/async/jvm/anf.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.anf.AnfTransformSpec]) diff --git a/test/async/jvm/await0.scala b/test/async/jvm/await0.scala index 896b9aaf04e1..fb412b73fc68 100644 --- a/test/async/jvm/await0.scala +++ b/test/async/jvm/await0.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.await0.Await0Spec]) diff --git a/test/async/jvm/block0.scala b/test/async/jvm/block0.scala index b5192a684bb8..f485ea05fdc6 100644 --- a/test/async/jvm/block0.scala +++ b/test/async/jvm/block0.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.block0.AsyncSpec]) diff --git a/test/async/jvm/block1.scala b/test/async/jvm/block1.scala index 5a4cd0e14c26..0fd42105656e 100644 --- a/test/async/jvm/block1.scala +++ b/test/async/jvm/block1.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.block1.Block1Spec]) diff --git a/test/async/jvm/completable-future.scala b/test/async/jvm/completable-future.scala index dd2b5538b31b..6d702d508e2e 100644 --- a/test/async/jvm/completable-future.scala +++ b/test/async/jvm/completable-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import java.util.concurrent._ import scala.tools.partest.async.CompletableFutureAwait._ diff --git a/test/async/jvm/concurrent_AfterRefchecksIssue.scala b/test/async/jvm/concurrent_AfterRefchecksIssue.scala index e91af0b7924e..1113bbbd29fe 100644 --- a/test/async/jvm/concurrent_AfterRefchecksIssue.scala +++ b/test/async/jvm/concurrent_AfterRefchecksIssue.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._, ExecutionContext.Implicits.global, scala.tools.testkit.async.Async._ diff --git a/test/async/jvm/concurrent_ArrayIndexOutOfBoundIssue.scala b/test/async/jvm/concurrent_ArrayIndexOutOfBoundIssue.scala index c760607568dd..b1017e8f94eb 100644 --- a/test/async/jvm/concurrent_ArrayIndexOutOfBoundIssue.scala +++ b/test/async/jvm/concurrent_ArrayIndexOutOfBoundIssue.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_GenericTypeBoundaryIssue.scala b/test/async/jvm/concurrent_GenericTypeBoundaryIssue.scala index 83cc4a3d2e29..a63fe07cfddc 100644 --- a/test/async/jvm/concurrent_GenericTypeBoundaryIssue.scala +++ b/test/async/jvm/concurrent_GenericTypeBoundaryIssue.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import Test.test diff --git a/test/async/jvm/concurrent_MatchEndIssue.scala b/test/async/jvm/concurrent_MatchEndIssue.scala index bd37b24f3612..055fd125ead2 100644 --- a/test/async/jvm/concurrent_MatchEndIssue.scala +++ b/test/async/jvm/concurrent_MatchEndIssue.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_NegativeArraySizeException.scala b/test/async/jvm/concurrent_NegativeArraySizeException.scala index 9cda7fa26d8e..58960561fb2b 100644 --- a/test/async/jvm/concurrent_NegativeArraySizeException.scala +++ b/test/async/jvm/concurrent_NegativeArraySizeException.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_NegativeArraySizeExceptionFine1.scala b/test/async/jvm/concurrent_NegativeArraySizeExceptionFine1.scala index 20a7325838e2..1c3ddc9f4a33 100644 --- a/test/async/jvm/concurrent_NegativeArraySizeExceptionFine1.scala +++ b/test/async/jvm/concurrent_NegativeArraySizeExceptionFine1.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_ReturnTupleIssue.scala b/test/async/jvm/concurrent_ReturnTupleIssue.scala index 9f8d52949d6d..61c3495a7bfe 100644 --- a/test/async/jvm/concurrent_ReturnTupleIssue.scala +++ b/test/async/jvm/concurrent_ReturnTupleIssue.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_fetch.scala b/test/async/jvm/concurrent_fetch.scala index 126dd9204438..c25214709ecb 100644 --- a/test/async/jvm/concurrent_fetch.scala +++ b/test/async/jvm/concurrent_fetch.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent.{Await, Future, duration} import scala.concurrent.ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_patternAlternative.scala b/test/async/jvm/concurrent_patternAlternative.scala index f85aef1e9ef0..8ccfd05f005a 100644 --- a/test/async/jvm/concurrent_patternAlternative.scala +++ b/test/async/jvm/concurrent_patternAlternative.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_patternAlternativeBothAnnotations.scala b/test/async/jvm/concurrent_patternAlternativeBothAnnotations.scala index b94a8bad4323..61e8bfb9a934 100644 --- a/test/async/jvm/concurrent_patternAlternativeBothAnnotations.scala +++ b/test/async/jvm/concurrent_patternAlternativeBothAnnotations.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_polymorphicMethod.scala b/test/async/jvm/concurrent_polymorphicMethod.scala index 13543621dae0..c74160a8c05c 100644 --- a/test/async/jvm/concurrent_polymorphicMethod.scala +++ b/test/async/jvm/concurrent_polymorphicMethod.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_shadowing.scala b/test/async/jvm/concurrent_shadowing.scala index 8918096d4da0..9e959911fe4c 100644 --- a/test/async/jvm/concurrent_shadowing.scala +++ b/test/async/jvm/concurrent_shadowing.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_shadowing0.scala b/test/async/jvm/concurrent_shadowing0.scala index f1593831be93..e708eb44d169 100644 --- a/test/async/jvm/concurrent_shadowing0.scala +++ b/test/async/jvm/concurrent_shadowing0.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_shadowing2.scala b/test/async/jvm/concurrent_shadowing2.scala index 65fa05e086ab..3a02f0b2db9d 100644 --- a/test/async/jvm/concurrent_shadowing2.scala +++ b/test/async/jvm/concurrent_shadowing2.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_shadowingRefinedTypes.scala b/test/async/jvm/concurrent_shadowingRefinedTypes.scala index 79c96e09e76a..5264923c9fbd 100644 --- a/test/async/jvm/concurrent_shadowingRefinedTypes.scala +++ b/test/async/jvm/concurrent_shadowingRefinedTypes.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/jvm/concurrent_test0.scala b/test/async/jvm/concurrent_test0.scala index 772c25826b27..24dd770474d6 100644 --- a/test/async/jvm/concurrent_test0.scala +++ b/test/async/jvm/concurrent_test0.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync /* * Scala (https://www.scala-lang.org) diff --git a/test/async/jvm/exceptions.scala b/test/async/jvm/exceptions.scala index 59ae91f28a66..22908defa1a5 100644 --- a/test/async/jvm/exceptions.scala +++ b/test/async/jvm/exceptions.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.exceptions.ExceptionsSpec]) diff --git a/test/async/jvm/futures.scala b/test/async/jvm/futures.scala index 55ebd4c8a6bb..cc871fb056a4 100644 --- a/test/async/jvm/futures.scala +++ b/test/async/jvm/futures.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync -deprecation +//> using options -Xasync -deprecation object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.futures.FutureSpec]) diff --git a/test/async/jvm/hygiene.scala b/test/async/jvm/hygiene.scala index debee49bffc5..39cb86c11767 100644 --- a/test/async/jvm/hygiene.scala +++ b/test/async/jvm/hygiene.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.hygiene.HygieneSpec]) diff --git a/test/async/jvm/ifelse0.scala b/test/async/jvm/ifelse0.scala index 138ee0a57e68..e81a026e53b3 100644 --- a/test/async/jvm/ifelse0.scala +++ b/test/async/jvm/ifelse0.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.ifelse0.IfElseSpec]) diff --git a/test/async/jvm/ifelse0_while.scala b/test/async/jvm/ifelse0_while.scala index 64d07fde62d6..a5cce1445e31 100644 --- a/test/async/jvm/ifelse0_while.scala +++ b/test/async/jvm/ifelse0_while.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.ifelse0.WhileSpec]) diff --git a/test/async/jvm/ifelse1.scala b/test/async/jvm/ifelse1.scala index 86e6cc57ef93..104cf20ce323 100644 --- a/test/async/jvm/ifelse1.scala +++ b/test/async/jvm/ifelse1.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.ifelse1.IfElse1Spec]) diff --git a/test/async/jvm/ifelse2.scala b/test/async/jvm/ifelse2.scala index 12e8bd5a7b88..a65ed71ad45e 100644 --- a/test/async/jvm/ifelse2.scala +++ b/test/async/jvm/ifelse2.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.ifelse2.IfElse2Spec]) diff --git a/test/async/jvm/ifelse3.scala b/test/async/jvm/ifelse3.scala index 0eaeb8f5ea0d..5f455d7bbfee 100644 --- a/test/async/jvm/ifelse3.scala +++ b/test/async/jvm/ifelse3.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.ifelse3.IfElse3Spec]) diff --git a/test/async/jvm/ifelse4.scala b/test/async/jvm/ifelse4.scala index b32a5de26bac..4fd1ff982921 100644 --- a/test/async/jvm/ifelse4.scala +++ b/test/async/jvm/ifelse4.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.ifelse4.IfElse4Spec]) diff --git a/test/async/jvm/lazyval.scala b/test/async/jvm/lazyval.scala index d52f7e275821..414edd6c5310 100644 --- a/test/async/jvm/lazyval.scala +++ b/test/async/jvm/lazyval.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.lazyval.LazyValSpec]) diff --git a/test/async/jvm/live.scala b/test/async/jvm/live.scala index 18fb9245bc15..7ef1e9bd0a0f 100644 --- a/test/async/jvm/live.scala +++ b/test/async/jvm/live.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.live.LiveVariablesSpec]) diff --git a/test/async/jvm/localclasses.scala b/test/async/jvm/localclasses.scala index 9bafc634d079..c0fb5d251051 100644 --- a/test/async/jvm/localclasses.scala +++ b/test/async/jvm/localclasses.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.neg.LocalClasses0Spec]) diff --git a/test/async/jvm/match0.scala b/test/async/jvm/match0.scala index 9916df5edda9..566227e38d18 100644 --- a/test/async/jvm/match0.scala +++ b/test/async/jvm/match0.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.match0.MatchSpec]) diff --git a/test/async/jvm/nesteddef.scala b/test/async/jvm/nesteddef.scala index 42e1763bdfc3..656797e991c9 100644 --- a/test/async/jvm/nesteddef.scala +++ b/test/async/jvm/nesteddef.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.nesteddef.NestedDef]) diff --git a/test/async/jvm/noawait.scala b/test/async/jvm/noawait.scala index dbcc03ac3662..788984fd8d5a 100644 --- a/test/async/jvm/noawait.scala +++ b/test/async/jvm/noawait.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.noawait.NoAwaitSpec]) diff --git a/test/async/jvm/stackoverflow.scala b/test/async/jvm/stackoverflow.scala index f1395194a9f7..6708575d3120 100644 --- a/test/async/jvm/stackoverflow.scala +++ b/test/async/jvm/stackoverflow.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import scala.concurrent.duration._ diff --git a/test/async/jvm/syncOptimization.scala b/test/async/jvm/syncOptimization.scala index a6fc3392c4dc..4d23ea348231 100644 --- a/test/async/jvm/syncOptimization.scala +++ b/test/async/jvm/syncOptimization.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.testkit.async.Async._ import scala.concurrent._ diff --git a/test/async/jvm/toughtype.check b/test/async/jvm/toughtype.check index 1de9501259aa..8dcb3441e8d4 100644 --- a/test/async/jvm/toughtype.check +++ b/test/async/jvm/toughtype.check @@ -1,6 +1,3 @@ -toughtype.scala:175: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - identity[A] _ - ^ -toughtype.scala:175: warning: a pure expression does nothing in statement position +toughtype.scala:175: warning: discarded pure expression does nothing identity[A] _ ^ diff --git a/test/async/jvm/toughtype.scala b/test/async/jvm/toughtype.scala index 9587afa35f19..d8a9643e0efb 100644 --- a/test/async/jvm/toughtype.scala +++ b/test/async/jvm/toughtype.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync object Test extends scala.tools.partest.JUnitTest(classOf[scala.async.run.toughtype.ToughTypeSpec]) @@ -34,7 +34,7 @@ package scala.async.run.toughtype { class ToughTypeSpec { - @Test def `propogates tough types`(): Unit = { + @Test def `propagates tough types`(): Unit = { val fut = ToughTypeObject.m2 val res: (List[_], scala.async.run.toughtype.ToughTypeObject.Inner) = Await.result(fut, 2 seconds) assertEquals(Nil, res._1) diff --git a/test/async/neg/ill-nested-await.scala b/test/async/neg/ill-nested-await.scala index dc2a0f93a4f8..aacee1e7ac9d 100644 --- a/test/async/neg/ill-nested-await.scala +++ b/test/async/neg/ill-nested-await.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.concurrent._ import ExecutionContext.Implicits.global diff --git a/test/async/neg/naked_await.scala b/test/async/neg/naked_await.scala index 31833df14c99..13333d11615f 100644 --- a/test/async/neg/naked_await.scala +++ b/test/async/neg/naked_await.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.testkit.async.Async._ import scala.concurrent.{ExecutionContext, Future} diff --git a/test/async/neg/stark_naked_await.scala b/test/async/neg/stark_naked_await.scala index 7025061eafcd..11970557b7c2 100644 --- a/test/async/neg/stark_naked_await.scala +++ b/test/async/neg/stark_naked_await.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.testkit.async.Async._ import scala.concurrent.{ExecutionContext, Future} diff --git a/test/async/run/booleans.scala b/test/async/run/booleans.scala index fe9df0b8ca87..f5c74607f59b 100644 --- a/test/async/run/booleans.scala +++ b/test/async/run/booleans.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/async/run/edge-cases.scala b/test/async/run/edge-cases.scala index 4306570dc608..ab244c239a62 100644 --- a/test/async/run/edge-cases.scala +++ b/test/async/run/edge-cases.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/async/run/lambda.scala b/test/async/run/lambda.scala index 2f23500d581c..455efc8af908 100644 --- a/test/async/run/lambda.scala +++ b/test/async/run/lambda.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ //import org.junit.Assert._ diff --git a/test/async/run/output.scala b/test/async/run/output.scala index 4324eae15b95..a61332f768eb 100644 --- a/test/async/run/output.scala +++ b/test/async/run/output.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.{OutputAwait, Output} import scala.collection.immutable diff --git a/test/async/run/smoketest.scala b/test/async/run/smoketest.scala index 1a1858988c81..f31c46445603 100644 --- a/test/async/run/smoketest.scala +++ b/test/async/run/smoketest.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/async/run/string-switch-async.scala b/test/async/run/string-switch-async.scala index 466f7e3abac4..f907e0b5a34f 100644 --- a/test/async/run/string-switch-async.scala +++ b/test/async/run/string-switch-async.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/async/run/string-switch-bug.scala b/test/async/run/string-switch-bug.scala index daa0020925dc..28fb8889c504 100644 --- a/test/async/run/string-switch-bug.scala +++ b/test/async/run/string-switch-bug.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/async/run/switch-await-in-guard.scala b/test/async/run/switch-await-in-guard.scala new file mode 100644 index 000000000000..28678792054f --- /dev/null +++ b/test/async/run/switch-await-in-guard.scala @@ -0,0 +1,50 @@ +//> using options -Xasync + +import scala.tools.partest.async.OptionAwait._ +import org.junit.Assert._ + +object Test { + def main(args: Array[String]): Unit = { + assertEquals(Some(22), sw1(11)) + assertEquals(Some(3), sw1(3)) + + assertEquals(Some(22), sw2(11)) + assertEquals(Some(3), sw2(3)) + + assertEquals(Some(22), sw3(11)) + assertEquals(Some(44), sw3(22)) + assertEquals(Some(3), sw3(3)) + + assertEquals(Some("22"), swS("11")) + assertEquals(Some("3"), swS("3")) + } + + private def sw1(i: Int) = optionally { + i match { + case 11 if value(Some(430)) > 42 => 22 + case p => p + } + } + + private def sw2(i: Int) = optionally { + i match { + case 11 => if (value(Some(430)) > 42) 22 else i + case p => p + } + } + + private def sw3(i: Int) = optionally { + i match { + case 11 => if (value(Some(430)) > 42) 22 else i + case 22 | 33 => 44 + case p => p + } + } + + private def swS(s: String) = optionally { + s match { + case "11" if value(Some(430)) > 42 => "22" + case p => p + } + } +} diff --git a/test/async/run/t12723.scala b/test/async/run/t12723.scala index 473e89a63fa5..0c8e0796999d 100644 --- a/test/async/run/t12723.scala +++ b/test/async/run/t12723.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync -Werror -Wnonunit-statement +//> using options -Xasync -Werror -Wnonunit-statement import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/async/run/value-class.scala b/test/async/run/value-class.scala index d50bd24422b2..0fd3d81f8b5a 100644 --- a/test/async/run/value-class.scala +++ b/test/async/run/value-class.scala @@ -1,4 +1,4 @@ -// scalac: -Xasync +//> using options -Xasync import scala.tools.partest.async.OptionAwait._ import org.junit.Assert._ diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/ArraySeqBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/ArraySeqBenchmark.scala index 58338584e85f..62755b48439d 100644 --- a/test/benchmarks/src/main/scala/scala/collection/immutable/ArraySeqBenchmark.scala +++ b/test/benchmarks/src/main/scala/scala/collection/immutable/ArraySeqBenchmark.scala @@ -15,7 +15,7 @@ import scala.reflect.ClassTag @State(Scope.Benchmark) class ArraySeqBenchmark { - @Param(Array("0", "1", "10", "1000", "10000")) + @Param(Array("0", "1", "10", "100", "1000", "10000")) var size: Int = _ var integersS: ArraySeq[Int] = _ var stringsS: ArraySeq[String] = _ @@ -93,4 +93,8 @@ class ArraySeqBenchmark { integersS.max } + @Benchmark def sliding(bh: Blackhole): Any = { + var coll = stringsS + coll.sliding(2).foreach(bh.consume) + } } diff --git a/test/benchmarks/src/main/scala/scala/collection/immutable/VectorBenchmark2.scala b/test/benchmarks/src/main/scala/scala/collection/immutable/VectorBenchmark2.scala index 948ed28119c7..d59862cca487 100644 --- a/test/benchmarks/src/main/scala/scala/collection/immutable/VectorBenchmark2.scala +++ b/test/benchmarks/src/main/scala/scala/collection/immutable/VectorBenchmark2.scala @@ -587,4 +587,9 @@ class VectorBenchmark2 { var coll = nv bh.consume(coll.filter(x => false)) } + + @Benchmark def nvSliding(bh: Blackhole): Any = { + var coll = nv + coll.sliding(2).foreach(bh.consume) + } } diff --git a/test/benchmarks/src/main/scala/scala/collection/mutable/ArrayBufferBenchmark.scala b/test/benchmarks/src/main/scala/scala/collection/mutable/ArrayBufferBenchmark.scala index f1d231adcec6..d988031a5c9b 100644 --- a/test/benchmarks/src/main/scala/scala/collection/mutable/ArrayBufferBenchmark.scala +++ b/test/benchmarks/src/main/scala/scala/collection/mutable/ArrayBufferBenchmark.scala @@ -45,6 +45,17 @@ class ArrayBufferBenchmark { bh.consume(b) } + @Benchmark def toObjArrayTagged(bh:Blackhole):Unit = { + val res = ref.asInstanceOf[ArrayBuffer[Integer]].toArray + bh.consume(res) + } + + @Benchmark def toObjArrayUntagged(bh:Blackhole):Unit = { + val res = ref.asInstanceOf[ArrayBuffer[AnyRef]].toArray + bh.consume(res) + } + + @Benchmark def update(bh: Blackhole): Unit = { val b = ref.clone() var i = 0 @@ -63,6 +74,20 @@ class ArrayBufferBenchmark { bh.consume(b1) } + //addOne + @Benchmark def addOneArrayBuffer(bh:Blackhole):Unit = { + val res = ArrayBuffer[Object]() + ref.asInstanceOf[ArrayBuffer[Object]].foreach(res.addOne) + bh.consume(res) + } + + //addOne comparison + @Benchmark def addOneArrayList(bh:Blackhole):Unit = { + val res = new java.util.ArrayList[Object]() + ref.asInstanceOf[ArrayBuffer[Object]].foreach(res.add) + bh.consume(res) + } + // append `Iterable` with known size @Benchmark def addAll2(bh: Blackhole): Unit = { val b = ref.clone() diff --git a/test/benchmarks/src/main/scala/scala/tools/nsc/PhaseAssemblyBenchmark.scala b/test/benchmarks/src/main/scala/scala/tools/nsc/PhaseAssemblyBenchmark.scala index 6ba78f52276e..ff77e6bf392d 100644 --- a/test/benchmarks/src/main/scala/scala/tools/nsc/PhaseAssemblyBenchmark.scala +++ b/test/benchmarks/src/main/scala/scala/tools/nsc/PhaseAssemblyBenchmark.scala @@ -18,26 +18,28 @@ class PhaseAssemblyBenchmark { class Data[G <: Global with Singleton](val global: G, val components: List[SubComponent { val global: G}]) var data: Data[_] = _ - @Param(Array("1", "4", "8", "16")) - var size: Int = 16 + case class component[G <: Global with Singleton]( + global: G, + phaseName: String, + override val runsRightAfter: Option[String], + override val runsAfter: List[String], + override val runsBefore: List[String], + ) extends SubComponent { + override val initial: Boolean = phaseName == "parser" + override val terminal: Boolean = phaseName == "terminal" + override def newPhase(prev: Phase): Phase = ??? + } + + @Param(Array("1", "4", "8", "16", "64")) + var size: Int = 64 @Setup def setup(): Unit = { val global = new Global(new Settings) - case class component[G <: Global with Singleton](val global: G, val phaseName: String, override val runsRightAfter: Option[String], override val runsAfter: List[String], override val runsBefore: List[String]) extends SubComponent { - override def newPhase(prev: Phase): Phase = ??? - - } - object component { - def apply(phaseName: String, runsRightAfter: Option[String], runsAfter: List[String], runsBefore: List[String]): component[global.type] = { - new component[global.type](global, phaseName, runsRightAfter, runsAfter, runsBefore) - } - } val N = size val components = List.tabulate(N){ i => - component(i.toString, None, if (i == 0) List("parser") else List.tabulate(2)(j => i - j - 1).filter(_ >= 0).map(_.toString), List("terminal")) - } ::: List(component("parser", None, Nil, Nil), component("terminal", None, Nil, List(N.toString))) - + component(global, i.toString, None, if (i == 0) List("parser") else List.tabulate(2)(j => i - j - 1).filter(_ >= 0).map(_.toString), List("terminal")) + } ::: List(component(global, "parser", None, Nil, Nil), component(global, "terminal", None, Nil, Nil)) data = new Data[global.type](global, components ) } @@ -45,11 +47,8 @@ class PhaseAssemblyBenchmark { @Benchmark def assemble(): Object = { val s = data.asInstanceOf[Data[Global with Singleton]] val g = s.global - val graph = g.phasesSetToDepGraph(s.components.reverse) - graph.removeDanglingNodes() - graph.validateAndEnforceHardlinks() - graph.collapseHardLinksAndLevels(graph.getNodeByPhase("parser"), 1) - graph + val graph = DependencyGraph(s.components.reverse) + graph.compilerPhaseList() } } @@ -59,4 +58,4 @@ object PhaseAssemblyBenchmark { bench.setup() bench.assemble() } -} \ No newline at end of file +} diff --git a/test/files/bench/equality/eqeq.eqlog b/test/files/bench/equality/eqeq.eqlog index 55a5eb430a96..0a126941c5b8 100644 --- a/test/files/bench/equality/eqeq.eqlog +++ b/test/files/bench/equality/eqeq.eqlog @@ -1,4 +1,4 @@ -Banchmark results for testing equality operations: +Benchmark results for testing equality operations: eq.scala: Base case, use eq equality only eqeq.scala: Test case, use == instead of eq. All tests run on Thinkpad T400, 1.6.0_12 client VM. diff --git a/test/files/instrumented/inline-in-constructors/assert_1.scala b/test/files/instrumented/inline-in-constructors/assert_1.scala index 9c055a49475e..0ab3c4047773 100644 --- a/test/files/instrumented/inline-in-constructors/assert_1.scala +++ b/test/files/instrumented/inline-in-constructors/assert_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt package instrumented object MyPredef { diff --git a/test/files/instrumented/inline-in-constructors/bar_2.scala b/test/files/instrumented/inline-in-constructors/bar_2.scala index 7a4c4504b898..b67ea9f2f90a 100644 --- a/test/files/instrumented/inline-in-constructors/bar_2.scala +++ b/test/files/instrumented/inline-in-constructors/bar_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** package instrumented /** Class that uses assert compiled in previous compiler run so we check if diff --git a/test/files/instrumented/inline-in-constructors/test_3.scala b/test/files/instrumented/inline-in-constructors/test_3.scala index 00fbf8bd5d44..d4e6cd6fe716 100644 --- a/test/files/instrumented/inline-in-constructors/test_3.scala +++ b/test/files/instrumented/inline-in-constructors/test_3.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt import scala.tools.partest.instrumented.Instrumentation._ import instrumented._ diff --git a/test/files/jvm/annotations/Test_2.scala b/test/files/jvm/annotations/Test_2.scala index 83fdeb3f808a..d098f4084ea3 100644 --- a/test/files/jvm/annotations/Test_2.scala +++ b/test/files/jvm/annotations/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // import scala.tools.partest.Util.ArrayDeep import scala.language.reflectiveCalls diff --git a/test/files/jvm/deprecation/Test_1.scala b/test/files/jvm/deprecation/Test_1.scala index 04c9b22365be..3288e20a4a5b 100644 --- a/test/files/jvm/deprecation/Test_1.scala +++ b/test/files/jvm/deprecation/Test_1.scala @@ -1,5 +1,5 @@ -// scalac: -Xlint:deprecation +//> using options -Xlint:deprecation class Test { def test: Unit = { diff --git a/test/files/jvm/deprecation/Use_2.java b/test/files/jvm/deprecation/Use_2.java index 36d5b4ffed9a..c821f028d4c1 100644 --- a/test/files/jvm/deprecation/Use_2.java +++ b/test/files/jvm/deprecation/Use_2.java @@ -1,5 +1,5 @@ -// javac: -Xlint:deprecation +//> using javacOpt -Xlint:deprecation class Use_2 { public int test() { diff --git a/test/files/jvm/innerClassAttribute.check b/test/files/jvm/innerClassAttribute.check index bb293a93ada1..d43971dce825 100644 --- a/test/files/jvm/innerClassAttribute.check +++ b/test/files/jvm/innerClassAttribute.check @@ -4,7 +4,7 @@ Classes_1.scala:117: warning: a pure expression does nothing in statement positi Classes_1.scala:124: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses ((x: String) => x + "2") ^ -Classes_1.scala:129: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +Classes_1.scala:129: warning: a pure expression does nothing in statement position (s: String) => { ^ Classes_1.scala:130: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses diff --git a/test/files/jvm/methvsfield/Test_2.scala b/test/files/jvm/methvsfield/Test_2.scala index b9ad46ac7426..da26ebd31e84 100644 --- a/test/files/jvm/methvsfield/Test_2.scala +++ b/test/files/jvm/methvsfield/Test_2.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.forked.jvm +//> using javaOpt -Dneeds.forked.jvm // bug #1062 object Test extends App { println((new MethVsField_1).three) diff --git a/test/files/jvm/natives.scala b/test/files/jvm/natives.scala index f1b74b74861d..14e65970acef 100644 --- a/test/files/jvm/natives.scala +++ b/test/files/jvm/natives.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.to.fork +//> using javaOpt -Dneeds.to.fork object Test { diff --git a/test/files/jvm/nil-conversion/Foo_1.scala b/test/files/jvm/nil-conversion/Foo_1.scala index 51144f297cec..1fcf37c0393d 100644 --- a/test/files/jvm/nil-conversion/Foo_1.scala +++ b/test/files/jvm/nil-conversion/Foo_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:none +//> using options -opt:none class Foo_1 { def foo: List[Int] = List() diff --git a/test/files/jvm/nil-conversion/Test.scala b/test/files/jvm/nil-conversion/Test.scala index 7305989fb5f7..78013c21b437 100644 --- a/test/files/jvm/nil-conversion/Test.scala +++ b/test/files/jvm/nil-conversion/Test.scala @@ -1,4 +1,4 @@ -// scalac: -opt:none +//> using options -opt:none import scala.tools.partest.BytecodeTest import scala.tools.asm diff --git a/test/files/jvm/non-fatal-tests.scala b/test/files/jvm/non-fatal-tests.scala index 70cd00c58d5f..bc4106c91f64 100644 --- a/test/files/jvm/non-fatal-tests.scala +++ b/test/files/jvm/non-fatal-tests.scala @@ -42,6 +42,4 @@ trait NonFatalTests { object Test extends App -with NonFatalTests { - System.exit(0) -} +with NonFatalTests diff --git a/test/files/jvm/scala-concurrent-tck-b.check b/test/files/jvm/scala-concurrent-tck-b.check new file mode 100644 index 000000000000..9c0aad3aa893 --- /dev/null +++ b/test/files/jvm/scala-concurrent-tck-b.check @@ -0,0 +1,2 @@ +starting testUncaughtExceptionReporting +finished testUncaughtExceptionReporting diff --git a/test/files/jvm/scala-concurrent-tck-b.scala b/test/files/jvm/scala-concurrent-tck-b.scala new file mode 100644 index 000000000000..882440297750 --- /dev/null +++ b/test/files/jvm/scala-concurrent-tck-b.scala @@ -0,0 +1,120 @@ +//> using jvm 9+ +import scala.concurrent.{ + TimeoutException, + ExecutionContext, + ExecutionContextExecutorService, + Await, + Awaitable, +} +import scala.annotation.tailrec +import scala.concurrent.duration._ +import scala.tools.testkit.AssertUtil.{Fast, Slow, waitFor, waitForIt} +import scala.util.{Try, Success, Failure} +import scala.util.chaining._ +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit.{MILLISECONDS => Milliseconds, SECONDS => Seconds} + +trait TestBase { + + trait Done { def apply(proof: => Boolean): Unit } + + def once(body: Done => Unit): Unit = { + import java.util.concurrent.LinkedBlockingQueue + val q = new LinkedBlockingQueue[Try[Boolean]] + body(new Done { + def apply(proof: => Boolean): Unit = q offer Try(proof) + }) + var tried: Try[Boolean] = null + def check = q.poll(5000L, Milliseconds).tap(tried = _) != null + waitForIt(check, progress = Slow, label = "concurrent-tck") + assert(tried.isSuccess) + assert(tried.get) + // Check that we don't get more than one completion + assert(q.poll(50, Milliseconds) eq null) + } + + def test[T](name: String)(body: => T): T = { + println(s"starting $name") + body.tap(_ => println(s"finished $name")) + } + + def await[A](value: Awaitable[A]): A = { + def check: Option[A] = + Try(Await.result(value, Duration(500, "ms"))) match { + case Success(x) => Some(x) + case Failure(_: TimeoutException) => None + case Failure(t) => throw t + } + waitFor(check, progress = Fast, label = "concurrent-tck test result") + } +} + +class ReportingExecutionContext extends TestBase { + val progress = Fast + @volatile var thread: Thread = null + @volatile var reportedOn: Thread = null + @volatile var reported: Throwable = null + val latch = new CountDownLatch(1) + + def report(t: Thread, e: Throwable): Unit = { + reportedOn = t + reported = e + latch.countDown() + } + + def ecesUsingDefaultFactory = { + import java.util.concurrent.{ForkJoinPool} + import java.util.function.Predicate + import scala.reflect.internal.util.RichClassLoader._ + + val path = "java.util.concurrent.ForkJoinPool" + val n = 2 // parallelism + val factory = scala.concurrent.TestUtil.threadFactory(report) + val ueh: Thread.UncaughtExceptionHandler = report(_, _) + val async = true + val coreSize = 4 + val maxSize = 4 + val minRun = 1 // minimumRunnable for liveness + val saturate: Predicate[ForkJoinPool] = (fjp: ForkJoinPool) => false // whether to continue after blocking at maxSize + val keepAlive = 2000L + val fjp = new ForkJoinPool(n, factory, ueh, async, coreSize, maxSize, minRun, saturate, keepAlive, Milliseconds) + ExecutionContext.fromExecutorService(fjp, report(null, _)) + } + + def testUncaughtExceptionReporting(ec: ExecutionContextExecutorService): Unit = once { + done => + val example = new InterruptedException + + @tailrec def spinForThreadDeath(turns: Int): Boolean = + turns > 0 && (thread != null && !thread.isAlive || { Thread.sleep(100L); spinForThreadDeath(turns - 1) }) + + def truthfully(b: Boolean): Option[Boolean] = if (b) Some(true) else None + + // jdk17 thread receives pool exception handler, so wait for thread to die slow and painful expired keepalive + def threadIsDead = waitFor(truthfully(spinForThreadDeath(turns = 10)), progress = progress, label = "concurrent-tck-thread-death") + + try { + ec.execute(() => { + thread = Thread.currentThread + throw example + }) + latch.await(2, Seconds) + done(threadIsDead && (example.eq(reported) || example.eq(reported.getCause))) + } + finally ec.shutdown() + } + + test("testUncaughtExceptionReporting")(testUncaughtExceptionReporting { + ecesUsingDefaultFactory + }) +} + +object Test extends App { + new ReportingExecutionContext +} + +package scala.concurrent { + object TestUtil { + def threadFactory(uncaughtExceptionHandler: Thread.UncaughtExceptionHandler) = new impl.ExecutionContextImpl.DefaultThreadFactory(daemonic=true, maxBlockers=256, prefix="test-thread", uncaughtExceptionHandler) + } +} diff --git a/test/files/jvm/scala-concurrent-tck.check b/test/files/jvm/scala-concurrent-tck.check index 864f5b7949ff..dbe69425548c 100644 --- a/test/files/jvm/scala-concurrent-tck.check +++ b/test/files/jvm/scala-concurrent-tck.check @@ -124,8 +124,6 @@ starting rejectedExecutionException finished rejectedExecutionException starting testNameOfGlobalECThreads finished testNameOfGlobalECThreads -starting testUncaughtExceptionReporting -finished testUncaughtExceptionReporting starting testOnSuccessCustomEC finished testOnSuccessCustomEC starting testKeptPromiseCustomEC diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala index f31d8b2a5757..3a9119c438a9 100644 --- a/test/files/jvm/scala-concurrent-tck.scala +++ b/test/files/jvm/scala-concurrent-tck.scala @@ -1,9 +1,11 @@ + import scala.concurrent.{ Future, Promise, TimeoutException, ExecutionException, ExecutionContext, + ExecutionContextExecutorService, CanAwait, Await, Awaitable, @@ -15,7 +17,7 @@ import scala.reflect.{classTag, ClassTag} import scala.tools.testkit.AssertUtil.{Fast, Slow, assertThrows, waitFor, waitForIt} import scala.util.{Try, Success, Failure} import scala.util.chaining._ -import java.util.concurrent.CountDownLatch +import java.util.concurrent.{CountDownLatch, ThreadPoolExecutor} import java.util.concurrent.TimeUnit.{MILLISECONDS => Milliseconds, SECONDS => Seconds} trait TestBase { @@ -29,7 +31,7 @@ trait TestBase { def apply(proof: => Boolean): Unit = q offer Try(proof) }) var tried: Try[Boolean] = null - def check = { tried = q.poll(5000L, Milliseconds) ; tried != null } + def check = q.poll(5000L, Milliseconds).tap(tried = _) != null waitForIt(check, progress = Slow, label = "concurrent-tck") assert(tried.isSuccess) assert(tried.get) @@ -747,7 +749,7 @@ class Blocking extends TestBase { class BlockContexts extends TestBase { import ExecutionContext.Implicits._ - import scala.concurrent.{ Await, Awaitable, BlockContext } + import scala.concurrent.BlockContext private def getBlockContext(body: => BlockContext): BlockContext = await(Future(body)) @@ -877,7 +879,6 @@ class GlobalExecutionContext extends TestBase { } class CustomExecutionContext extends TestBase { - import scala.concurrent.{ ExecutionContext, Awaitable } def defaultEC = ExecutionContext.global @@ -987,37 +988,6 @@ class CustomExecutionContext extends TestBase { assert(count >= 1) } - def testUncaughtExceptionReporting(): Unit = once { done => - val example = new InterruptedException - val latch = new CountDownLatch(1) - @volatile var thread: Thread = null - @volatile var reported: Throwable = null - val ec = ExecutionContext.fromExecutorService(null, t => { - reported = t - latch.countDown() - }) - - @tailrec def waitForThreadDeath(turns: Int): Boolean = - turns > 0 && (thread != null && !thread.isAlive || { Thread.sleep(10L) ; waitForThreadDeath(turns - 1) }) - - def truthfully(b: Boolean): Option[Boolean] = if (b) Some(true) else None - - // jdk17 thread receives pool exception handler, so wait for thread to die slow and painful expired keepalive - def threadIsDead = - waitFor(truthfully(waitForThreadDeath(turns = 100)), progress = Slow, label = "concurrent-tck-thread-death") - - try { - ec.execute(() => { - thread = Thread.currentThread - throw example - }) - latch.await(2, Seconds) - done(threadIsDead && (reported eq example)) - } - finally ec.shutdown() - } - - test("testUncaughtExceptionReporting")(testUncaughtExceptionReporting()) test("testOnSuccessCustomEC")(testOnSuccessCustomEC()) test("testKeptPromiseCustomEC")(testKeptPromiseCustomEC()) test("testCallbackChainCustomEC")(testCallbackChainCustomEC()) @@ -1088,6 +1058,4 @@ extends App { new GlobalExecutionContext new CustomExecutionContext new ExecutionContextPrepare - - System.exit(0) } diff --git a/test/files/jvm/t10610.scala b/test/files/jvm/t10610.scala index a697bc941c88..b54e0de685a8 100644 --- a/test/files/jvm/t10610.scala +++ b/test/files/jvm/t10610.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:serial +//> using options -Xlint:serial // @SerialVersionUID(0L) // should have no effect trait T diff --git a/test/files/jvm/t1600.scala b/test/files/jvm/t1600.scala index da04a5f7c923..4211294e386c 100644 --- a/test/files/jvm/t1600.scala +++ b/test/files/jvm/t1600.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.forked.jvm.maybe.because.context.classloader +//> using javaOpt -Dneeds.forked.jvm.maybe.because.context.classloader /** * Checks that serialization of hash-based collections works correctly if the hashCode diff --git a/test/files/jvm/t7253/test.scala b/test/files/jvm/t7253/test.scala index c506a116ae0c..9ee22aa71887 100644 --- a/test/files/jvm/t7253/test.scala +++ b/test/files/jvm/t7253/test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint import scala.tools.asm.Opcodes import scala.tools.partest.BytecodeTest diff --git a/test/files/jvm/t8582.scala b/test/files/jvm/t8582.scala index da76d80e8de9..8d33663d45e3 100644 --- a/test/files/jvm/t8582.scala +++ b/test/files/jvm/t8582.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation import scala.tools.partest.BytecodeTest import scala.jdk.CollectionConverters._ diff --git a/test/files/jvm/t8689.scala b/test/files/jvm/t8689.scala index 2eeb12a12cf1..bf4fb6ac9444 100644 --- a/test/files/jvm/t8689.scala +++ b/test/files/jvm/t8689.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.forked.jvm +//> using javaOpt -Dneeds.forked.jvm object Test { def main(args: Array[String]): Unit = { import scala.concurrent._ diff --git a/test/files/neg/FooMapView.scala b/test/files/neg/FooMapView.scala index ce448be3a301..103bf924246d 100644 --- a/test/files/neg/FooMapView.scala +++ b/test/files/neg/FooMapView.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation // class FooMapView extends collection.MapView[Int,Int] { def iterator: Iterator[(Int,Int)] = ??? diff --git a/test/files/neg/abstract-explaintypes.scala b/test/files/neg/abstract-explaintypes.scala index 99e09b956d39..2b2d3e6ad9c1 100644 --- a/test/files/neg/abstract-explaintypes.scala +++ b/test/files/neg/abstract-explaintypes.scala @@ -1,4 +1,4 @@ -// scalac: -explaintypes +//> using options -explaintypes // trait A { type T <: A; diff --git a/test/files/neg/abstract-inaccessible.scala b/test/files/neg/abstract-inaccessible.scala index d2636a53e881..006ccc84a407 100644 --- a/test/files/neg/abstract-inaccessible.scala +++ b/test/files/neg/abstract-inaccessible.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:inaccessible +//> using options -Xfatal-warnings -Xlint:inaccessible // package foo { private[foo] trait Bippy { } diff --git a/test/files/neg/adapt-to-any-member.check b/test/files/neg/adapt-to-any-member.check new file mode 100644 index 000000000000..6309622bb05e --- /dev/null +++ b/test/files/neg/adapt-to-any-member.check @@ -0,0 +1,6 @@ +adapt-to-any-member.scala:6: warning: conversion Elvis adds universal member method eq to type A + def f[A](x: A) = if (x eq null) 0 else 1 // warn + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/adapt-to-any-member.scala b/test/files/neg/adapt-to-any-member.scala new file mode 100644 index 000000000000..e4ecc81fceac --- /dev/null +++ b/test/files/neg/adapt-to-any-member.scala @@ -0,0 +1,14 @@ + +//> using options -Werror -Xlint:universal-methods + +class C { + import C._ + def f[A](x: A) = if (x eq null) 0 else 1 // warn + def g[A](x: A) = if (x.hashCode(0) == 0) 0 else 1 // nowarn +} +object C { + implicit class Elvis[A](alt: => A) { + def ?:(a: A): A = if (a.asInstanceOf[AnyRef] ne null) a else alt + def hashCode(seed: Int): Int = seed + } +} diff --git a/test/files/neg/aladdin1055/Test_1.scala b/test/files/neg/aladdin1055/Test_1.scala index 4e2fb0c3ba14..4dd40df63666 100644 --- a/test/files/neg/aladdin1055/Test_1.scala +++ b/test/files/neg/aladdin1055/Test_1.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings object Test { def foo(t: A.T) = t match { case a: A.TT => 0 diff --git a/test/files/neg/ambiguous-same.check b/test/files/neg/ambiguous-same.check deleted file mode 100644 index abdf013a7ef8..000000000000 --- a/test/files/neg/ambiguous-same.check +++ /dev/null @@ -1,6 +0,0 @@ -ambiguous-same.scala:13: error: reference to x is ambiguous; -it is both defined in object X and imported subsequently by -import X.x - x - ^ -1 error diff --git a/test/files/neg/ambiguous-same.scala b/test/files/neg/ambiguous-same.scala deleted file mode 100644 index 2bf3ba5ea60a..000000000000 --- a/test/files/neg/ambiguous-same.scala +++ /dev/null @@ -1,39 +0,0 @@ - -// When faced with ambiguities between imports, -// an attempt is made to see if the imports intend -// identical types. -// -// Here, no attempt is made to notice that x -// names the same thing, because the definition is in this file. -// -object X { - val x = 42 - def f = { - import X.x - x - // not OK, import doesn't shadow definition - } -} - -// counterexamples showing normal behavior, no puzzlers - -object X2 { - val x = 42 - def f = { - def x = ??? - import X2.{x => x2} - x2 // OK, rename makes it obvious there were some poor naming choices - } -} - -object Y { - import Z._ - - object Z { - def z = 17 - def f = z // OK, definition shadows import - } - object Other { - def g = z // the casually scoped import is useful - } -} diff --git a/test/files/neg/and-future.scala b/test/files/neg/and-future.scala index 1092c013b186..01e821206798 100644 --- a/test/files/neg/and-future.scala +++ b/test/files/neg/and-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // trait X diff --git a/test/files/neg/annots-constant-neg.check b/test/files/neg/annots-constant-neg.check index f531b2a98540..5c0562f60f2a 100644 --- a/test/files/neg/annots-constant-neg.check +++ b/test/files/neg/annots-constant-neg.check @@ -1,7 +1,7 @@ -Test.scala:12: error: class Ann1 cannot have auxiliary constructors because it extends ConstantAnnotation +Test.scala:11: error: class Ann1 cannot have auxiliary constructors because it extends ConstantAnnotation def this(s: String) = this(0) // err ^ -Test.scala:14: error: class Ann2 needs to have exactly one argument list because it extends ConstantAnnotation +Test.scala:13: error: class Ann2 needs to have exactly one argument list because it extends ConstantAnnotation class Ann2(x: Int)(y: Int) extends ConstantAnnotation // err ^ Test.scala:27: error: annotation argument needs to be a constant; found: Test.this.nonConst @@ -69,10 +69,6 @@ Test.scala:69: error: Java annotation SuppressWarnings is abstract; cannot be in Error occurred in an application involving default arguments. @Ann(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def u17 = 0 // err ^ -Test.scala:69: error: not found: value value -Error occurred in an application involving default arguments. - @Ann(value = 0, c = Array(new SuppressWarnings(value = Array("")))) def u17 = 0 // err - ^ Test.scala:71: error: annotation argument needs to be a constant; found: new scala.inline() @Ann(value = 0, c = Array(new inline)) def u18 = 0 // err ^ @@ -89,7 +85,7 @@ Test.scala:79: error: not enough arguments for constructor Ann2: (x: Int)(y: Int Unspecified value parameter x. @Ann2 def v7 = 0 // err ^ -Test.scala:80: error: missing argument list for constructor Ann2 in class Ann2 +Test.scala:80: error: missing argument list for constructor Ann2 in class Ann2 of type (x: Int)(y: Int): Ann2 @Ann2(x = 0) def v8 = 0 // err ^ Test.scala:83: error: no arguments allowed for nullary constructor Ann3: (): Ann3 @@ -107,4 +103,4 @@ currently not supported; ignoring arguments List(0) @Ann2(x = 0)(y = 0) def v9 = 0 // warn ^ 1 warning -32 errors +31 errors diff --git a/test/files/neg/annots-constant-neg/Test.scala b/test/files/neg/annots-constant-neg/Test.scala index fa2779b94ca4..3eccee0fdc84 100644 --- a/test/files/neg/annots-constant-neg/Test.scala +++ b/test/files/neg/annots-constant-neg/Test.scala @@ -7,8 +7,7 @@ class Ann( b: Class[_] = classOf[String], c: Array[Object] = Array()) extends ConstantAnnotation -// non-constant defaults are allowed -class Ann1(value: Int = Test.nonConst) extends ConstantAnnotation { +class Ann1(value: Int = 1) extends ConstantAnnotation { def this(s: String) = this(0) // err } class Ann2(x: Int)(y: Int) extends ConstantAnnotation // err @@ -16,7 +15,8 @@ class Ann3 extends ConstantAnnotation class Ann4(x: Int = 0, value: Int) extends ConstantAnnotation class Ann5() extends ConstantAnnotation class Ann6(x: Int) extends ConstantAnnotation // scala/bug#11724 -class Ann7[T](x: T) extends annotation.ConstantAnnotation // scala/bug#11724 +class Ann7[T](x: T) extends ConstantAnnotation // scala/bug#11724 +class Ann8(x: Int = Test.nonConst) extends ConstantAnnotation // defaults of `ConstantAnnotation` are not enforced to be constants object Test { final val const = 1 diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check index a9a1f7ebf48b..854f7004002c 100644 --- a/test/files/neg/applydynamic_sip.check +++ b/test/files/neg/applydynamic_sip.check @@ -14,9 +14,6 @@ error after rewriting to Test.this.qual.("sel") possible cause: maybe a wrong Dynamic method signature? qual.sel(arg = a, a2: _*) ^ -applydynamic_sip.scala:10: error: not found: value arg - qual.sel(arg = a, a2: _*) - ^ applydynamic_sip.scala:11: error: applyDynamicNamed does not support passing a vararg parameter qual.sel(arg, arg2 = "a2", a2: _*) ^ @@ -28,9 +25,6 @@ possible cause: maybe a wrong Dynamic method signature? applydynamic_sip.scala:11: error: not found: value arg qual.sel(arg, arg2 = "a2", a2: _*) ^ -applydynamic_sip.scala:11: error: not found: value arg2 - qual.sel(arg, arg2 = "a2", a2: _*) - ^ applydynamic_sip.scala:20: error: type mismatch; found : String("sel") required: Int @@ -52,9 +46,6 @@ error after rewriting to Test.this.bad1.applyDynamicNamed("sel") possible cause: maybe a wrong Dynamic method signature? bad1.sel(a = 1) ^ -applydynamic_sip.scala:22: error: reassignment to val - bad1.sel(a = 1) - ^ applydynamic_sip.scala:23: error: type mismatch; found : String("sel") required: Int @@ -77,12 +68,9 @@ error after rewriting to Test.this.bad2.applyDynamicNamed("sel") possible cause: maybe a wrong Dynamic method signature? bad2.sel(a = 1) ^ -applydynamic_sip.scala:33: error: reassignment to val - bad2.sel(a = 1) - ^ applydynamic_sip.scala:34: error: Int does not take parameters error after rewriting to Test.this.bad2.updateDynamic("sel") possible cause: maybe a wrong Dynamic method signature? bad2.sel = 1 ^ -19 errors +15 errors diff --git a/test/files/neg/applydynamic_sip.scala b/test/files/neg/applydynamic_sip.scala index cc37378903b3..5884dbec7544 100644 --- a/test/files/neg/applydynamic_sip.scala +++ b/test/files/neg/applydynamic_sip.scala @@ -1,4 +1,4 @@ -// scalac: -language:dynamics +//> using options -language:dynamics // object Test extends App { val qual: Dynamic = ??? diff --git a/test/files/neg/auto-application.scala b/test/files/neg/auto-application.scala index 0da77191caf8..906bd16d158e 100644 --- a/test/files/neg/auto-application.scala +++ b/test/files/neg/auto-application.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Werror +//> using options -deprecation -Werror class Test { ("": Any).##() diff --git a/test/files/neg/bad-advice.scala b/test/files/neg/bad-advice.scala index d0706197278b..0683a61036f0 100644 --- a/test/files/neg/bad-advice.scala +++ b/test/files/neg/bad-advice.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Bip object Test { diff --git a/test/files/neg/badtok-1.scala b/test/files/neg/badtok-1.scala index 563711e2a517..c9e98d468bb8 100644 --- a/test/files/neg/badtok-1.scala +++ b/test/files/neg/badtok-1.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation -Werror +//> using options -Xlint:deprecation -Werror // // bug 989 '42' diff --git a/test/files/neg/byname-implicit.check b/test/files/neg/byname-implicit.check index 3aca2b998ee3..082a0dbd9e4e 100644 --- a/test/files/neg/byname-implicit.check +++ b/test/files/neg/byname-implicit.check @@ -1,13 +1,13 @@ -byname-implicit.scala:84: warning: Implicits applied to block expressions after overload resolution may have unexpected semantics +byname-implicit.scala:84: warning: Overloaded implicit conversions that take a by-name parameter are applied to the entire block, not just the result expression. Foo.bar { println("barring"); 0 } // warn ^ -byname-implicit.scala:14: warning: Block result was adapted via implicit conversion (method ints are strs) taking a by-name parameter +byname-implicit.scala:14: warning: Block result expression was adapted via implicit conversion (method ints are strs) taking a by-name parameter; only the result was passed, not the entire block. 42 // warn ^ -byname-implicit.scala:25: warning: Block result was adapted via implicit conversion (method bools are strs) taking a by-name parameter +byname-implicit.scala:25: warning: Block result expression was adapted via implicit conversion (method bools are strs) taking a by-name parameter; only the result was passed, not the entire block. true // warn ^ -byname-implicit.scala:68: warning: Block result was adapted via implicit conversion (method fromBooleanCheck) taking a by-name parameter +byname-implicit.scala:68: warning: Block result expression was adapted via implicit conversion (method fromBooleanCheck) taking a by-name parameter; only the result was passed, not the entire block. false // warn ^ error: No warnings can be incurred under -Werror. diff --git a/test/files/neg/byname-implicit.scala b/test/files/neg/byname-implicit.scala index 49ce1011eda4..937f45a32abf 100644 --- a/test/files/neg/byname-implicit.scala +++ b/test/files/neg/byname-implicit.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:byname-implicit +//> using options -Werror -Xlint:byname-implicit import language._ @@ -84,3 +84,11 @@ object FooTest extends App { Foo.bar { println("barring"); 0 } // warn } +class Nowarn { + implicit def cv(n: => Int): String = n.toString + + def show(s: String) = println(s"[$s]") + + def f(): Unit = show(cv(42)) // nowarn because it only warns if statements + def g(): Unit = show { println(); cv(42) } // nowarn anymore because explicit call by user +} diff --git a/test/files/neg/case-collision-multifile/one.scala b/test/files/neg/case-collision-multifile/one.scala index 1ae99705908b..5da343dae653 100644 --- a/test/files/neg/case-collision-multifile/one.scala +++ b/test/files/neg/case-collision-multifile/one.scala @@ -1,2 +1,2 @@ -// scalac: -Werror +//> using options -Werror -Ybackend-parallelism 1 class HotDog diff --git a/test/files/neg/case-collision.scala b/test/files/neg/case-collision.scala index 378c6c3957fe..4e005dc40479 100644 --- a/test/files/neg/case-collision.scala +++ b/test/files/neg/case-collision.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // package foo { diff --git a/test/files/neg/case-cross.check b/test/files/neg/case-cross.check new file mode 100644 index 000000000000..0517c49c04b2 --- /dev/null +++ b/test/files/neg/case-cross.check @@ -0,0 +1,6 @@ +case-cross.scala:5: error: access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C.apply +case class C private (c: Int) { + ^ +1 error diff --git a/test/files/neg/case-cross.scala b/test/files/neg/case-cross.scala new file mode 100644 index 000000000000..273dc438b77e --- /dev/null +++ b/test/files/neg/case-cross.scala @@ -0,0 +1,7 @@ +//> using options -Xsource:3 + +// warn about case class synthetic method getting access modifier from constructor + +case class C private (c: Int) { + def copy(c: Int) = this // warn about apply instead +} diff --git a/test/files/neg/case-warn.check b/test/files/neg/case-warn.check new file mode 100644 index 000000000000..64e18ed54216 --- /dev/null +++ b/test/files/neg/case-warn.check @@ -0,0 +1,9 @@ +case-warn.scala:6: warning: access modifiers for `copy` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +case class C private (c: Int) + ^ +case-warn.scala:6: warning: access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +case class C private (c: Int) + ^ +error: No warnings can be incurred under -Werror. +2 warnings +1 error diff --git a/test/files/neg/case-warn.scala b/test/files/neg/case-warn.scala new file mode 100644 index 000000000000..f72f09a9f60a --- /dev/null +++ b/test/files/neg/case-warn.scala @@ -0,0 +1,6 @@ +//> using options -Werror -Xsource:3 -Wconf:cat=scala3-migration:w + +// warn about case class synthetic method getting access modifier from constructor. +// if erroring, the error message for apply is hidden by previous error for copy. + +case class C private (c: Int) diff --git a/test/files/neg/caseclass_private_constructor.scala b/test/files/neg/caseclass_private_constructor.scala index 344c23d76be9..3282dfd85011 100644 --- a/test/files/neg/caseclass_private_constructor.scala +++ b/test/files/neg/caseclass_private_constructor.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3-cross -Wconf:cat=scala3-migration:s +//> using options -Xsource:3 -Wconf:cat=scala3-migration:s -Xsource-features:case-apply-copy-access case class A private (i: Int) object A diff --git a/test/files/neg/catch-all.scala b/test/files/neg/catch-all.scala index eb9f9b506716..46d6d757e4fb 100644 --- a/test/files/neg/catch-all.scala +++ b/test/files/neg/catch-all.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // object CatchAll { try { "warn" } catch { case _ => } diff --git a/test/files/neg/check-dead.scala b/test/files/neg/check-dead.scala index f702c754e6f1..efe12f0bb4bf 100644 --- a/test/files/neg/check-dead.scala +++ b/test/files/neg/check-dead.scala @@ -1,4 +1,4 @@ -// scalac: -Wdead-code -Werror +//> using options -Wdead-code -Werror object Other { def oops(msg: String = "xxx"): Nothing = throw new Exception(msg) // should not warn } diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check index 1de2afd4944b..f150f255fb1f 100644 --- a/test/files/neg/checksensible.check +++ b/test/files/neg/checksensible.check @@ -1,120 +1,129 @@ checksensible.scala:54: warning: symbol literal is deprecated; use Symbol("sym") instead [quickfixable] - (1 != 'sym) + (1 != 'sym) // w ^ checksensible.scala:15: warning: comparing a fresh object using `eq` will always yield false - (new AnyRef) eq (new AnyRef) + (new AnyRef) eq (new AnyRef) // w ^ checksensible.scala:16: warning: comparing a fresh object using `ne` will always yield true - (new AnyRef) ne (new AnyRef) + (new AnyRef) ne (new AnyRef) // w ^ checksensible.scala:17: warning: comparing a fresh object using `eq` will always yield false - Shmoopie eq (new AnyRef) + Shmoopie eq (new AnyRef) // w ^ checksensible.scala:18: warning: comparing a fresh object using `eq` will always yield false - (Shmoopie: AnyRef) eq (new AnyRef) + (Shmoopie: AnyRef) eq (new AnyRef) // w ^ checksensible.scala:19: warning: comparing a fresh object using `eq` will always yield false - (new AnyRef) eq Shmoopie + (new AnyRef) eq Shmoopie // w ^ checksensible.scala:20: warning: comparing a fresh object using `eq` will always yield false - (new AnyRef) eq null + (new AnyRef) eq null // w ^ checksensible.scala:21: warning: comparing a fresh object using `eq` will always yield false - null eq new AnyRef + null eq new AnyRef // w ^ checksensible.scala:28: warning: comparing values of types Unit and Int using `==` will always yield false - (c = 1) == 0 + (c = 1) == 0 // w ^ checksensible.scala:29: warning: comparing values of types Integer and Unit using `==` will always yield false - 0 == (c = 1) + 0 == (c = 1) // w ^ checksensible.scala:31: warning: comparing values of types Int and String using `==` will always yield false - 1 == "abc" + 1 == "abc" // w ^ +checksensible.scala:34: warning: comparing values of types String and Int using `==` will always yield false + "abc" == 1 // w: string equality is known + ^ checksensible.scala:35: warning: comparing values of types Some[Int] and Int using `==` will always yield false - Some(1) == 1 // as above + Some(1) == 1 // w: case class equals ^ checksensible.scala:40: warning: comparing a fresh object using `==` will always yield false - new AnyRef == 1 + new AnyRef == 1 // w: fresh object ^ checksensible.scala:43: warning: comparing values of types Int and Boolean using `==` will always yield false - 1 == java.lang.Boolean.valueOf(true) + 1 == java.lang.Boolean.valueOf(true) // w ^ checksensible.scala:45: warning: comparing values of types Int and Boolean using `!=` will always yield true - 1 != true + 1 != true // w ^ checksensible.scala:46: warning: comparing values of types Unit and Boolean using `==` will always yield false - () == true + () == true // w ^ checksensible.scala:47: warning: comparing values of types Unit and Unit using `==` will always yield true - () == () + () == () // w ^ checksensible.scala:48: warning: comparing values of types Unit and Unit using `==` will always yield true - () == println() + () == println() // w ^ checksensible.scala:49: warning: comparing values of types Unit and scala.runtime.BoxedUnit using `==` will always yield true - () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false + () == scala.runtime.BoxedUnit.UNIT // w ^ checksensible.scala:50: warning: comparing values of types scala.runtime.BoxedUnit and Unit using `!=` will always yield false - scala.runtime.BoxedUnit.UNIT != () + scala.runtime.BoxedUnit.UNIT != () // w ^ checksensible.scala:53: warning: comparing values of types Int and Unit using `!=` will always yield true - (1 != println()) + (1 != println()) // w ^ checksensible.scala:54: warning: comparing values of types Int and Symbol using `!=` will always yield true - (1 != 'sym) + (1 != 'sym) // w ^ checksensible.scala:60: warning: comparing a fresh object using `==` will always yield false - ((x: Int) => x + 1) == null + ((x: Int) => x + 1) == null // w (fresh object) ^ checksensible.scala:61: warning: comparing a fresh object using `==` will always yield false - Bep == ((_: Int) + 1) + Bep == ((_: Int) + 1) // w (fresh object) ^ checksensible.scala:63: warning: comparing a fresh object using `==` will always yield false - new Object == new Object + new Object == new Object // w ^ checksensible.scala:64: warning: comparing a fresh object using `==` will always yield false - new Object == "abc" + new Object == "abc" // w ^ checksensible.scala:65: warning: comparing a fresh object using `!=` will always yield true - new Exception() != new Exception() + new Exception() != new Exception() // w ^ checksensible.scala:68: warning: comparing values of types Int and Null using `==` will always yield false - if (foo.length == null) "plante" else "plante pas" + if (foo.length == null) "plante" else "plante pas" // w ^ checksensible.scala:73: warning: comparing values of types Bip and Bop using `==` will always yield false - (x1 == x2) + (x1 == x2) // w ^ checksensible.scala:83: warning: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==` will always yield false - c3 == z1 + c3 == z1 // w ^ checksensible.scala:84: warning: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==` will always yield false - z1 == c3 + z1 == c3 // w ^ checksensible.scala:85: warning: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=` will always yield true - z1 != c3 + z1 != c3 // w ^ checksensible.scala:86: warning: comparing values of types EqEqRefTest.this.C3 and String using `!=` will always yield true - c3 != "abc" + c3 != "abc" // w ^ checksensible.scala:97: warning: comparing values of types Unit and Int using `!=` will always yield true - while ((c = in.read) != -1) + while ((c = in.read) != -1) // w ^ checksensible.scala:105: warning: comparing values of types Long and Int using `equals` unsafely bypasses cooperative equality; use `==` instead - 1L equals 1 + 1L equals 1 // w: bypasses coopeq ^ checksensible.scala:112: warning: comparing values of types Any and Int using `equals` unsafely bypasses cooperative equality; use `==` instead - (1L: Any) equals 1 + (1L: Any) equals 1 // w: bypasses coopeq ^ checksensible.scala:113: warning: comparing values of types AnyVal and Int using `equals` unsafely bypasses cooperative equality; use `==` instead - (1L: AnyVal) equals 1 + (1L: AnyVal) equals 1 // w: bypasses coopeq ^ checksensible.scala:114: warning: comparing values of types AnyVal and AnyVal using `equals` unsafely bypasses cooperative equality; use `==` instead - (1L: AnyVal) equals (1: AnyVal) + (1L: AnyVal) equals (1: AnyVal) // w: bypasses coopeq ^ checksensible.scala:117: warning: comparing values of types A and Int using `equals` unsafely bypasses cooperative equality; use `==` instead - def foo[A](a: A) = a.equals(1) + def foo[A](a: A) = a.equals(1) // w: bypasses coopeq ^ +checksensible.scala:126: warning: eq_refine.E and String are unrelated: they will most likely never compare equal + if (e == "") ??? // warn about comparing unrelated types + ^ +checksensible.scala:129: warning: eq_refine.SE and String are unrelated: they will most likely never compare equal + if (se == "") ??? // types are still unrelated + ^ error: No warnings can be incurred under -Werror. -39 warnings +42 warnings 1 error diff --git a/test/files/neg/checksensible.scala b/test/files/neg/checksensible.scala index 65cfe390eddf..91ae29a8f1ac 100644 --- a/test/files/neg/checksensible.scala +++ b/test/files/neg/checksensible.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Werror -deprecation // final class Bip { def <=(other: Bop) = true } final class Bop { } @@ -12,65 +12,65 @@ final class Zing { class RefEqTest { object Shmoopie - (new AnyRef) eq (new AnyRef) - (new AnyRef) ne (new AnyRef) - Shmoopie eq (new AnyRef) - (Shmoopie: AnyRef) eq (new AnyRef) - (new AnyRef) eq Shmoopie - (new AnyRef) eq null - null eq new AnyRef + (new AnyRef) eq (new AnyRef) // w + (new AnyRef) ne (new AnyRef) // w + Shmoopie eq (new AnyRef) // w + (Shmoopie: AnyRef) eq (new AnyRef) // w + (new AnyRef) eq Shmoopie // w + (new AnyRef) eq null // w + null eq new AnyRef // w } // 13 warnings class EqEqValTest { var c = 0 - (c = 1) == 0 - 0 == (c = 1) - - 1 == "abc" - 1 == ("abc": Any) // doesn't warn because an Any may be a boxed Int - 1 == (1: Any) // as above - "abc" == 1 // warns because the lub of String and Int is Any - Some(1) == 1 // as above - - true == java.lang.Boolean.valueOf(true) // none of these should warn - java.lang.Boolean.valueOf(true) == true - - new AnyRef == 1 - 1 == new AnyRef // doesn't warn because it could be... - 1 == java.lang.Integer.valueOf(1) // ...something like this - 1 == java.lang.Boolean.valueOf(true) - - 1 != true - () == true - () == () - () == println() - () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false - scala.runtime.BoxedUnit.UNIT != () - (scala.runtime.BoxedUnit.UNIT: java.io.Serializable) != () // shouldn't warn - - (1 != println()) - (1 != 'sym) + (c = 1) == 0 // w + 0 == (c = 1) // w + + 1 == "abc" // w + 1 == ("abc": Any) // n: Any may be a boxed Int + 1 == (1: Any) // n: as above + "abc" == 1 // w: string equality is known + Some(1) == 1 // w: case class equals + + true == java.lang.Boolean.valueOf(true) // n + java.lang.Boolean.valueOf(true) == true // n + + new AnyRef == 1 // w: fresh object + 1 == (Integer.valueOf(1): AnyRef) // n: `AnyRef` could be an Integer, which is handled by cooperative equality + 1 == java.lang.Integer.valueOf(1) // n: cooperative equality (BoxesRunTime) + 1 == java.lang.Boolean.valueOf(true) // w + + 1 != true // w + () == true // w + () == () // w + () == println() // w + () == scala.runtime.BoxedUnit.UNIT // w + scala.runtime.BoxedUnit.UNIT != () // w + (scala.runtime.BoxedUnit.UNIT: java.io.Serializable) != () // n + + (1 != println()) // w + (1 != 'sym) // w } // 12 warnings class EqEqRefTest { val ref = new Bop - ((x: Int) => x + 1) == null - Bep == ((_: Int) + 1) + ((x: Int) => x + 1) == null // w (fresh object) + Bep == ((_: Int) + 1) // w (fresh object) - new Object == new Object - new Object == "abc" - new Exception() != new Exception() + new Object == new Object // w + new Object == "abc" // w + new Exception() != new Exception() // w val foo: Array[String] = Array("1","2","3") - if (foo.length == null) "plante" else "plante pas" + if (foo.length == null) "plante" else "plante pas" // w // final classes with default equals val x1 = new Bip val x2 = new Bop - (x1 == x2) + (x1 == x2) // w class C1 { } class C2 extends C1 { } @@ -80,21 +80,21 @@ class EqEqRefTest { val c3 = new C3 // these should always warn - c3 == z1 - z1 == c3 - z1 != c3 - c3 != "abc" - // this should warn when feeling chatty - c3 != z1 + c3 == z1 // w + z1 == c3 // w + z1 != c3 // w + c3 != "abc" // w + + c3 != z1 // n: method != is overridden // non-warners - (null: AnyRef) == (null: AnyRef) - (x1 <= x2) + (null: AnyRef) == (null: AnyRef) // n + (x1 <= x2) // n def main(args: Array[String]) = { val in = new java.io.FileInputStream(args(0)) var c = 0 - while ((c = in.read) != -1) + while ((c = in.read) != -1) // w print(c.toChar) in.close @@ -102,19 +102,29 @@ class EqEqRefTest { } class AnyEqualsTest { - 1L equals 1 + 1L equals 1 // w: bypasses coopeq // ok, because it's between the same numeric types - 1 equals 1 + 1 equals 1 // n // ok - 1L equals "string" + 1L equals "string" // n // ok - 1L.equals(()) - (1L: Any) equals 1 - (1L: AnyVal) equals 1 - (1L: AnyVal) equals (1: AnyVal) + 1L.equals(()) // n + (1L: Any) equals 1 // w: bypasses coopeq + (1L: AnyVal) equals 1 // w: bypasses coopeq + (1L: AnyVal) equals (1: AnyVal) // w: bypasses coopeq // ok - "string" equals 1 - def foo[A](a: A) = a.equals(1) + "string" equals 1 // n + def foo[A](a: A) = a.equals(1) // w: bypasses coopeq // ok - def bar[A <: AnyRef](a: A) = a.equals(1) + def bar[A <: AnyRef](a: A) = a.equals(1) // n +} + +object eq_refine { + class E + class SE extends Serializable + val e = new E + if (e == "") ??? // warn about comparing unrelated types + + val se = new SE + if (se == "") ??? // types are still unrelated } diff --git a/test/files/neg/choices.scala b/test/files/neg/choices.scala index fa1ba9ab8333..9803dfdf802a 100644 --- a/test/files/neg/choices.scala +++ b/test/files/neg/choices.scala @@ -1,4 +1,4 @@ -// scalac: -Yresolve-term-conflict +//> using options -Yresolve-term-conflict // object Test { def main(args: Array[String]): Unit = { diff --git a/test/files/neg/classOfDeprecation.scala b/test/files/neg/classOfDeprecation.scala index d7557e3f2e90..92bab336b57f 100644 --- a/test/files/neg/classOfDeprecation.scala +++ b/test/files/neg/classOfDeprecation.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Werror +//> using options -deprecation -Werror @deprecated("no no!", "like, forever") class C class ann(x: Any) extends annotation.Annotation diff --git a/test/files/neg/classmanifests_new_deprecations.scala b/test/files/neg/classmanifests_new_deprecations.scala index 71e5cd22ac80..2c253e170417 100644 --- a/test/files/neg/classmanifests_new_deprecations.scala +++ b/test/files/neg/classmanifests_new_deprecations.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror // object Test extends App { def rcm1[T: scala.reflect.ClassManifest] = ??? diff --git a/test/files/neg/cloneable.check b/test/files/neg/cloneable.check index 751a6b945622..a8e5617df6af 100644 --- a/test/files/neg/cloneable.check +++ b/test/files/neg/cloneable.check @@ -1,4 +1,4 @@ -cloneable.scala:6: warning: object X should not extend Cloneable. +cloneable.scala:7: warning: object X should not extend Cloneable. object X extends Base ^ error: No warnings can be incurred under -Werror. diff --git a/test/files/neg/cloneable.scala b/test/files/neg/cloneable.scala index 72f06d5558c8..98b33c23c3ec 100644 --- a/test/files/neg/cloneable.scala +++ b/test/files/neg/cloneable.scala @@ -1,5 +1,6 @@ //> using options -Werror -Xlint:cloneable +//> using retest.options -Wconf:cat=lint-cloneable:s class Base extends Cloneable diff --git a/test/files/neg/constructor-init-order.scala b/test/files/neg/constructor-init-order.scala index 8bb8d720cc83..baaaa3fb2cd6 100644 --- a/test/files/neg/constructor-init-order.scala +++ b/test/files/neg/constructor-init-order.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait Foo0 { val quux1: String diff --git a/test/files/neg/cycle-bounds.scala b/test/files/neg/cycle-bounds.scala index 5cf5db1996d1..6a709cec752a 100644 --- a/test/files/neg/cycle-bounds.scala +++ b/test/files/neg/cycle-bounds.scala @@ -1,4 +1,4 @@ -// scalac: -Ybreak-cycles +//> using options -Ybreak-cycles // // This should be allowed class Ok[T <: Comparable[_ >: T]] diff --git a/test/files/neg/delayed-init-ref.scala b/test/files/neg/delayed-init-ref.scala index eebabca1d310..1ad93fa328bd 100644 --- a/test/files/neg/delayed-init-ref.scala +++ b/test/files/neg/delayed-init-ref.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xlint -Xfatal-warnings +//> using options -deprecation -Xlint -Xfatal-warnings // trait T { val traitVal = "" diff --git a/test/files/neg/deprecated-annots.check b/test/files/neg/deprecated-annots.check index b85c663b1996..9fd704e7d1d5 100644 --- a/test/files/neg/deprecated-annots.check +++ b/test/files/neg/deprecated-annots.check @@ -1,5 +1,5 @@ deprecated-annots.scala:9: error: @scala.annotation.elidable is ignored in Scala 3 -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D @annotation.elidable(42) ^ diff --git a/test/files/neg/deprecated-annots.scala b/test/files/neg/deprecated-annots.scala index 609a02ffc3ef..fbdcd39b81cf 100644 --- a/test/files/neg/deprecated-annots.scala +++ b/test/files/neg/deprecated-annots.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xlint -Xsource:3 +//> using options -Werror -Xlint -Xsource:3 class C[@specialized A] diff --git a/test/files/neg/deprecated-options.check b/test/files/neg/deprecated-options.check index 31867bd09bf2..6153a635f83b 100644 --- a/test/files/neg/deprecated-options.check +++ b/test/files/neg/deprecated-options.check @@ -1,4 +1,4 @@ -warning: -Xsource is deprecated: instead of -Xsource:2.14, use -Xsource:3 or -Xsource:3-cross +warning: -Xsource is deprecated: instead of -Xsource:2.14, use -Xsource:3 and optionally -Xsource-features warning: -Xfuture is deprecated: Not used since 2.13. warning: -optimize is deprecated: Since 2.12, enables -opt:inline:**. This can be dangerous. warning: -Xexperimental is deprecated: Not used since 2.13. diff --git a/test/files/neg/deprecated-options.scala b/test/files/neg/deprecated-options.scala index ce12f38d587d..bea08b8e324f 100644 --- a/test/files/neg/deprecated-options.scala +++ b/test/files/neg/deprecated-options.scala @@ -1,4 +1,4 @@ // -// scalac: -Werror -deprecation -optimise -Xexperimental -Xfuture -Xsource:2.14 +//> using options -Werror -deprecation -optimise -Xexperimental -Xfuture -Xsource:2.14 // // Deprecated options are announced before compilation. diff --git a/test/files/neg/deprecated_widening.scala b/test/files/neg/deprecated_widening.scala index fade37e00d95..46fc46fdd25a 100644 --- a/test/files/neg/deprecated_widening.scala +++ b/test/files/neg/deprecated_widening.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // object Test { def foo(i: Int, l: Long): Unit = { diff --git a/test/files/neg/deprecationsFor3.check b/test/files/neg/deprecationsFor3.check index 898b49176838..5b47c9def436 100644 --- a/test/files/neg/deprecationsFor3.check +++ b/test/files/neg/deprecationsFor3.check @@ -1,10 +1,8 @@ deprecationsFor3.scala:4: warning: Unicode escapes in triple quoted strings are deprecated; use the literal character instead def inTripleQuoted = """\u0041""" // deprecation ^ -deprecationsFor3.scala:16: warning: Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +deprecationsFor3.scala:16: warning: Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. `x` (42) // migration ^ deprecationsFor3.scala:5: warning: Unicode escapes in raw interpolations are deprecated; use literal characters instead diff --git a/test/files/neg/deprecationsFor3.scala b/test/files/neg/deprecationsFor3.scala index 43925f1b1491..b06e613b6fc9 100644 --- a/test/files/neg/deprecationsFor3.scala +++ b/test/files/neg/deprecationsFor3.scala @@ -1,4 +1,4 @@ -//> using options -deprecation -Xmigration -Werror +//> using options -deprecation -Werror -Xmigration object UnicodeEscapes { def inTripleQuoted = """\u0041""" // deprecation diff --git a/test/files/neg/discard-advice-a.check b/test/files/neg/discard-advice-a.check new file mode 100644 index 000000000000..acdcb1a30ca9 --- /dev/null +++ b/test/files/neg/discard-advice-a.check @@ -0,0 +1,12 @@ +discard-advice-a.scala:7: warning: unused value of type scala.concurrent.Future[Int] + Future(42) + ^ +discard-advice-a.scala:10: warning: unused value of type scala.concurrent.Future[Int] + Future(42) + ^ +discard-advice-a.scala:11: warning: unused value of type Boolean(true) + true + ^ +error: No warnings can be incurred under -Werror. +3 warnings +1 error diff --git a/test/files/neg/discard-advice-a.scala b/test/files/neg/discard-advice-a.scala new file mode 100644 index 000000000000..4e825ee92178 --- /dev/null +++ b/test/files/neg/discard-advice-a.scala @@ -0,0 +1,13 @@ +//> using options -Werror -Wnonunit-statement -Wvalue-discard + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/discard-advice-b.check b/test/files/neg/discard-advice-b.check new file mode 100644 index 000000000000..dc786b099b61 --- /dev/null +++ b/test/files/neg/discard-advice-b.check @@ -0,0 +1,9 @@ +discard-advice-b.scala:7: warning: discarded non-Unit value of type scala.concurrent.Future[Int] + Future(42) + ^ +discard-advice-b.scala:11: warning: discarded non-Unit value of type Boolean(true) + true + ^ +error: No warnings can be incurred under -Werror. +2 warnings +1 error diff --git a/test/files/neg/discard-advice-b.scala b/test/files/neg/discard-advice-b.scala new file mode 100644 index 000000000000..3ff081cff8eb --- /dev/null +++ b/test/files/neg/discard-advice-b.scala @@ -0,0 +1,13 @@ +//> using options -Werror -Wvalue-discard + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/discard-advice-c.check b/test/files/neg/discard-advice-c.check new file mode 100644 index 000000000000..f05cf5a48fb5 --- /dev/null +++ b/test/files/neg/discard-advice-c.check @@ -0,0 +1,6 @@ +discard-advice-c.scala:11: warning: discarded pure expression does nothing + true + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/discard-advice-c.scala b/test/files/neg/discard-advice-c.scala new file mode 100644 index 000000000000..c5784e09a9c0 --- /dev/null +++ b/test/files/neg/discard-advice-c.scala @@ -0,0 +1,13 @@ +//> using options -Werror + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/discard-advice-d.check b/test/files/neg/discard-advice-d.check new file mode 100644 index 000000000000..652de3b28504 --- /dev/null +++ b/test/files/neg/discard-advice-d.check @@ -0,0 +1,15 @@ +discard-advice-d.scala:7: warning: unused value of type scala.concurrent.Future[Int] +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.f + Future(42) + ^ +discard-advice-d.scala:10: warning: unused value of type scala.concurrent.Future[Int] +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.g + Future(42) + ^ +discard-advice-d.scala:11: warning: unused value of type Boolean(true) +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.g + true + ^ +error: No warnings can be incurred under -Werror. +3 warnings +1 error diff --git a/test/files/neg/discard-advice-d.scala b/test/files/neg/discard-advice-d.scala new file mode 100644 index 000000000000..e685981bb6da --- /dev/null +++ b/test/files/neg/discard-advice-d.scala @@ -0,0 +1,13 @@ +//> using options -Wconf:any:warning-verbose -Werror -Wnonunit-statement -Wvalue-discard + +import concurrent._, ExecutionContext.Implicits._ + +class C { + def f(): Unit = { + Future(42) + } + def g(): Unit = { + Future(42) + true + } +} diff --git a/test/files/neg/dotless-targs-a.check b/test/files/neg/dotless-targs-a.check index 6fa4bd321423..087020309552 100644 --- a/test/files/neg/dotless-targs-a.check +++ b/test/files/neg/dotless-targs-a.check @@ -1,16 +1,16 @@ dotless-targs-a.scala:4: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def fn2 = List apply[Int] 2 - ^ + ^ dotless-targs-a.scala:9: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ dotless-targs-a.scala:9: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ 3 errors diff --git a/test/files/neg/dotless-targs-a.scala b/test/files/neg/dotless-targs-a.scala index d3095c69adfc..a1bfe41655cc 100644 --- a/test/files/neg/dotless-targs-a.scala +++ b/test/files/neg/dotless-targs-a.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Yrangepos:false +//> using options -Xsource:3 -Yrangepos:false class A { def fn1 = List apply 1 def fn2 = List apply[Int] 2 diff --git a/test/files/neg/dotless-targs-b.check b/test/files/neg/dotless-targs-b.check index ca61b350cbda..bcd970176bc8 100644 --- a/test/files/neg/dotless-targs-b.check +++ b/test/files/neg/dotless-targs-b.check @@ -1,16 +1,16 @@ dotless-targs-b.scala:4: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def fn2 = List apply[Int] 2 - ^ + ^ dotless-targs-b.scala:9: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ dotless-targs-b.scala:9: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ 3 errors diff --git a/test/files/neg/dotless-targs-b.scala b/test/files/neg/dotless-targs-b.scala index d54344238a9a..838d6cb49842 100644 --- a/test/files/neg/dotless-targs-b.scala +++ b/test/files/neg/dotless-targs-b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Xsource:3 -Yrangepos:false +//> using options -Werror -Xlint -Xsource:3 -Yrangepos:false class A { def fn1 = List apply 1 def fn2 = List apply[Int] 2 diff --git a/test/files/neg/dotless-targs-ranged-a.check b/test/files/neg/dotless-targs-ranged-a.check index 6620d7438e9d..2f4e7e9a1c22 100644 --- a/test/files/neg/dotless-targs-ranged-a.check +++ b/test/files/neg/dotless-targs-ranged-a.check @@ -1,24 +1,21 @@ dotless-targs-ranged-a.scala:4: warning: type application is not allowed for infix operators [quickfixable] def fn2 = List apply[Int] 2 - ^ + ^ dotless-targs-ranged-a.scala:9: warning: type application is not allowed for infix operators [quickfixable] def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ dotless-targs-ranged-a.scala:9: warning: type application is not allowed for infix operators [quickfixable] def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ dotless-targs-ranged-a.scala:13: warning: type application is not allowed for infix operators [quickfixable] def eval = 1 ->[Int] 2 - ^ + ^ dotless-targs-ranged-a.scala:14: warning: type application is not allowed for infix operators [quickfixable] def evil = new A() op [Int, String ] 42 - ^ -dotless-targs-ranged-a.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated - def h1 = List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) - ^ + ^ dotless-targs-ranged-a.scala:11: warning: type parameter A defined in method op shadows class A defined in package . You may want to rename your type parameter, or possibly remove it. def op[A, B](i: Int): Int = 2*i ^ error: No warnings can be incurred under -Werror. -7 warnings +6 warnings 1 error diff --git a/test/files/neg/dotless-targs-ranged-a.scala b/test/files/neg/dotless-targs-ranged-a.scala index 3b312d4e6ad0..f2416b0aa372 100644 --- a/test/files/neg/dotless-targs-ranged-a.scala +++ b/test/files/neg/dotless-targs-ranged-a.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Xmigration -Xsource:3 -Yrangepos:true +//> using options -Wconf:cat=scala3-migration:w -Werror -Xlint -Xsource:3 class A { def fn1 = List apply 1 def fn2 = List apply[Int] 2 diff --git a/test/files/neg/dotless-targs.check b/test/files/neg/dotless-targs.check index e85ded85bb4c..4cb371f3f331 100644 --- a/test/files/neg/dotless-targs.check +++ b/test/files/neg/dotless-targs.check @@ -1,4 +1,4 @@ dotless-targs.scala:4: error: type application is not allowed for postfix operators def f1 = "f1" isInstanceOf[String] // not ok - ^ + ^ 1 error diff --git a/test/files/neg/dotless-targs.scala b/test/files/neg/dotless-targs.scala index 70e01c9a00a4..e4b41535fb19 100644 --- a/test/files/neg/dotless-targs.scala +++ b/test/files/neg/dotless-targs.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -language:postfixOps +//> using options -Xsource:3 -language:postfixOps // class A { def f1 = "f1" isInstanceOf[String] // not ok diff --git a/test/files/neg/early-type-defs.scala b/test/files/neg/early-type-defs.scala index ba78f423acd9..8c425e9b5f24 100644 --- a/test/files/neg/early-type-defs.scala +++ b/test/files/neg/early-type-defs.scala @@ -1,4 +1,4 @@ // -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // object Test extends { type A1 = Int } with Runnable { def run() = () } diff --git a/test/files/neg/equiv-migration.scala b/test/files/neg/equiv-migration.scala index 8c740902f30f..19ed773a3245 100644 --- a/test/files/neg/equiv-migration.scala +++ b/test/files/neg/equiv-migration.scala @@ -1,4 +1,4 @@ -// scalac: -Xmigration -Werror +//> using options -Werror -Xmigration object Test { val f = Equiv[Float] val d = Equiv[Double] diff --git a/test/files/neg/exhausting.scala b/test/files/neg/exhausting.scala index 48d6cc6b4120..d595aab64b26 100644 --- a/test/files/neg/exhausting.scala +++ b/test/files/neg/exhausting.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { sealed abstract class Foo[T] diff --git a/test/files/neg/for-comprehension-old.scala b/test/files/neg/for-comprehension-old.scala index 0434d59adb29..adbb3babcc8b 100644 --- a/test/files/neg/for-comprehension-old.scala +++ b/test/files/neg/for-comprehension-old.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // class A { for (x <- 1 to 5 ; y = x) yield x+y // ok diff --git a/test/files/neg/for-comprehension-val.check b/test/files/neg/for-comprehension-val.check index 463efbba96f2..1e04d88b7958 100644 --- a/test/files/neg/for-comprehension-val.check +++ b/test/files/neg/for-comprehension-val.check @@ -11,22 +11,22 @@ for-comprehension-val.scala:12: error: `val` keyword in for comprehension is uns for (z <- 1 to 2 ; val x <- 1 to 5 ; val y = x) yield x+y // fail ^ for-comprehension-val.scala:5: error: `val` keyword in for comprehension is unsupported: instead, bind the value without `val` [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration for (x <- 1 to 5 ; val y = x) yield x+y // fail ^ for-comprehension-val.scala:7: error: `val` keyword in for comprehension is unsupported: instead, bind the value without `val` [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration for (val x <- 1 to 5 ; val y = x) yield x+y // fail ^ for-comprehension-val.scala:10: error: `val` keyword in for comprehension is unsupported: instead, bind the value without `val` [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration for (z <- 1 to 2 ; x <- 1 to 5 ; val y = x) yield x+y // fail ^ for-comprehension-val.scala:12: error: `val` keyword in for comprehension is unsupported: instead, bind the value without `val` [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration for (z <- 1 to 2 ; val x <- 1 to 5 ; val y = x) yield x+y // fail ^ diff --git a/test/files/neg/for-comprehension-val.scala b/test/files/neg/for-comprehension-val.scala index aaab52c2976c..875e9d09a9f6 100644 --- a/test/files/neg/for-comprehension-val.scala +++ b/test/files/neg/for-comprehension-val.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // class A { for (x <- 1 to 5 ; y = x) yield x+y // ok diff --git a/test/files/neg/forgot-interpolator.check b/test/files/neg/forgot-interpolator.check index 004bc35ddee9..dff7b631640f 100644 --- a/test/files/neg/forgot-interpolator.check +++ b/test/files/neg/forgot-interpolator.check @@ -1,4 +1,4 @@ -forgot-interpolator.scala:6: warning: possible missing interpolator: detected interpolated identifier `$bippy` +forgot-interpolator.scala:6: warning: possible missing interpolator: detected interpolated identifiers `$bippy`, `$bippy` def f = "Put the $bippy in the $bippy!" // warn 1 ^ forgot-interpolator.scala:16: warning: possible missing interpolator: detected an interpolated expression @@ -25,6 +25,48 @@ forgot-interpolator.scala:92: warning: possible missing interpolator: detected i forgot-interpolator.scala:126: warning: possible missing interpolator: detected an interpolated expression @deprecated("${myProperty}") ^ +forgot-interpolator.scala:144: warning: possible missing interpolator: detected interpolated identifier `$foo` + "An important $foo message!" // warn on ident in scope + ^ +forgot-interpolator.scala:148: warning: possible missing interpolator: detected an interpolated expression + "A doubly important ${foo * 2} message!" // warn on some expr, see below + ^ +forgot-interpolator.scala:151: warning: possible missing interpolator: detected interpolated identifier `$bar` + def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test + ^ +forgot-interpolator.scala:152: warning: possible missing interpolator: detected interpolated identifier `$bar` + def j = s"Try using '${ "something like $bar" }' instead." // warn + ^ +forgot-interpolator.scala:158: warning: possible missing interpolator: detected an interpolated expression + def v = "${baz}${bar}" // warn on second expr + ^ +forgot-interpolator.scala:159: warning: possible missing interpolator: detected an interpolated expression + def w = "${ op_* }" // warn, only cheap ident parsing + ^ +forgot-interpolator.scala:160: warning: possible missing interpolator: detected an interpolated expression + def x = "${ bar }" // warn, a cheap ident in scope + ^ +forgot-interpolator.scala:162: warning: possible missing interpolator: detected an interpolated expression + def z = "${ baz * 3}" // warn, no expr parsing + ^ +forgot-interpolator.scala:164: warning: possible missing interpolator: detected interpolated identifier `$this` + def thisly = "$this" + ^ +forgot-interpolator.scala:165: warning: possible missing interpolator: detected an interpolated expression + def exprly = "${this}" + ^ +forgot-interpolator.scala:170: warning: possible missing interpolator: detected interpolated identifier `$s` + val t = "$s" + ^ +forgot-interpolator.scala:171: warning: possible missing interpolator: detected an interpolated expression + val u = "a${s}b" + ^ +forgot-interpolator.scala:172: warning: possible missing interpolator: detected interpolated identifier `$s` + val v = "a$s b" + ^ +forgot-interpolator.scala:177: warning: possible missing interpolator: detected interpolated identifiers `$foo`, `$bar` + def s = "$foo$bar" + ^ error: No warnings can be incurred under -Werror. -9 warnings +23 warnings 1 error diff --git a/test/files/neg/forgot-interpolator.scala b/test/files/neg/forgot-interpolator.scala index 8b188e8c3d0b..2a7839092466 100644 --- a/test/files/neg/forgot-interpolator.scala +++ b/test/files/neg/forgot-interpolator.scala @@ -126,3 +126,53 @@ object t10456 { @deprecated("${myProperty}") var myProperty: String = _ } + +package pancake { } + +object Tester { + type NonVal = Int + + def ok = "Don't warn on $nosymbol interpolated." + + def pass = "Don't warn on $pancake package names." + + def types = "Or $NonVal type symbols either." + + def bar = "bar" + def f = { + val foo = "bar" + "An important $foo message!" // warn on ident in scope + } + def g = { + val foo = "bar" + "A doubly important ${foo * 2} message!" // warn on some expr, see below + } + def h = s"Try using '$$bar' instead." // no warn + def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test + def j = s"Try using '${ "something like $bar" }' instead." // warn + def k = f"Try using '$bar' instead." // no warn on other std interps + def p = "Template ${} {}" // no warn on unlikely or empty expressions + def q = "${}$bar" // disables subsequent checks! (a feature) + def r = "${}${bar}" // disables subsequent checks! (a feature) + + def v = "${baz}${bar}" // warn on second expr + def w = "${ op_* }" // warn, only cheap ident parsing + def x = "${ bar }" // warn, a cheap ident in scope + def y = "${ baz }" // no warn, cheap ident not in scope + def z = "${ baz * 3}" // warn, no expr parsing + + def thisly = "$this" + def exprly = "${this}" +} + +trait X { + val s = "hello" + val t = "$s" + val u = "a${s}b" + val v = "a$s b" +} + +trait DollarDollar { + val foo, bar = 42 + def s = "$foo$bar" +} diff --git a/test/files/neg/hk-existential-lb.scala b/test/files/neg/hk-existential-lb.scala index af4bc27c3341..df4ff906fb63 100644 --- a/test/files/neg/hk-existential-lb.scala +++ b/test/files/neg/hk-existential-lb.scala @@ -1,4 +1,4 @@ -// scalac: -language:higherKinds,existentials -Xfatal-warnings +//> using options -language:higherKinds,existentials -Xfatal-warnings // class Functor[F[_]] object Functor { diff --git a/test/files/neg/hk-typevar-unification.scala b/test/files/neg/hk-typevar-unification.scala index 9b44e40b1062..2cd9c93b2b43 100644 --- a/test/files/neg/hk-typevar-unification.scala +++ b/test/files/neg/hk-typevar-unification.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // class A class B diff --git a/test/files/neg/i15552.scala b/test/files/neg/i15552.scala index e9363222d038..95f608efcb52 100644 --- a/test/files/neg/i15552.scala +++ b/test/files/neg/i15552.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class C { val ctx: C = new C() def f() = g(42)(using ctx) // error: no g diff --git a/test/files/neg/i17266.check b/test/files/neg/i17266.check index 9fc496eafac7..cf40a08872d6 100644 --- a/test/files/neg/i17266.check +++ b/test/files/neg/i17266.check @@ -10,9 +10,18 @@ i17266.scala:32: warning: notify not selected from this instance i17266.scala:33: warning: notifyAll not selected from this instance def `maybe notifyAll`(): Unit = notifyAll() ^ +i17266.scala:53: warning: conversion int2Integer adds universal member method synchronized to class Int + 1.synchronized { // warn + ^ +i17266.scala:165: warning: conversion int2Integer adds universal member method wait to class Int + 1.wait() // not an error (should be?) + ^ +i17266.scala:183: warning: conversion int2Integer adds universal member method wait to class Int + 1.wait(10) // not an error (should be?) + ^ i17266.scala:53: warning: Suspicious `synchronized` call involving boxed primitive `Integer` 1.synchronized { // warn ^ error: No warnings can be incurred under -Werror. -5 warnings +8 warnings 1 error diff --git a/test/files/neg/i17266.scala b/test/files/neg/i17266.scala index 78566ef26ef2..411fa262c73a 100644 --- a/test/files/neg/i17266.scala +++ b/test/files/neg/i17266.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xsource:3 -Xlint:universal-methods +//> using options -Werror -Xsource:3 -Xlint:universal-methods // Dotty has top-level defs, so the reference is linted based on context. // For Scala 2, check result of looking up the identifier. diff --git a/test/files/neg/i17266c.scala b/test/files/neg/i17266c.scala index 3cff3e34b30a..1858c3427711 100644 --- a/test/files/neg/i17266c.scala +++ b/test/files/neg/i17266c.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:universal-methods +//> using options -Werror -Xlint:universal-methods object X diff --git a/test/files/neg/i20006.check b/test/files/neg/i20006.check new file mode 100644 index 000000000000..65ef7fe590ba --- /dev/null +++ b/test/files/neg/i20006.check @@ -0,0 +1,22 @@ +i20006.scala:8: error: method next is defined twice; + the conflicting value next was defined at line 6:7 + override def next(): T = { // error + ^ +i20006.scala:7: error: method hasNext is defined twice; + the conflicting value hasNext was defined at line 5:7 + override def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006.scala:47: error: x is already defined as value x + val x: String = "member" // error + ^ +i20006.scala:53: error: x is already defined as value x + private[this] var x: Int = 42 // error + ^ +i20006.scala:67: error: method x is defined twice; + the conflicting method x was defined at line 66:21 + def x(): Int = 42 // error + ^ +i20006.scala:77: error: x is already defined as variable x + def x(): Int = x // error + ^ +6 errors diff --git a/test/files/neg/i20006.scala b/test/files/neg/i20006.scala new file mode 100644 index 000000000000..542fad79063c --- /dev/null +++ b/test/files/neg/i20006.scala @@ -0,0 +1,79 @@ + +abstract class XIterateIterator[T](seed: T) extends collection.AbstractIterator[T] { + private var first = true + private var acc = seed + val hasNext: T => Boolean + val next: T => T + override def hasNext: Boolean = first || hasNext(acc) // error + override def next(): T = { // error + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +final class YIterateIterator[T](seed: T, hasNext: T => Boolean, next: T => T) extends collection.AbstractIterator[T] { + private var first = true + private var acc = seed + override def hasNext: Boolean = first || hasNext(acc) // error + override def next(): T = { // noerror + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +final class ZIterateIterator[T](seed: T, hasNext: T => Boolean, next: T => T) { + private var first = true + private var acc = seed + def hasNext: Boolean = first || hasNext(acc) // error + def next(): T = { // noerror + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +class C(x: String) { + val x: String = "member" // error +} +class D(x: String) { + private var x: Int = 42 // error +} +class E(x: String) { + private[this] var x: Int = 42 // error +} +class F(x: String) { + def x(): Int = 42 // noerror +} +class G(x: String) { + def x(i: Int): Int = i +} +class H { + private[this] val x: String = "" + def x(): Int = 42 // noerror +} +class I { + private[this] def x: String = "" + def x(): Int = 42 // error +} +class PrivateConflict { + private[this] var x = 42 + def x(): Int = x + def x_=(n: Int) = x = n +} +class LocalConflict { + def f(): Unit = { + var x = 42 + def x(): Int = x // error + } +} diff --git a/test/files/neg/i20006b.check b/test/files/neg/i20006b.check new file mode 100644 index 000000000000..9b8efd0ea951 --- /dev/null +++ b/test/files/neg/i20006b.check @@ -0,0 +1,62 @@ +i20006b.scala:9: error: method next is defined twice; + the conflicting value next was defined at line 7:7 + override def next(): T = { // error + ^ +i20006b.scala:8: error: method hasNext is defined twice; + the conflicting value hasNext was defined at line 6:7 + override def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006b.scala:48: error: x is already defined as value x + val x: String = "member" // error + ^ +i20006b.scala:54: error: x is already defined as value x + private[this] var x: Int = 42 // error + ^ +i20006b.scala:68: error: method x is defined twice; + the conflicting method x was defined at line 67:21 + def x(): Int = 42 // error + ^ +i20006b.scala:78: error: x is already defined as variable x + def x(): Int = x // error + ^ +i20006b.scala:23: error: Double definition will be detected in Scala 3; the conflicting value next is defined at 19:65 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=YIterateIterator + override def next(): T = { // werror + ^ +i20006b.scala:22: error: Double definition will be detected in Scala 3; the conflicting value hasNext is defined at 19:42 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=YIterateIterator + override def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006b.scala:37: error: Double definition will be detected in Scala 3; the conflicting value next is defined at 33:65 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=ZIterateIterator + def next(): T = { // werror + ^ +i20006b.scala:36: error: Double definition will be detected in Scala 3; the conflicting value hasNext is defined at 33:42 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=ZIterateIterator + def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006b.scala:51: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 50:9 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D + private var x: Int = 42 // error + ^ +i20006b.scala:57: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 56:9 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=F + def x(): Int = 42 // werror + ^ +i20006b.scala:64: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 63:21 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=H + def x(): Int = 42 // werror + ^ +i20006b.scala:72: error: Double definition will be detected in Scala 3; the conflicting variable x is defined at 71:21 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=PrivateConflict + def x(): Int = x // werror + ^ +14 errors diff --git a/test/files/neg/i20006b.scala b/test/files/neg/i20006b.scala new file mode 100644 index 000000000000..ea04906accd4 --- /dev/null +++ b/test/files/neg/i20006b.scala @@ -0,0 +1,158 @@ +//> using options -Werror -Xsource:3 + +abstract class XIterateIterator[T](seed: T) extends collection.AbstractIterator[T] { + private var first = true + private var acc = seed + val hasNext: T => Boolean + val next: T => T + override def hasNext: Boolean = first || hasNext(acc) // error + override def next(): T = { // error + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +final class YIterateIterator[T](seed: T, hasNext: T => Boolean, next: T => T) extends collection.AbstractIterator[T] { + private var first = true + private var acc = seed + override def hasNext: Boolean = first || hasNext(acc) // error + override def next(): T = { // werror + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +final class ZIterateIterator[T](seed: T, hasNext: T => Boolean, next: T => T) { + private var first = true + private var acc = seed + def hasNext: Boolean = first || hasNext(acc) // error + def next(): T = { // werror + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +class C(x: String) { + val x: String = "member" // error +} +class D(x: String) { + private var x: Int = 42 // error +} +class E(x: String) { + private[this] var x: Int = 42 // error +} +class F(x: String) { + def x(): Int = 42 // werror +} +class G(x: String) { + def x(i: Int): Int = i +} +class H { + private[this] val x: String = "" + def x(): Int = 42 // werror +} +class I { + private[this] def x: String = "" + def x(): Int = 42 // error +} +class PrivateConflict { + private[this] var x = 42 + def x(): Int = x // werror + def x_=(n: Int) = x = n +} +class LocalConflict { + def f(): Unit = { + var x = 42 + def x(): Int = x // error + } +} + +/* +-- [E120] Naming Error: test/files/neg/i20006.scala:8:15 --------------------------------------------------------------- +8 | override def hasNext: Boolean = first || hasNext(acc) + | ^ + | Double definition: + | val hasNext: T => Boolean in class XIterateIterator at line 6 and + | override def hasNext: Boolean in class XIterateIterator at line 8 +-- [E120] Naming Error: test/files/neg/i20006.scala:9:15 --------------------------------------------------------------- +9 | override def next(): T = { + | ^ + | Double definition: + | val next: T => T in class XIterateIterator at line 7 and + | override def next(): T in class XIterateIterator at line 9 +-- [E120] Naming Error: test/files/neg/i20006.scala:22:15 -------------------------------------------------------------- +22 | override def hasNext: Boolean = first || hasNext(acc) + | ^ + | Double definition: + | private[this] val hasNext: T => Boolean in class YIterateIterator at line 19 and + | override def hasNext: Boolean in class YIterateIterator at line 22 +-- [E120] Naming Error: test/files/neg/i20006.scala:23:15 -------------------------------------------------------------- +23 | override def next(): T = { + | ^ + | Double definition: + | private[this] val next: T => T in class YIterateIterator at line 19 and + | override def next(): T in class YIterateIterator at line 23 +-- [E120] Naming Error: test/files/neg/i20006.scala:36:6 --------------------------------------------------------------- +36 | def hasNext: Boolean = first || hasNext(acc) + | ^ + | Double definition: + | private[this] val hasNext: T => Boolean in class ZIterateIterator at line 33 and + | def hasNext: Boolean in class ZIterateIterator at line 36 +-- [E120] Naming Error: test/files/neg/i20006.scala:37:6 --------------------------------------------------------------- +37 | def next(): T = { + | ^ + | Double definition: + | private[this] val next: T => T in class ZIterateIterator at line 33 and + | def next(): T in class ZIterateIterator at line 37 +-- [E120] Naming Error: test/files/neg/i20006.scala:48:6 --------------------------------------------------------------- +48 | val x: String = "member" // error + | ^ + | Double definition: + | private[this] val x: String in class C at line 47 and + | val x: String in class C at line 48 +-- [E120] Naming Error: test/files/neg/i20006.scala:51:14 -------------------------------------------------------------- +51 | private var x: Int = 42 // error + | ^ + | Double definition: + | private[this] val x: String in class D at line 50 and + | private[this] var x: Int in class D at line 51 +-- [E120] Naming Error: test/files/neg/i20006.scala:54:20 -------------------------------------------------------------- +54 | private[this] var x: Int = 42 // error + | ^ + | Double definition: + | private[this] val x: String in class E at line 53 and + | private[this] var x: Int in class E at line 54 +-- [E120] Naming Error: test/files/neg/i20006.scala:57:6 --------------------------------------------------------------- +57 | def x(): Int = 42 // error + | ^ + | Double definition: + | private[this] val x: String in class F at line 56 and + | def x(): Int in class F at line 57 +-- [E120] Naming Error: test/files/neg/i20006.scala:65:6 --------------------------------------------------------------- +65 | def x(): Int = 42 + | ^ + | Double definition: + | val x: String in class H at line 63 and + | def x(): Int in class H at line 65 +-- Warning: test/files/neg/i20006.scala:54:16 -------------------------------------------------------------------------- +54 | private[this] var x: Int = 42 // error + | ^ + | Ignoring [this] qualifier. + | This syntax will be deprecated in the future; it should be dropped. + | See: https://docs.scala-lang.org/scala3/reference/dropped-features/this-qualifier.html + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. +1 warning found +11 errors found +*/ diff --git a/test/files/neg/i20006c.check b/test/files/neg/i20006c.check new file mode 100644 index 000000000000..6c46c554da6b --- /dev/null +++ b/test/files/neg/i20006c.check @@ -0,0 +1,54 @@ +i20006c.scala:9: error: method next is defined twice; + the conflicting value next was defined at line 7:7 + override def next(): T = { // error + ^ +i20006c.scala:8: error: method hasNext is defined twice; + the conflicting value hasNext was defined at line 6:7 + override def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006c.scala:23: error: method next is defined twice; + the conflicting value next was defined at line 19:65 + override def next(): T = { // error + ^ +i20006c.scala:22: error: method hasNext is defined twice; + the conflicting value hasNext was defined at line 19:42 + override def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006c.scala:37: error: method next is defined twice; + the conflicting value next was defined at line 33:65 + def next(): T = { // error + ^ +i20006c.scala:36: error: method hasNext is defined twice; + the conflicting value hasNext was defined at line 33:42 + def hasNext: Boolean = first || hasNext(acc) // error + ^ +i20006c.scala:48: error: x is already defined as value x + val x: String = "member" // error + ^ +i20006c.scala:51: error: variable x is defined twice; + the conflicting value x was defined at line 50:9 + private var x: Int = 42 // error + ^ +i20006c.scala:54: error: x is already defined as value x + private[this] var x: Int = 42 // error + ^ +i20006c.scala:57: error: method x is defined twice; + the conflicting value x was defined at line 56:9 + def x(): Int = 42 // error + ^ +i20006c.scala:64: error: method x is defined twice; + the conflicting value x was defined at line 63:21 + def x(): Int = 42 // error + ^ +i20006c.scala:68: error: method x is defined twice; + the conflicting method x was defined at line 67:21 + def x(): Int = 42 // error + ^ +i20006c.scala:72: error: method x is defined twice; + the conflicting variable x was defined at line 71:21 + def x(): Int = x // error + ^ +i20006c.scala:78: error: x is already defined as variable x + def x(): Int = x // error + ^ +14 errors diff --git a/test/files/neg/i20006c.scala b/test/files/neg/i20006c.scala new file mode 100644 index 000000000000..90cf99e96869 --- /dev/null +++ b/test/files/neg/i20006c.scala @@ -0,0 +1,80 @@ +//> using options -Werror -Xsource:3 -Xsource-features:double-definitions + +abstract class XIterateIterator[T](seed: T) extends collection.AbstractIterator[T] { + private var first = true + private var acc = seed + val hasNext: T => Boolean + val next: T => T + override def hasNext: Boolean = first || hasNext(acc) // error + override def next(): T = { // error + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +final class YIterateIterator[T](seed: T, hasNext: T => Boolean, next: T => T) extends collection.AbstractIterator[T] { + private var first = true + private var acc = seed + override def hasNext: Boolean = first || hasNext(acc) // error + override def next(): T = { // error + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +final class ZIterateIterator[T](seed: T, hasNext: T => Boolean, next: T => T) { + private var first = true + private var acc = seed + def hasNext: Boolean = first || hasNext(acc) // error + def next(): T = { // error + if (first) { + first = false + } else { + acc = next(acc) + } + acc + } +} + +class C(x: String) { + val x: String = "member" // error +} +class D(x: String) { + private var x: Int = 42 // error +} +class E(x: String) { + private[this] var x: Int = 42 // error +} +class F(x: String) { + def x(): Int = 42 // error +} +class G(x: String) { + def x(i: Int): Int = i +} +class H { + private[this] val x: String = "" + def x(): Int = 42 // error +} +class I { + private[this] def x: String = "" + def x(): Int = 42 // error +} +class PrivateConflict { + private[this] var x = 42 + def x(): Int = x // error + def x_=(n: Int) = x = n +} +class LocalConflict { + def f(): Unit = { + var x = 42 + def x(): Int = x // error + } +} diff --git a/test/files/neg/i20006d.check b/test/files/neg/i20006d.check new file mode 100644 index 000000000000..12f91280798c --- /dev/null +++ b/test/files/neg/i20006d.check @@ -0,0 +1,62 @@ +i20006d.scala:12: error: method x is defined twice; + the conflicting value x was defined at line 11:22 + def x: Int = 4 // err + ^ +i20006d.scala:17: error: method x is defined twice; + the conflicting value x was defined at line 16:28 + def x: Int = 4 // err + ^ +i20006d.scala:22: error: method x is defined twice; + the conflicting value x was defined at line 21:24 + def x: Int = 4 // err + ^ +i20006d.scala:27: error: method x is defined twice; + the conflicting value x was defined at line 26:30 + def x: Int = 4 // err + ^ +i20006d.scala:32: error: method x is defined twice; + the conflicting value x was defined at line 31:14 + def x: Int = 4 // err + ^ +i20006d.scala:44: error: method x is defined twice; + the conflicting value x was defined at line 43:22 + def x(): Int = 4 // err + ^ +i20006d.scala:49: error: method x is defined twice; + the conflicting value x was defined at line 48:28 + def x(): Int = 4 // err + ^ +i20006d.scala:54: error: method x is defined twice; + the conflicting value x was defined at line 53:24 + def x(): Int = 4 // err + ^ +i20006d.scala:59: error: method x is defined twice; + the conflicting value x was defined at line 58:30 + def x(): Int = 4 // err + ^ +i20006d.scala:64: error: method x is defined twice; + the conflicting value x was defined at line 63:14 + def x(): Int = 4 // err + ^ +i20006d.scala:68: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006d.scala:72: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006d.scala:76: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006d.scala:81: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006d.scala:86: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006d.scala:91: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006d.scala:96: error: x is already defined as value x + val x: Int = 4 // err + ^ +17 errors diff --git a/test/files/neg/i20006d.scala b/test/files/neg/i20006d.scala new file mode 100644 index 000000000000..9d75adfceb3d --- /dev/null +++ b/test/files/neg/i20006d.scala @@ -0,0 +1,97 @@ +//> using options -Werror + +class C1(x: String) { + def x: Int = 4 // ok in Scala 2 +} + +class C2(private[this] val x: String) { + def x: Int = 4 // ok in Scala 2 +} + +class C3(private val x: String) { + def x: Int = 4 // err +} + +object o4 { + class C4(private[o4] val x: String) { + def x: Int = 4 // err + } +} + +class C5(protected val x: String) { + def x: Int = 4 // err +} + +object o6 { + class C6(protected[o6] val x: String) { + def x: Int = 4 // err + } +} + +class C7(val x: String) { + def x: Int = 4 // err +} + +class D1(x: String) { + def x(): Int = 4 // ok +} + +class D2(private[this] val x: String) { + def x(): Int = 4 // ok +} + +class D3(private val x: String) { + def x(): Int = 4 // err +} + +object p4 { + class D4(private[p4] val x: String) { + def x(): Int = 4 // err + } +} + +class D5(protected val x: String) { + def x(): Int = 4 // err +} + +object p6 { + class D6(protected[p6] val x: String) { + def x(): Int = 4 // err + } +} + +class D7(val x: String) { + def x(): Int = 4 // err +} + +class E1(x: String) { + val x: Int = 4 // err +} + +class E2(private[this] val x: String) { + val x: Int = 4 // err +} + +class E3(private val x: String) { + val x: Int = 4 // err +} + +object q4 { + class E4(private[q4] val x: String) { + val x: Int = 4 // err + } +} + +class E5(protected val x: String) { + val x: Int = 4 // err +} + +object q6 { + class E6(protected[q6] val x: String) { + val x: Int = 4 // err + } +} + +class E7(val x: String) { + val x: Int = 4 // err +} diff --git a/test/files/neg/i20006e.check b/test/files/neg/i20006e.check new file mode 100644 index 000000000000..db8c0a149848 --- /dev/null +++ b/test/files/neg/i20006e.check @@ -0,0 +1,82 @@ +i20006e.scala:12: error: method x is defined twice; + the conflicting value x was defined at line 11:22 + def x: Int = 4 // err + ^ +i20006e.scala:17: error: method x is defined twice; + the conflicting value x was defined at line 16:28 + def x: Int = 4 // err + ^ +i20006e.scala:22: error: method x is defined twice; + the conflicting value x was defined at line 21:24 + def x: Int = 4 // err + ^ +i20006e.scala:27: error: method x is defined twice; + the conflicting value x was defined at line 26:30 + def x: Int = 4 // err + ^ +i20006e.scala:32: error: method x is defined twice; + the conflicting value x was defined at line 31:14 + def x: Int = 4 // err + ^ +i20006e.scala:44: error: method x is defined twice; + the conflicting value x was defined at line 43:22 + def x(): Int = 4 // err + ^ +i20006e.scala:49: error: method x is defined twice; + the conflicting value x was defined at line 48:28 + def x(): Int = 4 // err + ^ +i20006e.scala:54: error: method x is defined twice; + the conflicting value x was defined at line 53:24 + def x(): Int = 4 // err + ^ +i20006e.scala:59: error: method x is defined twice; + the conflicting value x was defined at line 58:30 + def x(): Int = 4 // err + ^ +i20006e.scala:64: error: method x is defined twice; + the conflicting value x was defined at line 63:14 + def x(): Int = 4 // err + ^ +i20006e.scala:68: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:72: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:76: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:81: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:86: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:91: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:96: error: x is already defined as value x + val x: Int = 4 // err + ^ +i20006e.scala:4: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 3:10 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C1 + def x: Int = 4 // warn in Xsource:3 + ^ +i20006e.scala:8: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 7:28 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C2 + def x: Int = 4 // warn in Xsource:3 + ^ +i20006e.scala:36: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 35:10 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D1 + def x(): Int = 4 // warn in Xsource:3 + ^ +i20006e.scala:40: error: Double definition will be detected in Scala 3; the conflicting value x is defined at 39:28 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D2 + def x(): Int = 4 // warn in Xsource:3 + ^ +21 errors diff --git a/test/files/neg/i20006e.scala b/test/files/neg/i20006e.scala new file mode 100644 index 000000000000..58d8d230903e --- /dev/null +++ b/test/files/neg/i20006e.scala @@ -0,0 +1,97 @@ +//> using options -Werror -Xsource:3 + +class C1(x: String) { + def x: Int = 4 // warn in Xsource:3 +} + +class C2(private[this] val x: String) { + def x: Int = 4 // warn in Xsource:3 +} + +class C3(private val x: String) { + def x: Int = 4 // err +} + +object o4 { + class C4(private[o4] val x: String) { + def x: Int = 4 // err + } +} + +class C5(protected val x: String) { + def x: Int = 4 // err +} + +object o6 { + class C6(protected[o6] val x: String) { + def x: Int = 4 // err + } +} + +class C7(val x: String) { + def x: Int = 4 // err +} + +class D1(x: String) { + def x(): Int = 4 // warn in Xsource:3 +} + +class D2(private[this] val x: String) { + def x(): Int = 4 // warn in Xsource:3 +} + +class D3(private val x: String) { + def x(): Int = 4 // err +} + +object p4 { + class D4(private[p4] val x: String) { + def x(): Int = 4 // err + } +} + +class D5(protected val x: String) { + def x(): Int = 4 // err +} + +object p6 { + class D6(protected[p6] val x: String) { + def x(): Int = 4 // err + } +} + +class D7(val x: String) { + def x(): Int = 4 // err +} + +class E1(x: String) { + val x: Int = 4 // err +} + +class E2(private[this] val x: String) { + val x: Int = 4 // err +} + +class E3(private val x: String) { + val x: Int = 4 // err +} + +object q4 { + class E4(private[q4] val x: String) { + val x: Int = 4 // err + } +} + +class E5(protected val x: String) { + val x: Int = 4 // err +} + +object q6 { + class E6(protected[q6] val x: String) { + val x: Int = 4 // err + } +} + +class E7(val x: String) { + val x: Int = 4 // err +} diff --git a/test/files/neg/i20026.check b/test/files/neg/i20026.check new file mode 100644 index 000000000000..1686b9040973 --- /dev/null +++ b/test/files/neg/i20026.check @@ -0,0 +1,4 @@ +JTest.java:3: error: illegal start of type declaration +import java.util.*; + ^ +1 error diff --git a/test/files/neg/i20026/JTest.java b/test/files/neg/i20026/JTest.java new file mode 100644 index 000000000000..c0f9ffa1a881 --- /dev/null +++ b/test/files/neg/i20026/JTest.java @@ -0,0 +1,6 @@ + +@Deprecated +import java.util.*; + +public class JTest { +} diff --git a/test/files/neg/i20026/p.java b/test/files/neg/i20026/p.java new file mode 100644 index 000000000000..a6fc2f1597d3 --- /dev/null +++ b/test/files/neg/i20026/p.java @@ -0,0 +1,2 @@ +@Deprecated +package p; diff --git a/test/files/neg/i20026/test.scala b/test/files/neg/i20026/test.scala new file mode 100644 index 000000000000..792e10c36d61 --- /dev/null +++ b/test/files/neg/i20026/test.scala @@ -0,0 +1,6 @@ + +object Test extends App { + println { + new JTest + } +} diff --git a/test/files/neg/implicit-ambiguous-invalid.scala b/test/files/neg/implicit-ambiguous-invalid.scala index 465cd9163d98..ca6003e34496 100644 --- a/test/files/neg/implicit-ambiguous-invalid.scala +++ b/test/files/neg/implicit-ambiguous-invalid.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:implicit-not-found -Xfatal-warnings +//> using options -Xlint:implicit-not-found -Xfatal-warnings // object Test { trait =!=[C, D] diff --git a/test/files/neg/implicit-any2stringadd-migration.check b/test/files/neg/implicit-any2stringadd-migration.check new file mode 100644 index 000000000000..700a916ed5a7 --- /dev/null +++ b/test/files/neg/implicit-any2stringadd-migration.check @@ -0,0 +1,6 @@ +implicit-any2stringadd-migration.scala:4: error: Converting to String for concatenation is not supported in Scala 3 (or with -Xsource-features:any2stringadd). +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=scala.Predef.any2stringadd + true + "what" + ^ +1 error diff --git a/test/files/neg/implicit-any2stringadd-migration.scala b/test/files/neg/implicit-any2stringadd-migration.scala new file mode 100644 index 000000000000..bbf2ee1c6525 --- /dev/null +++ b/test/files/neg/implicit-any2stringadd-migration.scala @@ -0,0 +1,5 @@ +//> using options -Xsource:3 + +object Test { + true + "what" +} diff --git a/test/files/neg/implicit-any2stringadd-warning.scala b/test/files/neg/implicit-any2stringadd-warning.scala index 66b1135812a6..4c928fd775f3 100644 --- a/test/files/neg/implicit-any2stringadd-warning.scala +++ b/test/files/neg/implicit-any2stringadd-warning.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings -deprecation -// +//> using options -Werror -deprecation + object Test { true + "what" } diff --git a/test/files/neg/implicit-any2stringadd.scala b/test/files/neg/implicit-any2stringadd.scala index 0692d9a7b9cb..bfcdc5832c90 100644 --- a/test/files/neg/implicit-any2stringadd.scala +++ b/test/files/neg/implicit-any2stringadd.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3-cross -Vimplicits -// +//> using options -Xsource:3 -Xsource-features:any2stringadd + object Test { true + "what" } diff --git a/test/files/neg/implicit-shadow.scala b/test/files/neg/implicit-shadow.scala index 33725ece13f1..dffa838221f4 100644 --- a/test/files/neg/implicit-shadow.scala +++ b/test/files/neg/implicit-shadow.scala @@ -1,4 +1,4 @@ -// scalac: -Vimplicits +//> using options -Vimplicits // object Test { import B._, C._ diff --git a/test/files/neg/implicitly-self.scala b/test/files/neg/implicitly-self.scala index 8515f1235d23..becd16ccb311 100644 --- a/test/files/neg/implicitly-self.scala +++ b/test/files/neg/implicitly-self.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:implicit-recursion +//> using options -Werror -Xlint:implicit-recursion // trait TC[A] { def ix: Int } diff --git a/test/files/neg/import-future.check b/test/files/neg/import-future.check index 000601f45b7d..daaaa678b635 100644 --- a/test/files/neg/import-future.check +++ b/test/files/neg/import-future.check @@ -1,4 +1,13 @@ import-future.scala:15: error: not found: value unrelated unrelated(1) // error ^ -1 error +import-future.scala:40: error: not found: value f + def g = f[Int] // error no f, was given is not a member + ^ +import-future.scala:44: error: could not find implicit value for parameter t: T[Int] + def g = f[Int] // implicit unavailable + ^ +import-future.scala:48: error: could not find implicit value for parameter t: T[Int] + def g = f[Int] // implicit unavailable + ^ +4 errors diff --git a/test/files/neg/import-future.scala b/test/files/neg/import-future.scala index 288fd3d0e240..4f88cf64c3e4 100644 --- a/test/files/neg/import-future.scala +++ b/test/files/neg/import-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // class D { @@ -25,3 +25,25 @@ object Test { *(1) } } + +trait T[A] { + def t: A +} +object TX { + implicit def tInt: T[Int] = new T[Int] { + def t: Int = 42 + } + def f[A](implicit t: T[A]): A = t.t +} +object X { + import TX.given + def g = f[Int] // error no f, was given is not a member +} +object Y { + import TX.{f, tInt as _, given} + def g = f[Int] // implicit unavailable +} +object Z { + import TX.{tInt as _, *} + def g = f[Int] // implicit unavailable +} diff --git a/test/files/neg/import-syntax.scala b/test/files/neg/import-syntax.scala index 0e3deb00cce0..00caf0aecd7b 100644 --- a/test/files/neg/import-syntax.scala +++ b/test/files/neg/import-syntax.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 class D { def *(y: Int): Int = y diff --git a/test/files/neg/inferred-structural-3.check b/test/files/neg/inferred-structural-3.check new file mode 100644 index 000000000000..f297042016d3 --- /dev/null +++ b/test/files/neg/inferred-structural-3.check @@ -0,0 +1,18 @@ +inferred-structural-3.scala:8: error: in Scala 3 (or with -Xsource-features:no-infer-structural), method a will no longer have a structural type: Option[AnyRef{def g: Int}] + members that can be accessed with a reflective call: def g: Int +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C.a + def a = Option(new { def g = 1 }) // warn + ^ +inferred-structural-3.scala:16: error: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to AnyRef instead of A [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C.g + def g = new A { def f = this } // warn -- inferred type of `f` is `A`, since we're not using -Xsource-features:infer-override + ^ +inferred-structural-3.scala:19: error: in Scala 3 (or with -Xsource-features:no-infer-structural), method i will no longer have a structural type: AnyRef{val x: Int} + members that can be accessed with a reflective call: val x: Int +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C.i + def i = new AnyRef { val x = 2 } // warn + ^ +3 errors diff --git a/test/files/neg/inferred-structural-3.scala b/test/files/neg/inferred-structural-3.scala new file mode 100644 index 000000000000..dc4c09325b79 --- /dev/null +++ b/test/files/neg/inferred-structural-3.scala @@ -0,0 +1,20 @@ +//> using options -Xsource:3 -Werror + +trait A { + def f: AnyRef +} + +class C { + def a = Option(new { def g = 1 }) // warn + def b: Option[{ def g: Int }] = Option(new { def g = 1 }) // ok + + def c(p: { def i: Int }): Int = 0 // ok + def d = new A { def f: A = this } // ok + + def e = new A { def f: AnyRef = new AnyRef } // ok + def f = new A { def f = new AnyRef } // ok + def g = new A { def f = this } // warn -- inferred type of `f` is `A`, since we're not using -Xsource-features:infer-override + + def h = new AnyRef { type T = String } // ok + def i = new AnyRef { val x = 2 } // warn +} diff --git a/test/files/neg/infix-named-arg.check b/test/files/neg/infix-named-arg.check new file mode 100644 index 000000000000..add5420ab385 --- /dev/null +++ b/test/files/neg/infix-named-arg.check @@ -0,0 +1,6 @@ +infix-named-arg.scala:5: warning: named argument is deprecated for infix syntax + def f = 42 + (x = 1) + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/infix-named-arg.scala b/test/files/neg/infix-named-arg.scala new file mode 100644 index 000000000000..b22b05613bb5 --- /dev/null +++ b/test/files/neg/infix-named-arg.scala @@ -0,0 +1,8 @@ + +//> using options -Werror -Xlint -Xsource:3 + +class C { + def f = 42 + (x = 1) + def multi(x: Int, y: Int): Int = x + y + def g = new C() `multi` (x = 42, y = 27) +} diff --git a/test/files/neg/infixed.scala b/test/files/neg/infixed.scala index 01a6cd950978..1b8422e1792d 100644 --- a/test/files/neg/infixed.scala +++ b/test/files/neg/infixed.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 class K { def x(y: Int) = 0 } diff --git a/test/files/neg/inlineIndyLambdaPrivate/Test_2.scala b/test/files/neg/inlineIndyLambdaPrivate/Test_2.scala index 71d75a45e47a..87648689f116 100644 --- a/test/files/neg/inlineIndyLambdaPrivate/Test_2.scala +++ b/test/files/neg/inlineIndyLambdaPrivate/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Yopt-inline-heuristics:everything -Wopt:_ -Werror +//> using options -opt:inline:** -Yopt-inline-heuristics:everything -Wopt:_ -Werror class Test { def foo = A_1.test } diff --git a/test/files/neg/iterable-ordering.scala b/test/files/neg/iterable-ordering.scala index 9ef34b1cdb75..ae25b1dd4522 100644 --- a/test/files/neg/iterable-ordering.scala +++ b/test/files/neg/iterable-ordering.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation -Werror +//> using options -Xlint:deprecation -Werror object Test { val o = Ordering[Iterable[Int]] } diff --git a/test/files/neg/lint-inferred-structural.check b/test/files/neg/lint-inferred-structural.check new file mode 100644 index 000000000000..7141e1ee6464 --- /dev/null +++ b/test/files/neg/lint-inferred-structural.check @@ -0,0 +1,12 @@ +lint-inferred-structural.scala:8: warning: method a has an inferred structural type: Option[AnyRef{def g: Int}] + members that can be accessed with a reflective call: def g: Int + def a = Option(new { def g = 1 }) // warn + ^ +lint-inferred-structural.scala:19: warning: method i has an inferred structural type: AnyRef{val x: Int} + members that can be accessed with a reflective call: val x: Int + def i = new AnyRef { val x = 2 } // warn + ^ +warning: 1 feature warning; re-run with -feature for details +error: No warnings can be incurred under -Werror. +3 warnings +1 error diff --git a/test/files/neg/lint-inferred-structural.scala b/test/files/neg/lint-inferred-structural.scala new file mode 100644 index 000000000000..f3b17d7030d9 --- /dev/null +++ b/test/files/neg/lint-inferred-structural.scala @@ -0,0 +1,20 @@ +//> using options -Xlint -Werror + +trait A { + def f: AnyRef +} + +class C { + def a = Option(new { def g = 1 }) // warn + def b: Option[{ def g: Int }] = Option(new { def g = 1 }) // ok + + def c(p: { def i: Int }): Int = 0 // ok + def d = new A { def f: A = this } // ok + + def e = new A { def f: AnyRef = new AnyRef } // ok + def f = new A { def f = new AnyRef } // ok + def g = new A { def f = this } // ok + + def h = new AnyRef { type T = String } // ok + def i = new AnyRef { val x = 2 } // warn +} diff --git a/test/files/neg/lint-int-div-to-float.scala b/test/files/neg/lint-int-div-to-float.scala index 4f66c481384e..927c82853f90 100644 --- a/test/files/neg/lint-int-div-to-float.scala +++ b/test/files/neg/lint-int-div-to-float.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Xfatal-warnings +//> using options -Xlint -Xfatal-warnings class C { def f = 1 diff --git a/test/files/neg/literals.scala b/test/files/neg/literals.scala index 9557d26bdc51..f7e9e3d2bf42 100644 --- a/test/files/neg/literals.scala +++ b/test/files/neg/literals.scala @@ -1,4 +1,4 @@ -// scalac: -Woctal-literal -Werror -deprecation +//> using options -Woctal-literal -Werror -deprecation trait RejectedLiterals { def missingHex: Int = { 0x } // line 4: was: not reported, taken as zero diff --git a/test/files/neg/locally-x.scala b/test/files/neg/locally-x.scala index 4a6c7560058d..58435659b2df 100644 --- a/test/files/neg/locally-x.scala +++ b/test/files/neg/locally-x.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // // an innocent gotcha // diff --git a/test/files/neg/logImplicits.scala b/test/files/neg/logImplicits.scala index 2d94fcbd3b6e..72df36b90a17 100644 --- a/test/files/neg/logImplicits.scala +++ b/test/files/neg/logImplicits.scala @@ -1,4 +1,4 @@ -// scalac: -Xlog-implicit-conversions +//> using options -Xlog-implicit-conversions // class A { def f(xs: Array[Byte]) = xs.size diff --git a/test/files/neg/macro-annot-not-expanded/Macros_1.scala b/test/files/neg/macro-annot-not-expanded/Macros_1.scala index fdb63874cdd7..08c24880d5ad 100644 --- a/test/files/neg/macro-annot-not-expanded/Macros_1.scala +++ b/test/files/neg/macro-annot-not-expanded/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations +//> using options -Ymacro-annotations import scala.language.experimental.macros import scala.reflect.macros.blackbox import scala.annotation.StaticAnnotation diff --git a/test/files/neg/macro-annot-unused-param/Macros_1.scala b/test/files/neg/macro-annot-unused-param/Macros_1.scala index 17d602216c23..3ab8d0bc820c 100644 --- a/test/files/neg/macro-annot-unused-param/Macros_1.scala +++ b/test/files/neg/macro-annot-unused-param/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations +//> using options -Ymacro-annotations import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context import scala.annotation.StaticAnnotation diff --git a/test/files/neg/macro-annot-unused-param/Test_2.scala b/test/files/neg/macro-annot-unused-param/Test_2.scala index 6ac2d3f50eeb..f43e1122a8a0 100644 --- a/test/files/neg/macro-annot-unused-param/Test_2.scala +++ b/test/files/neg/macro-annot-unused-param/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations -Wunused:params -Wmacros:after -Werror +//> using options -Ymacro-annotations -Wunused:params -Wmacros:after -Werror @mymacro class X diff --git a/test/files/neg/macro-deprecate-idents.scala b/test/files/neg/macro-deprecate-idents.scala index 7c0e9e762a13..be21c06893db 100644 --- a/test/files/neg/macro-deprecate-idents.scala +++ b/test/files/neg/macro-deprecate-idents.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object Test1 { val macro = ??? diff --git a/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.scala b/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.scala index 5b24ff5c7b11..c3e2b9255ab0 100644 --- a/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.scala +++ b/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. +//> using options -Xplugin:. import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala b/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala index 5b24ff5c7b11..c3e2b9255ab0 100644 --- a/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala +++ b/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. +//> using options -Xplugin:. import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala b/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala index c1ff232f98b8..e9f7953e3881 100644 --- a/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala +++ b/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala @@ -1,4 +1,4 @@ -// scalac: -Vmacro-lite +//> using options -Vmacro-lite object Test extends App { Macros.foo Macros.foo diff --git a/test/files/neg/macro-invalidret/Macros_Test_2.scala b/test/files/neg/macro-invalidret/Macros_Test_2.scala index c1851acc0206..102d112fb58c 100644 --- a/test/files/neg/macro-invalidret/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidret/Macros_Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation -Werror +//> using options -Xlint:deprecation -Werror import language.experimental.macros object Macros { diff --git a/test/files/neg/macro-invalidshape.check b/test/files/neg/macro-invalidshape.check index e05b6a092665..8f639225d5d7 100644 --- a/test/files/neg/macro-invalidshape.check +++ b/test/files/neg/macro-invalidshape.check @@ -8,7 +8,7 @@ macro [].[[]] or macro [].[[]] def foo2(x: Any) = macro Impls.foo(null)(null) ^ -Macros_Test_2.scala:5: error: missing argument list for method foo in object Impls +Macros_Test_2.scala:5: error: missing argument list for method foo in object Impls of type (c: scala.reflect.macros.blackbox.Context)(x: c.Expr[Any]): Nothing Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `foo _` or `foo(_)(_)` instead of `foo`. def foo3(x: Any) = macro {2; Impls.foo} diff --git a/test/files/neg/main1.scala b/test/files/neg/main1.scala index 295920808350..a07b51e0d03b 100644 --- a/test/files/neg/main1.scala +++ b/test/files/neg/main1.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // negatives package foo1 { diff --git a/test/files/neg/main2.scala b/test/files/neg/main2.scala index 3ec0c607ef65..2b3bb7a0a12f 100644 --- a/test/files/neg/main2.scala +++ b/test/files/neg/main2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xmain-class p.X +//> using options -Xfatal-warnings -Xmain-class p.X // // emit a warning diff --git a/test/files/neg/maxerrs.scala b/test/files/neg/maxerrs.scala index ad24a1cac4ba..f72577f5a319 100644 --- a/test/files/neg/maxerrs.scala +++ b/test/files/neg/maxerrs.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxerrs 3 -Xfatal-warnings -deprecation +//> using options -Xmaxerrs 3 -Xfatal-warnings -deprecation // object X { diff --git a/test/files/neg/maxwarns.scala b/test/files/neg/maxwarns.scala index 8b8d21329a03..a5523a9af8d4 100644 --- a/test/files/neg/maxwarns.scala +++ b/test/files/neg/maxwarns.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 3 -Xfatal-warnings -deprecation +//> using options -Xmaxwarns 3 -Xfatal-warnings -deprecation // object X { diff --git a/test/files/neg/missing-arg-list.check b/test/files/neg/missing-arg-list.check index 180896059538..902acecab736 100644 --- a/test/files/neg/missing-arg-list.check +++ b/test/files/neg/missing-arg-list.check @@ -1,24 +1,24 @@ -missing-arg-list.scala:9: error: missing argument list for method id in trait T +missing-arg-list.scala:9: error: missing argument list for method id in trait T of type (i: Int): Int Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `id _` or `id(_)` instead of `id`. val w = id ^ -missing-arg-list.scala:10: error: missing argument list for method f in trait T +missing-arg-list.scala:10: error: missing argument list for method f in trait T of type (i: Int)(j: Int): Int Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `f _` or `f(_)(_)` instead of `f`. val x = f ^ -missing-arg-list.scala:11: error: missing argument list for method g in trait T +missing-arg-list.scala:11: error: missing argument list for method g in trait T of type (i: Int, j: Int, k: Int): Int Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `g _` or `g(_,_,_)` instead of `g`. val y = g ^ -missing-arg-list.scala:12: error: missing argument list for method h in trait T +missing-arg-list.scala:12: error: missing argument list for method h in trait T of type (i: Int, j: Int, k: Int)(implicit s: String): String Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `h _` or `h(_,_,_)(_)` instead of `h`. val z = h ^ -missing-arg-list.scala:15: error: missing argument list for method + in trait T +missing-arg-list.scala:15: error: missing argument list for method + in trait T of type (i: Int): Int Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `+ _` or `+(_)` instead of `+`. val p = + diff --git a/test/files/neg/missing-param-type-tuple.check b/test/files/neg/missing-param-type-tuple.check index 270bcc6de057..a38bcb7cca21 100644 --- a/test/files/neg/missing-param-type-tuple.check +++ b/test/files/neg/missing-param-type-tuple.check @@ -6,6 +6,11 @@ Note: The expected type requires a one-argument function accepting a 2-Tuple. missing-param-type-tuple.scala:3: error: missing parameter type val x: ((Int, Int)) => Int = (a, b) => 0 ^ +missing-param-type-tuple.scala:3: error: type mismatch; + found : (?, ?) => ? + required: ((Int, Int)) => Int + val x: ((Int, Int)) => Int = (a, b) => 0 + ^ missing-param-type-tuple.scala:5: error: missing parameter type Note: The expected type requires a one-argument function accepting a 3-Tuple. Consider a pattern matching anonymous function, `{ case (param1, ..., param3) => ... }` @@ -17,6 +22,11 @@ missing-param-type-tuple.scala:5: error: missing parameter type missing-param-type-tuple.scala:5: error: missing parameter type val y: ((Int, Int, Int)) => Int = (a, b, !!) => 0 ^ +missing-param-type-tuple.scala:5: error: type mismatch; + found : (?, ?, ?) => ? + required: ((Int, Int, Int)) => Int + val y: ((Int, Int, Int)) => Int = (a, b, !!) => 0 + ^ missing-param-type-tuple.scala:7: error: missing parameter type Note: The expected type requires a one-argument function accepting a 3-Tuple. Consider a pattern matching anonymous function, `{ case (param1, ..., param3) => ... }` @@ -28,4 +38,9 @@ missing-param-type-tuple.scala:7: error: missing parameter type missing-param-type-tuple.scala:7: error: missing parameter type val z: ((Int, Int, Int)) => Int = (a, NotAVariablePatternName, c) => 0 ^ -8 errors +missing-param-type-tuple.scala:7: error: type mismatch; + found : (?, ?, ?) => ? + required: ((Int, Int, Int)) => Int + val z: ((Int, Int, Int)) => Int = (a, NotAVariablePatternName, c) => 0 + ^ +11 errors diff --git a/test/files/neg/multi-array.scala b/test/files/neg/multi-array.scala index ce50a0f4a1c3..82fb938d511d 100644 --- a/test/files/neg/multi-array.scala +++ b/test/files/neg/multi-array.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // /** Multi-dimensional array creation with `new` was removed in 2.10. * The replacement Array.ofDim[Int](10,10) makes the original mistake diff --git a/test/files/neg/multiLineOps-b.scala b/test/files/neg/multiLineOps-b.scala index 00763244086c..1f2a397d3326 100644 --- a/test/files/neg/multiLineOps-b.scala +++ b/test/files/neg/multiLineOps-b.scala @@ -1,4 +1,4 @@ -//> using options -Werror -Xsource:3-cross +//> using options -Werror -Xsource:3 -Xsource-features:leading-infix class Test { val b1 = { diff --git a/test/files/neg/multiLineOps-c.scala b/test/files/neg/multiLineOps-c.scala index af3f255cc04e..924f4c3ceec0 100644 --- a/test/files/neg/multiLineOps-c.scala +++ b/test/files/neg/multiLineOps-c.scala @@ -1,4 +1,4 @@ -//> using options -Werror -Xsource:3-cross +//> using options -Werror -Xsource:3 -Xsource-features:leading-infix class Test { val x = 42 diff --git a/test/files/neg/multiLineOps.scala b/test/files/neg/multiLineOps.scala index 1d8e9164014e..9d9ded40c09d 100644 --- a/test/files/neg/multiLineOps.scala +++ b/test/files/neg/multiLineOps.scala @@ -1,4 +1,4 @@ -//> using options -Werror -Xlint -Xsource:3-cross +//> using options -Werror -Xlint -Xsource:3 -Xsource-features:leading-infix class Test { val x = 1 diff --git a/test/files/neg/named-booleans-relaxed.check b/test/files/neg/named-booleans-relaxed.check new file mode 100644 index 000000000000..8e0235fc026e --- /dev/null +++ b/test/files/neg/named-booleans-relaxed.check @@ -0,0 +1,54 @@ +named-booleans-relaxed.scala:22: warning: Boolean literals should be passed using named argument syntax for parameter x. [quickfixable] + val x0 = c.f(17, true, false) // warn + ^ +named-booleans-relaxed.scala:22: warning: Boolean literals should be passed using named argument syntax for parameter y. [quickfixable] + val x0 = c.f(17, true, false) // warn + ^ +named-booleans-relaxed.scala:44: warning: Boolean literals should be passed using named argument syntax for parameter cond. [quickfixable] + c.uncheck(false, "OK", true) + ^ +named-booleans-relaxed.scala:44: warning: Boolean literals should be passed using named argument syntax for parameter flag. [quickfixable] + c.uncheck(false, "OK", true) + ^ +named-booleans-relaxed.scala:63: warning: Boolean literals should be passed using named argument syntax for parameter isKlazz. [quickfixable] + def test = Klazz(true, false) // warn case class apply as for ctor + ^ +named-booleans-relaxed.scala:63: warning: Boolean literals should be passed using named argument syntax for parameter isWarnable. [quickfixable] + def test = Klazz(true, false) // warn case class apply as for ctor + ^ +named-booleans-relaxed.scala:71: warning: Boolean literals should be passed using named argument syntax for parameter up. [quickfixable] + def g3 = f(42, false) // warn, unnamed could mean either param with default + ^ +named-booleans-relaxed.scala:72: warning: Boolean literals should be passed using named argument syntax for parameter up. [quickfixable] + def g4 = f(42, false, true) // warn, swappable + ^ +named-booleans-relaxed.scala:72: warning: Boolean literals should be passed using named argument syntax for parameter down. [quickfixable] + def g4 = f(42, false, true) // warn, swappable + ^ +named-booleans-relaxed.scala:79: warning: Boolean literals should be passed using named argument syntax for parameter up. [quickfixable] + def rev3 = rev(42, reverse=true, false) // warn, unnamed could mean either param with default + ^ +named-booleans-relaxed.scala:80: warning: Boolean literals should be passed using named argument syntax for parameter reverse. [quickfixable] + def rev4 = rev(42, false, true, false) // warn, swappable + ^ +named-booleans-relaxed.scala:80: warning: Boolean literals should be passed using named argument syntax for parameter up. [quickfixable] + def rev4 = rev(42, false, true, false) // warn, swappable + ^ +named-booleans-relaxed.scala:80: warning: Boolean literals should be passed using named argument syntax for parameter down. [quickfixable] + def rev4 = rev(42, false, true, false) // warn, swappable + ^ +named-booleans-relaxed.scala:81: warning: Boolean literals should be passed using named argument syntax for parameter reverse. [quickfixable] + def rev5 = rev(42, true, down=true) // warn, out of order so it's a named block, otherwise same as rev3 + ^ +named-booleans-relaxed.scala:92: warning: Boolean literals should be passed using named argument syntax for parameter insideIf. [quickfixable] + def sus(s: String) = p.needsParentheses(s)(false) // warn + ^ +named-booleans-relaxed.scala:95: warning: Boolean literals should be passed using named argument syntax for parameter x. [quickfixable] + def f = p.f(true, z=42) // warn + ^ +named-booleans-relaxed.scala:106: warning: Boolean literals should be passed using named argument syntax for parameter y. [quickfixable] + def w = new V(true).combo(false) + ^ +error: No warnings can be incurred under -Werror. +17 warnings +1 error diff --git a/test/files/neg/named-booleans-relaxed.scala b/test/files/neg/named-booleans-relaxed.scala new file mode 100644 index 000000000000..e4b5121a4219 --- /dev/null +++ b/test/files/neg/named-booleans-relaxed.scala @@ -0,0 +1,107 @@ +//> using options -Werror -Wunnamed-boolean-literal + +class C { + def f(n: Int = 42, x: Boolean, y: Boolean) = if (x && y) n else 0 + + def g(x: Any) = + x match { + case (true, false) => 0 + case _ => 1 + } + var b = false + def fs(n: Int)(s: String, b: Boolean) = if (b) s*n else s + def gs[A](n: Int)(s: A, b: Boolean) = if (b) s.toString*n else s.toString + + def check(cond: Boolean, msg: => String) = if (cond) println(msg) + def uncheck(cond: Boolean, msg: => String, flag: Boolean) = if (cond && flag) println(msg) +} + +object Test extends App { + val c = new C + val b = false + val x0 = c.f(17, true, false) // warn + val x1 = c.f(17, true, b) // nowarn + val x2 = c.f(y = b, n = 17, x = true) // nowarn + c.b = true + val y = Some(false) + val z = Option(false) + val w = (true, false) + val v = c g true // nowarn infix + + val s = collection.mutable.Set.empty[String] + def mutateS(): Unit = s("updater") = true + //def updateS(): Unit = s.update("updater", true) + + val m = collection.mutable.Map.empty[String, true] + def mutateM(): Unit = m("updater") = true + + val ss = c.fs(42)("hello", true) + val tt = c.gs(42)("hello", true) + + def f(g: Boolean => Option[Boolean]) = g(true).getOrElse(false) + + c.check(true, "OK") + c.uncheck(false, "OK", true) +} + +class Arrays { + def test = Array(true, false, true) +} + +class Tuples { + def test = (true, false, true) +} + +class Functions { + val f: Boolean => Boolean = identity + def test = f(true) +} + +case class Klazz(isKlazz: Boolean, isWarnable: Boolean) + +class Klazzy { + def test = Klazz(true, false) // warn case class apply as for ctor +} + +class Defaulting { + def f(n: Int, up: Boolean = true, down: Boolean = false) = if (up) n+1 else if (down) n-1 else n + def g0 = f(42) // nowarn, all defaults + def g1 = f(42, up=false) // nowarn, named or defaults + def g2 = f(42, up=false, true) // nowarn, in param order so not a named block, unnamed is last remaining param + def g3 = f(42, false) // warn, unnamed could mean either param with default + def g4 = f(42, false, true) // warn, swappable + + def rev(n: Int, reverse: Boolean = false, up: Boolean = true, down: Boolean = false) = + if (!reverse) f(n, up, down) else if (down) n+1 else if (up) n-1 else n + def rev0 = rev(42) // nowarn, all defaults + def rev1 = rev(42, up=false) // nowarn, named or defaults + def rev2 = rev(42, true, up=false, down=true) // nowarn, in param order so not a named block, unnamed is last remaining param + def rev3 = rev(42, reverse=true, false) // warn, unnamed could mean either param with default + def rev4 = rev(42, false, true, false) // warn, swappable + def rev5 = rev(42, true, down=true) // warn, out of order so it's a named block, otherwise same as rev3 +} + +class Printers { + def needsParentheses(parent: String)(insideIf: Boolean = true, insideMatch: Boolean = true, insideTry: Boolean = true, insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true, insideAssign: Boolean = true): Boolean = true + + def f(x: Boolean, y: String = "hi", z: Int = 2, b: Boolean = false) = if (x && b) y+z else y*z +} +object TestPrinters { + val p = new Printers + def ok(s: String) = p.needsParentheses(s)(insideLabelDef = false) + def sus(s: String) = p.needsParentheses(s)(false) // warn + def pick(s: String) = p.needsParentheses(s)(true, insideAssign=false, insideLabelDef=false, insideBlock=false, insideAnnotated=false, insideTry=false, insideMatch=false) + + def f = p.f(true, z=42) // warn + def g = p.f(x=true, b=true) // nowarn, no unnamed + def h = p.f(true, b=true) // nowarn, one unnamed but other boolean is named; defaults are non-boolean +} + +object Testy { + class V(val x: Boolean) extends AnyVal { + def combo(y: Boolean = true, z: Boolean = false) = x&&y&&z + } + + def v = new V(true) + def w = new V(true).combo(false) +} diff --git a/test/files/neg/named-booleans.check b/test/files/neg/named-booleans.check index ed9391411803..ad1ab31a7888 100644 --- a/test/files/neg/named-booleans.check +++ b/test/files/neg/named-booleans.check @@ -1,21 +1,30 @@ -named-booleans.scala:22: warning: Boolean literals should be passed using named argument syntax for parameter x. +named-booleans.scala:22: warning: Boolean literals should be passed using named argument syntax for parameter x. [quickfixable] val x0 = c.f(17, true, b) // warn ^ -named-booleans.scala:38: warning: Boolean literals should be passed using named argument syntax for parameter b. +named-booleans.scala:38: warning: Boolean literals should be passed using named argument syntax for parameter b. [quickfixable] val ss = c.fs(42)("hello", true) ^ -named-booleans.scala:39: warning: Boolean literals should be passed using named argument syntax for parameter b. +named-booleans.scala:39: warning: Boolean literals should be passed using named argument syntax for parameter b. [quickfixable] val tt = c.gs(42)("hello", true) ^ -named-booleans.scala:44: warning: Boolean literals should be passed using named argument syntax for parameter cond. +named-booleans.scala:44: warning: Boolean literals should be passed using named argument syntax for parameter cond. [quickfixable] c.uncheck(false, "OK", true) ^ -named-booleans.scala:44: warning: Boolean literals should be passed using named argument syntax for parameter flag. +named-booleans.scala:44: warning: Boolean literals should be passed using named argument syntax for parameter flag. [quickfixable] c.uncheck(false, "OK", true) ^ -named-booleans.scala:63: warning: Boolean literals should be passed using named argument syntax for parameter isKlazz. - def test = Klazz(true) // warn case class apply as for ctor - ^ +named-booleans.scala:70: warning: Boolean literals should be passed using named argument syntax for parameter down. [quickfixable] + def g2 = f(42, up=false, true) + ^ +named-booleans.scala:71: warning: Boolean literals should be passed using named argument syntax for parameter up. [quickfixable] + def g3 = f(42, false) + ^ +named-booleans.scala:72: warning: Boolean literals should be passed using named argument syntax for parameter up. [quickfixable] + def g4 = f(42, false, true) + ^ +named-booleans.scala:72: warning: Boolean literals should be passed using named argument syntax for parameter down. [quickfixable] + def g4 = f(42, false, true) + ^ error: No warnings can be incurred under -Werror. -6 warnings +9 warnings 1 error diff --git a/test/files/neg/named-booleans.scala b/test/files/neg/named-booleans.scala index e1ca8c9a10fd..a9ceaf575b21 100644 --- a/test/files/neg/named-booleans.scala +++ b/test/files/neg/named-booleans.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:named-booleans +//> using options -Werror -Wunnamed-boolean-literal-strict class C { def f(n: Int = 42, x: Boolean, y: Boolean) = if (x && y) n else 0 @@ -60,5 +60,14 @@ class Functions { case class Klazz(isKlazz: Boolean) class Klazzy { - def test = Klazz(true) // warn case class apply as for ctor + def test = Klazz(true) // nowarn case class apply as for ctor +} + +class Defaulting { + def f(n: Int, up: Boolean = true, down: Boolean = false) = if (up) n+1 else if (down) n-1 else n + def g0 = f(42) + def g1 = f(42, up=false) + def g2 = f(42, up=false, true) + def g3 = f(42, false) + def g4 = f(42, false, true) } diff --git a/test/files/neg/names-defaults-neg-213.scala b/test/files/neg/names-defaults-neg-213.scala index d40d6b9071bf..8e5c212f1d61 100644 --- a/test/files/neg/names-defaults-neg-213.scala +++ b/test/files/neg/names-defaults-neg-213.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // class C { def f1(x: Unit): Int = 0 diff --git a/test/files/neg/names-defaults-neg-pu.check b/test/files/neg/names-defaults-neg-pu.check index b4b5d13b1e46..89bbe121d4b5 100644 --- a/test/files/neg/names-defaults-neg-pu.check +++ b/test/files/neg/names-defaults-neg-pu.check @@ -118,6 +118,11 @@ names-defaults-neg-pu.scala:104: error: unknown parameter name: m names-defaults-neg-pu.scala:140: error: missing parameter type for expanded function (() => a = x$1) val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ +names-defaults-neg-pu.scala:140: error: type mismatch; + found : ? => ? + required: Int + val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) + ^ names-defaults-neg-pu.scala:140: error: not found: value get val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ @@ -127,6 +132,11 @@ names-defaults-neg-pu.scala:141: error: parameter 'a' is already specified at pa names-defaults-neg-pu.scala:142: error: missing parameter type for expanded function (() => b = x$4) val taf4: (Int, String) => Unit = testAnnFun(_, b = _) ^ +names-defaults-neg-pu.scala:142: error: type mismatch; + found : ? => ? + required: String + val taf4: (Int, String) => Unit = testAnnFun(_, b = _) + ^ names-defaults-neg-pu.scala:193: error: an expression of type Null is ineligible for implicit conversion Error occurred in an application involving default arguments. def f = new A3[Int]() @@ -141,4 +151,4 @@ names-defaults-neg-pu.scala:100: warning: naming parameter deprNam5Arg is deprec deprNam5(deprNam5Arg = null) ^ 3 warnings -34 errors +36 errors diff --git a/test/files/neg/names-defaults-neg-pu.scala b/test/files/neg/names-defaults-neg-pu.scala index e381e1119e11..1656b8b40691 100644 --- a/test/files/neg/names-defaults-neg-pu.scala +++ b/test/files/neg/names-defaults-neg-pu.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // object Test extends App { // TESTS diff --git a/test/files/neg/names-defaults-neg-warn.scala b/test/files/neg/names-defaults-neg-warn.scala index 3ecd909eaa2f..611ef6d65916 100644 --- a/test/files/neg/names-defaults-neg-warn.scala +++ b/test/files/neg/names-defaults-neg-warn.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object Test extends App { object deprNam2 { diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index af887de0aeeb..13c3ade0fc41 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -118,6 +118,11 @@ names-defaults-neg.scala:110: error: unknown parameter name: m names-defaults-neg.scala:146: error: missing parameter type for expanded function (() => a = x$1) val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ +names-defaults-neg.scala:146: error: type mismatch; + found : ? => ? + required: Int + val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) + ^ names-defaults-neg.scala:146: error: not found: value get val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ @@ -127,6 +132,11 @@ names-defaults-neg.scala:147: error: parameter 'a' is already specified at param names-defaults-neg.scala:148: error: missing parameter type for expanded function (() => b = x$4) val taf4: (Int, String) => Unit = testAnnFun(_, b = _) ^ +names-defaults-neg.scala:148: error: type mismatch; + found : ? => ? + required: String + val taf4: (Int, String) => Unit = testAnnFun(_, b = _) + ^ names-defaults-neg.scala:103: warning: symbol literal is deprecated; use Symbol("foo") instead [quickfixable] def deprNam6(@deprecatedName('foo) deprNam6Arg: String) = 0 ^ @@ -149,4 +159,4 @@ names-defaults-neg.scala:106: warning: the parameter name bar is deprecated (sin deprNam7(bar = null) ^ 7 warnings -33 errors +35 errors diff --git a/test/files/neg/names-defaults-neg.scala b/test/files/neg/names-defaults-neg.scala index c738aaa7de0d..fe76f5e41e8e 100644 --- a/test/files/neg/names-defaults-neg.scala +++ b/test/files/neg/names-defaults-neg.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // object Test extends App { // TESTS diff --git a/test/files/neg/nested-class-shadowing-removal.check b/test/files/neg/nested-class-shadowing-removal.check index b7f86d1987f6..95f4e66b2516 100644 --- a/test/files/neg/nested-class-shadowing-removal.check +++ b/test/files/neg/nested-class-shadowing-removal.check @@ -1,5 +1,5 @@ nested-class-shadowing-removal.scala:9: error: shadowing a nested class of a parent is deprecated but class Status shadows class Status defined in trait Core; rename the class to something else -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Ext.Status class Status extends super.Status ^ diff --git a/test/files/neg/nested-class-shadowing-removal.scala b/test/files/neg/nested-class-shadowing-removal.scala index 7b84845dfc1f..a691d3aed9da 100644 --- a/test/files/neg/nested-class-shadowing-removal.scala +++ b/test/files/neg/nested-class-shadowing-removal.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // trait Core { diff --git a/test/files/neg/nested-class-shadowing.scala b/test/files/neg/nested-class-shadowing.scala index d9ac447a4079..c50d695503b9 100644 --- a/test/files/neg/nested-class-shadowing.scala +++ b/test/files/neg/nested-class-shadowing.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // trait Core { diff --git a/test/files/neg/newpat_unreachable.scala b/test/files/neg/newpat_unreachable.scala index ccaf5ab5a825..8d6b0221675f 100644 --- a/test/files/neg/newpat_unreachable.scala +++ b/test/files/neg/newpat_unreachable.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { class A { diff --git a/test/files/neg/no-predef.scala b/test/files/neg/no-predef.scala index c4a1a120bad3..64f55028d46a 100644 --- a/test/files/neg/no-predef.scala +++ b/test/files/neg/no-predef.scala @@ -1,4 +1,4 @@ -// scalac: -Yno-predef +//> using options -Yno-predef // class NoPredef { def f1 = 5L: java.lang.Long diff --git a/test/files/neg/nonlocal-warning.scala b/test/files/neg/nonlocal-warning.scala index bfc731a65271..8fcf2e1c4709 100644 --- a/test/files/neg/nonlocal-warning.scala +++ b/test/files/neg/nonlocal-warning.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class Foo { def foo(l: List[Int]): Int = { diff --git a/test/files/neg/nonsense_eq_refine.check b/test/files/neg/nonsense_eq_refine.check deleted file mode 100644 index fb29ba09120a..000000000000 --- a/test/files/neg/nonsense_eq_refine.check +++ /dev/null @@ -1,9 +0,0 @@ -nonsense_eq_refine.scala:7: warning: E and String are unrelated: they will most likely never compare equal - if (e == "") ??? // warn about comparing unrelated types - ^ -nonsense_eq_refine.scala:10: warning: SE and String are unrelated: they will most likely never compare equal - if (se == "") ??? // types are still unrelated - ^ -error: No warnings can be incurred under -Werror. -2 warnings -1 error diff --git a/test/files/neg/nonsense_eq_refine.scala b/test/files/neg/nonsense_eq_refine.scala deleted file mode 100644 index c14776e9c1fa..000000000000 --- a/test/files/neg/nonsense_eq_refine.scala +++ /dev/null @@ -1,11 +0,0 @@ -// scalac: -Werror -class E -class SE extends Serializable - -object Test { - val e = new E - if (e == "") ??? // warn about comparing unrelated types - - val se = new SE - if (se == "") ??? // types are still unrelated -} diff --git a/test/files/neg/nonunit-if.check b/test/files/neg/nonunit-if.check index d1ffb1337ef3..25039baffb26 100644 --- a/test/files/neg/nonunit-if.check +++ b/test/files/neg/nonunit-if.check @@ -1,57 +1,51 @@ -nonunit-if.scala:58: warning: discarded non-Unit value of type U - if (!isEmpty) f(a) // warn, check is on - ^ -nonunit-if.scala:62: warning: discarded non-Unit value of type Boolean - f(a) // warn, check is on - ^ -nonunit-if.scala:13: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-if.scala:13: warning: unused value of type scala.concurrent.Future[Int] improved // warn ^ -nonunit-if.scala:20: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-if.scala:20: warning: unused value of type String new E().toString // warn ^ -nonunit-if.scala:26: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-if.scala:26: warning: unused value of type scala.concurrent.Future[Int] Future(42) // warn ^ -nonunit-if.scala:30: warning: unused value of type K (add `: Unit` to discard silently) +nonunit-if.scala:30: warning: unused value of type K copy() // warn ^ -nonunit-if.scala:37: warning: unused value of type List[Int] (add `: Unit` to discard silently) +nonunit-if.scala:37: warning: unused value of type List[Int] 27 +: xs // warn ^ nonunit-if.scala:44: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses null // warn for purity ^ -nonunit-if.scala:58: warning: unused value of type U (add `: Unit` to discard silently) +nonunit-if.scala:58: warning: unused value of type U if (!isEmpty) f(a) // warn, check is on ^ -nonunit-if.scala:62: warning: unused value of type Boolean (add `: Unit` to discard silently) +nonunit-if.scala:62: warning: unused value of type Boolean f(a) // warn, check is on ^ -nonunit-if.scala:73: warning: unused value of type U (add `: Unit` to discard silently) +nonunit-if.scala:73: warning: unused value of type U if (!fellback) action(z) // warn, check is on ^ -nonunit-if.scala:81: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:81: warning: unused value of type Int g // warn, check is on ^ -nonunit-if.scala:79: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:79: warning: unused value of type Int g // warn block statement ^ -nonunit-if.scala:86: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:86: warning: unused value of type Int g // warn ^ -nonunit-if.scala:84: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:84: warning: unused value of type Int g // warn ^ -nonunit-if.scala:96: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-if.scala:96: warning: unused value of type Int if (b) { // warn, at least one branch looks interesting ^ -nonunit-if.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] (add `: Unit` to discard silently) +nonunit-if.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] set += a // warn because cannot know whether the `set` was supposed to be consumed or assigned ^ -nonunit-if.scala:146: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-if.scala:146: warning: unused value of type String while (it.hasNext) it.next() // warn ^ error: No warnings can be incurred under -Werror. -18 warnings +16 warnings 1 error diff --git a/test/files/neg/nonunit-if.scala b/test/files/neg/nonunit-if.scala index 17aee82cc15c..8d79ef2a5fca 100644 --- a/test/files/neg/nonunit-if.scala +++ b/test/files/neg/nonunit-if.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wnonunit-statement -Wnonunit-if:true -Wvalue-discard +//> using options -Werror -Wnonunit-statement -Wnonunit-if:true -Wvalue-discard // debug: -Vprint:refchecks -Yprint-trees:format import collection.ArrayOps import collection.mutable.{ArrayBuilder, LinkedHashSet, ListBuffer} diff --git a/test/files/neg/nonunit-statement.check b/test/files/neg/nonunit-statement.check index b15ae34fb7fd..2a5f1ae9c21d 100644 --- a/test/files/neg/nonunit-statement.check +++ b/test/files/neg/nonunit-statement.check @@ -1,39 +1,42 @@ -nonunit-statement.scala:13: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-statement.scala:13: warning: unused value of type scala.concurrent.Future[Int] improved // warn ^ -nonunit-statement.scala:20: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-statement.scala:20: warning: unused value of type String new E().toString // warn ^ -nonunit-statement.scala:26: warning: unused value of type scala.concurrent.Future[Int] (add `: Unit` to discard silently) +nonunit-statement.scala:26: warning: unused value of type scala.concurrent.Future[Int] Future(42) // warn ^ -nonunit-statement.scala:30: warning: unused value of type K (add `: Unit` to discard silently) +nonunit-statement.scala:30: warning: unused value of type K copy() // warn ^ -nonunit-statement.scala:37: warning: unused value of type List[Int] (add `: Unit` to discard silently) +nonunit-statement.scala:37: warning: unused value of type List[Int] 27 +: xs // warn ^ nonunit-statement.scala:44: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses null // warn for purity ^ -nonunit-statement.scala:79: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:79: warning: unused value of type Int g // warn block statement ^ -nonunit-statement.scala:86: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:86: warning: unused value of type Int g // warn ^ -nonunit-statement.scala:84: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:84: warning: unused value of type Int g // warn ^ -nonunit-statement.scala:96: warning: unused value of type Int (add `: Unit` to discard silently) +nonunit-statement.scala:96: warning: unused value of type Int if (b) { // warn, at least one branch looks interesting ^ -nonunit-statement.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] (add `: Unit` to discard silently) +nonunit-statement.scala:116: warning: unused value of type scala.collection.mutable.LinkedHashSet[A] set += a // warn because cannot know whether the `set` was supposed to be consumed or assigned ^ -nonunit-statement.scala:146: warning: unused value of type String (add `: Unit` to discard silently) +nonunit-statement.scala:146: warning: unused value of type String while (it.hasNext) it.next() // warn ^ +nonunit-statement.scala:202: warning: a pure expression does nothing in statement position + null // warn for purity, but does not cause multiline clause + ^ error: No warnings can be incurred under -Werror. -12 warnings +13 warnings 1 error diff --git a/test/files/neg/nonunit-statement.scala b/test/files/neg/nonunit-statement.scala index 192091dbd034..b411249e5084 100644 --- a/test/files/neg/nonunit-statement.scala +++ b/test/files/neg/nonunit-statement.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wnonunit-statement -Wnonunit-if:false -Wvalue-discard +//> using options -Werror -Wnonunit-statement -Wnonunit-if:false -Wvalue-discard // debug: -Vprint:refchecks -Yprint-trees:format import collection.ArrayOps import collection.mutable.{ArrayBuilder, LinkedHashSet, ListBuffer} @@ -197,3 +197,7 @@ class Depends { () } } +// some uninteresting expressions may warn for other reasons +class NotMultiline { + null // warn for purity, but does not cause multiline clause +} diff --git a/test/files/neg/not-found.check b/test/files/neg/not-found.check index da64a6cfe1fe..8a84f05f022b 100644 --- a/test/files/neg/not-found.check +++ b/test/files/neg/not-found.check @@ -23,8 +23,4 @@ not-found.scala:21: error: not found: value X Identifiers that begin with uppercase are not pattern variables but match the value in scope. val X :: Nil = List(42) ^ -not-found.scala:21: warning: Pattern definition introduces Unit-valued member of T; consider wrapping it in `locally { ... }`. - val X :: Nil = List(42) - ^ -1 warning 7 errors diff --git a/test/files/neg/nowarn-lint.check b/test/files/neg/nowarn-lint.check index cdec97aa5b0e..284d93ad0b6c 100644 --- a/test/files/neg/nowarn-lint.check +++ b/test/files/neg/nowarn-lint.check @@ -7,7 +7,7 @@ class C[@specialized(Unit) A](a: A) nowarn-lint.scala:7: warning: Class parameter is specialized for type Unit. Consider using `@specialized(Specializable.Arg)` instead. class D[@specialized(Specializable.Primitives) A](a: A) ^ -nowarn-lint.scala:41: warning: @nowarn annotation does not suppress any warnings +nowarn-lint.scala:35: warning: @nowarn annotation does not suppress any warnings @nowarn("any") ^ error: No warnings can be incurred under -Werror. diff --git a/test/files/neg/nowarn-lint.scala b/test/files/neg/nowarn-lint.scala index 576993f68ac2..5fdc2bf327f8 100644 --- a/test/files/neg/nowarn-lint.scala +++ b/test/files/neg/nowarn-lint.scala @@ -1,4 +1,4 @@ -//scalac: -Werror -Xlint:multiarg-infix,unit-special,unused +//> using options -Werror -Xlint:unit-special,unused import annotation.nowarn @@ -31,12 +31,6 @@ class J { def f: Unit = () } -@nowarn("cat=lint-multiarg-infix") -trait T { - def m(i: Int, j: Int) = i + j - def f1(t: T) = t m (1, 2) // multiarg, warn -} - // canonically unused nowarn @nowarn("any") trait U diff --git a/test/files/neg/nowarnMacros/Test_2.scala b/test/files/neg/nowarnMacros/Test_2.scala index c9d76a54a393..207e4fa019bf 100644 --- a/test/files/neg/nowarnMacros/Test_2.scala +++ b/test/files/neg/nowarnMacros/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import language.experimental.macros import scala.annotation.nowarn diff --git a/test/files/neg/nowarnPointPos.scala b/test/files/neg/nowarnPointPos.scala index 0551d7aae378..770867388ddd 100644 --- a/test/files/neg/nowarnPointPos.scala +++ b/test/files/neg/nowarnPointPos.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Wunused:nowarn -Yrangepos:false -Werror +//> using options -deprecation -Wunused:nowarn -Yrangepos:false -Werror import scala.annotation._ class ann(a: Any) extends Annotation diff --git a/test/files/neg/nowarnRangePos.check b/test/files/neg/nowarnRangePos.check index c34853c86194..9c20039a995d 100644 --- a/test/files/neg/nowarnRangePos.check +++ b/test/files/neg/nowarnRangePos.check @@ -1,3 +1,7 @@ +nowarnRangePos.scala:84: warning: A try without a catch or finally is equivalent to putting its body in a block; no exceptions are handled. +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other, site=C.T12.f + @nowarn("v") def f = try 1 + ^ nowarnRangePos.scala:11: warning: method dep in class C is deprecated (since 1.2.3): message @nowarn @ann(dep) def t2 = 0 // deprecation warning, @nowarn unused ^ @@ -19,6 +23,16 @@ nowarnRangePos.scala:75: warning: a pure expression does nothing in statement po nowarnRangePos.scala:80: warning: method dep in class C is deprecated (since 1.2.3): message a + dep ^ +nowarnRangePos.scala:90: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses +Applicable -Wconf / @nowarn filters for this warning: msg=, cat=other-pure-statement, site=C.T13.g + def g = { 1; 2 } + ^ +nowarnRangePos.scala:113: warning: method dep in class C is deprecated (since 1.2.3): message + @purr def t2 = new C().dep // warn, plus unused @nowarn + ^ +nowarnRangePos.scala:116: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + @nodep def t4 = { 1; 2 } // warn, plus unused @nowarn + ^ nowarnRangePos.scala:45: warning: I3b has a valid main method (args: Array[String]): Unit, but C.I3b will not have an entry point on the JVM. Reason: companion is a trait, which means no static forwarder can be generated. @@ -43,6 +57,15 @@ nowarnRangePos.scala:24: warning: @nowarn annotation does not suppress any warni nowarnRangePos.scala:65: warning: @nowarn annotation does not suppress any warnings @nowarn("msg=something else") // unused ^ +nowarnRangePos.scala:91: warning: @nowarn annotation does not suppress any warnings + @nowarn("v") def unused = 0 + ^ +nowarnRangePos.scala:113: warning: @nowarn annotation does not suppress any warnings + @purr def t2 = new C().dep // warn, plus unused @nowarn + ^ +nowarnRangePos.scala:116: warning: @nowarn annotation does not suppress any warnings + @nodep def t4 = { 1; 2 } // warn, plus unused @nowarn + ^ error: No warnings can be incurred under -Werror. -14 warnings +21 warnings 1 error diff --git a/test/files/neg/nowarnRangePos.scala b/test/files/neg/nowarnRangePos.scala index 67c7975881d8..a8f5440734db 100644 --- a/test/files/neg/nowarnRangePos.scala +++ b/test/files/neg/nowarnRangePos.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Wunused:nowarn -Yrangepos:true -Werror +//> using options -deprecation -Wunused:nowarn -Werror import scala.annotation._ class ann(a: Any) extends Annotation @@ -79,6 +79,17 @@ class C { val a = dep: @nowarn a + dep } + + @nowarn object T12 { + @nowarn("v") def f = try 1 + def g = { 1; 2 } + } + + @nowarn("verbose") object T13 { + @nowarn def f = try 1 + def g = { 1; 2 } + @nowarn("v") def unused = 0 + } } trait T { @@ -93,3 +104,14 @@ class Uh { def g(c: C) = c.dep } } + +object sd884 { + class nodep extends nowarn("cat=deprecation") + class purr extends nowarn("msg=pure expression does nothing") + + @nodep def t1 = new C().dep // no warn + @purr def t2 = new C().dep // warn, plus unused @nowarn + + @purr def t3 = { 1; 2 } // no warn + @nodep def t4 = { 1; 2 } // warn, plus unused @nowarn +} diff --git a/test/files/neg/nullary-override-3a.check b/test/files/neg/nullary-override-3a.check index c1bcc516a16c..73e0af01aa7a 100644 --- a/test/files/neg/nullary-override-3a.check +++ b/test/files/neg/nullary-override-3a.check @@ -1,24 +1,24 @@ nullary-override-3a.scala:4: error: method with a single empty parameter list overrides method x in class A defined without a parameter list def x: Int (defined in class A) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=B class B extends A { override def x(): Int = 4 } ^ nullary-override-3a.scala:16: error: method with a single empty parameter list overrides method x in trait T1 defined without a parameter list def x: String (defined in trait T1) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Mix12b class Mix12b extends T1 with T2 { override def x() = "12b" } ^ nullary-override-3a.scala:18: error: method without a parameter list overrides method x in trait T2 defined with a single empty parameter list def x(): String (defined in trait T2) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Mix21a class Mix21a extends T2 with T1 { override def x = "21a" } ^ nullary-override-3a.scala:19: error: method with a single empty parameter list overrides method x in trait T1 defined without a parameter list def x: String (defined in trait T1) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Mix21b class Mix21b extends T2 with T1 { override def x() = "21b" } ^ diff --git a/test/files/neg/nullary-override-3a.scala b/test/files/neg/nullary-override-3a.scala index dbf30d034727..da03b78585e6 100644 --- a/test/files/neg/nullary-override-3a.scala +++ b/test/files/neg/nullary-override-3a.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:nowarn -Xsource:3 +//> using options -Werror -Wunused:nowarn -Xsource:3 // class A { def x: Int = 3 } class B extends A { override def x(): Int = 4 } diff --git a/test/files/neg/nullary-override-3b.check b/test/files/neg/nullary-override-3b.check index c0957b80bb90..4726c8b05f1e 100644 --- a/test/files/neg/nullary-override-3b.check +++ b/test/files/neg/nullary-override-3b.check @@ -1,12 +1,12 @@ nullary-override-3b.scala:6: error: method without a parameter list overrides method x in class P defined with a single empty parameter list def x(): Int (defined in class P) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Q class Q extends P { override def x: Int = 4 } ^ nullary-override-3b.scala:11: error: method without a parameter list overrides method x in trait T2 defined with a single empty parameter list def x(): String (defined in trait T2) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Mix12a class Mix12a extends T1 with T2 { override def x = "12a" } ^ diff --git a/test/files/neg/nullary-override-3b.scala b/test/files/neg/nullary-override-3b.scala index 265f9755b219..bf46b885dda3 100644 --- a/test/files/neg/nullary-override-3b.scala +++ b/test/files/neg/nullary-override-3b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:nowarn -Xsource:3 +//> using options -Werror -Wunused:nowarn -Xsource:3 // // P has parens class P { def x(): Int = 3 } diff --git a/test/files/neg/nullary-override.scala b/test/files/neg/nullary-override.scala index 18b713b94f64..4d3884deed94 100644 --- a/test/files/neg/nullary-override.scala +++ b/test/files/neg/nullary-override.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:nowarn +//> using options -Werror -Wunused:nowarn // class A { def x: Int = 3 } class B extends A { override def x(): Int = 4 } diff --git a/test/files/neg/numeric-add-string-warning.scala b/test/files/neg/numeric-add-string-warning.scala index b9baf5c109fb..07cae7735a80 100644 --- a/test/files/neg/numeric-add-string-warning.scala +++ b/test/files/neg/numeric-add-string-warning.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation // object Test { val x = 4 + "2" diff --git a/test/files/neg/open-infix-future.scala b/test/files/neg/open-infix-future.scala index 2a250f3b006e..f667d7961f21 100644 --- a/test/files/neg/open-infix-future.scala +++ b/test/files/neg/open-infix-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // open trait A // error diff --git a/test/files/neg/ordering-migration.scala b/test/files/neg/ordering-migration.scala index bda20b50f6bb..9458bbac9be4 100644 --- a/test/files/neg/ordering-migration.scala +++ b/test/files/neg/ordering-migration.scala @@ -1,4 +1,4 @@ -// scalac: -Xmigration -Werror +//> using options -Xmigration -Werror object Test { val f = Ordering[Float] val d = Ordering[Double] diff --git a/test/files/neg/outer-ref-checks.scala b/test/files/neg/outer-ref-checks.scala index c0e5d9e66b77..7e9996dac780 100644 --- a/test/files/neg/outer-ref-checks.scala +++ b/test/files/neg/outer-ref-checks.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import scala.annotation.unchecked.uncheckedVariance diff --git a/test/files/neg/overloaded-implicit.scala b/test/files/neg/overloaded-implicit.scala index 43000ff824ff..05b13be5b745 100644 --- a/test/files/neg/overloaded-implicit.scala +++ b/test/files/neg/overloaded-implicit.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:poly-implicit-overload -Xfatal-warnings -Xdev +//> using options -Xlint:poly-implicit-overload -Xfatal-warnings -Xdev // object Test { implicit def imp1[T](x: List[T]): Map[T, T] = Map() diff --git a/test/files/neg/parens-for-params.check b/test/files/neg/parens-for-params.check index 58ea0a5d89ec..498fb1feafb2 100644 --- a/test/files/neg/parens-for-params.check +++ b/test/files/neg/parens-for-params.check @@ -1,6 +1,6 @@ parens-for-params.scala:5: error: parentheses are required around the parameter of a lambda Use '-Wconf:msg=lambda-parens:s' to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration x: Int => x * 2 ^ diff --git a/test/files/neg/parens-for-params.scala b/test/files/neg/parens-for-params.scala index 4f73f5df01b0..b774c8d8cac6 100644 --- a/test/files/neg/parens-for-params.scala +++ b/test/files/neg/parens-for-params.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 class C { def f = { diff --git a/test/files/neg/partestInvalidFlag.scala b/test/files/neg/partestInvalidFlag.scala index b6315e63d5f6..b64913fa6e76 100644 --- a/test/files/neg/partestInvalidFlag.scala +++ b/test/files/neg/partestInvalidFlag.scala @@ -1,3 +1,3 @@ -// scalac: -badCompilerFlag notAFlag -opt:badChoice +//> using options -badCompilerFlag notAFlag -opt:badChoice // class C diff --git a/test/files/neg/pat_unreachable.scala b/test/files/neg/pat_unreachable.scala index cd5acfd093cb..ae73d384eec4 100644 --- a/test/files/neg/pat_unreachable.scala +++ b/test/files/neg/pat_unreachable.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test extends App { diff --git a/test/files/neg/patmat-classtag-compound.scala b/test/files/neg/patmat-classtag-compound.scala index 412123d78922..8867974a9ce1 100644 --- a/test/files/neg/patmat-classtag-compound.scala +++ b/test/files/neg/patmat-classtag-compound.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test extends App{ trait Bar diff --git a/test/files/neg/patmat-exprs-b.scala b/test/files/neg/patmat-exprs-b.scala index 17b2ed63473b..ac35e9c8bdc2 100644 --- a/test/files/neg/patmat-exprs-b.scala +++ b/test/files/neg/patmat-exprs-b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // import annotation.nowarn diff --git a/test/files/neg/patmat-sealed-reachable.scala b/test/files/neg/patmat-sealed-reachable.scala index 3242daabc6a0..e315db9743b7 100644 --- a/test/files/neg/patmat-sealed-reachable.scala +++ b/test/files/neg/patmat-sealed-reachable.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // aka t12438.scala diff --git a/test/files/neg/patmatexhaust.scala b/test/files/neg/patmatexhaust.scala index 9e061be8af9c..e44c26d70edc 100644 --- a/test/files/neg/patmatexhaust.scala +++ b/test/files/neg/patmatexhaust.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Ypatmat-exhaust-depth off +//> using options -Xfatal-warnings -Ypatmat-exhaust-depth off // class TestSealedExhaustive { // compile only sealed abstract class Foo diff --git a/test/files/neg/permanent-blindness.scala b/test/files/neg/permanent-blindness.scala index 975290508c0e..88fd07ada448 100644 --- a/test/files/neg/permanent-blindness.scala +++ b/test/files/neg/permanent-blindness.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // package foo { class Bippy diff --git a/test/files/neg/pickle-java-crash/Brash.scala b/test/files/neg/pickle-java-crash/Brash.scala index 3f6bb5b6f5a6..1a37d99291f4 100644 --- a/test/files/neg/pickle-java-crash/Brash.scala +++ b/test/files/neg/pickle-java-crash/Brash.scala @@ -1,3 +1,4 @@ +//> using options -Ypickle-java package crashy -object brash \ No newline at end of file +object brash diff --git a/test/files/neg/pickle-java-crash/Crash.java b/test/files/neg/pickle-java-crash/Crash.java index aaa8d453e566..2770a8cfc40f 100644 --- a/test/files/neg/pickle-java-crash/Crash.java +++ b/test/files/neg/pickle-java-crash/Crash.java @@ -1,4 +1,4 @@ -// scalac: -Ypickle-java + package crashy; public class Crash { diff --git a/test/files/neg/prefix-unary-nilary-deprecation.scala b/test/files/neg/prefix-unary-nilary-deprecation.scala index 3060cda77f97..1a41640d48c4 100644 --- a/test/files/neg/prefix-unary-nilary-deprecation.scala +++ b/test/files/neg/prefix-unary-nilary-deprecation.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // class Foo { def unary_~() : Foo = this diff --git a/test/files/neg/prefix-unary-nilary-removal.check b/test/files/neg/prefix-unary-nilary-removal.check index 64c21b2f3533..8f2c1388258a 100644 --- a/test/files/neg/prefix-unary-nilary-removal.check +++ b/test/files/neg/prefix-unary-nilary-removal.check @@ -1,19 +1,19 @@ -prefix-unary-nilary-removal.scala:4: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_~ : Foo = this` [quickfixable] - def unary_~() : Foo = this +prefix-unary-nilary-removal.scala:4: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_~ : Foo = Foo()` [quickfixable] + def unary_~(): Foo = Foo() ^ -prefix-unary-nilary-removal.scala:5: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_-(implicit pos: Long) = this` [quickfixable] - def unary_-()(implicit pos: Long) = this +prefix-unary-nilary-removal.scala:5: warning: unary prefix operator definition with empty parameter list is deprecated: instead, remove () to declare as `def unary_-(implicit pos: Long) = Foo()` [quickfixable] + def unary_-()(implicit pos: Long) = Foo() ^ -prefix-unary-nilary-removal.scala:12: warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method unary_~, +prefix-unary-nilary-removal.scala:15: warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method unary_~, or remove the empty argument list from its definition (Java-defined methods are exempt). In Scala 3, an unapplied method like this will be eta-expanded into a function. [quickfixable] val f2 = ~f ^ prefix-unary-nilary-removal.scala:5: warning: parameter pos in method unary_- is never used - def unary_-()(implicit pos: Long) = this + def unary_-()(implicit pos: Long) = Foo() ^ prefix-unary-nilary-removal.scala:8: warning: parameter pos in method unary_+ is never used - def unary_+(implicit pos: Long) = this // ok + def unary_+(implicit pos: Long) = Foo() // ok ^ error: No warnings can be incurred under -Werror. 5 warnings diff --git a/test/files/neg/prefix-unary-nilary-removal.scala b/test/files/neg/prefix-unary-nilary-removal.scala index cd8ec6986850..23826e988301 100644 --- a/test/files/neg/prefix-unary-nilary-removal.scala +++ b/test/files/neg/prefix-unary-nilary-removal.scala @@ -1,13 +1,16 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // class Foo { - def unary_~() : Foo = this - def unary_-()(implicit pos: Long) = this + def unary_~(): Foo = Foo() + def unary_-()(implicit pos: Long) = Foo() - def unary_! : Foo = this // ok - def unary_+(implicit pos: Long) = this // ok + def `unary_!`: Foo = Foo() // ok + def unary_+(implicit pos: Long) = Foo() // ok +} +object Foo { + def apply() = new Foo } object Test { - val f = new Foo + val f = Foo() val f2 = ~f } diff --git a/test/files/neg/procedure-deprecation.scala b/test/files/neg/procedure-deprecation.scala index 1e3cd199cb4f..9ae5ed4d566c 100644 --- a/test/files/neg/procedure-deprecation.scala +++ b/test/files/neg/procedure-deprecation.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // abstract class Foo { def bar {} diff --git a/test/files/neg/procedure-removal.scala b/test/files/neg/procedure-removal.scala index 9177d191fa7b..e7ae67e4ae71 100644 --- a/test/files/neg/procedure-removal.scala +++ b/test/files/neg/procedure-removal.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // abstract class Foo { def bar {} diff --git a/test/files/neg/qmark-deprecated.scala b/test/files/neg/qmark-deprecated.scala index f37edc58ea43..decba5fe92d0 100644 --- a/test/files/neg/qmark-deprecated.scala +++ b/test/files/neg/qmark-deprecated.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // class Foo[?] // error diff --git a/test/files/neg/quickfix-silent.scala b/test/files/neg/quickfix-silent.scala index 99bdc0e50a29..856eaa8cea96 100644 --- a/test/files/neg/quickfix-silent.scala +++ b/test/files/neg/quickfix-silent.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Werror -quickfix:silent +//> using options -deprecation -Werror -quickfix:silent class C { def f { println } diff --git a/test/files/neg/recursive-method-default.scala b/test/files/neg/recursive-method-default.scala index b2972e6c8b5b..2187f4d1afa5 100644 --- a/test/files/neg/recursive-method-default.scala +++ b/test/files/neg/recursive-method-default.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:recurse-with-default +//> using options -Werror -Xlint:recurse-with-default object Test { def rec1(a: Any, b: Any = "".reverse): Any = { rec1(0, 0) // okay diff --git a/test/files/neg/ref-checks.scala b/test/files/neg/ref-checks.scala index e68f25938810..42bab64d346d 100644 --- a/test/files/neg/ref-checks.scala +++ b/test/files/neg/ref-checks.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Werror +//> using options -deprecation -Werror import scala.annotation.{StaticAnnotation, nowarn} import scala.reflect.internal.annotations.uncheckedBounds diff --git a/test/files/neg/sammy_error.check b/test/files/neg/sammy_error.check index 0a940573d5cf..894d83aae30e 100644 --- a/test/files/neg/sammy_error.check +++ b/test/files/neg/sammy_error.check @@ -1,4 +1,11 @@ sammy_error.scala:6: error: missing parameter type foo(x => x) // should result in only one error (the second one stemmed from adapting to SAM when the tree was erroneous) ^ -1 error +sammy_error.scala:6: error: type mismatch; + found : F1[Any,Nothing] + required: F1[Any,Any] +Note: Nothing <: Any, but trait F1 is invariant in type B. +You may wish to define B as +B instead. (SLS 4.5) + foo(x => x) // should result in only one error (the second one stemmed from adapting to SAM when the tree was erroneous) + ^ +2 errors diff --git a/test/files/neg/sammy_wrong_arity.check b/test/files/neg/sammy_wrong_arity.check index f714fbb1ab27..e698871fc1a9 100644 --- a/test/files/neg/sammy_wrong_arity.check +++ b/test/files/neg/sammy_wrong_arity.check @@ -31,22 +31,47 @@ sammy_wrong_arity.scala:13: error: type mismatch; sammy_wrong_arity.scala:15: error: missing parameter type def f6 = ((x) => 0): T2 ^ +sammy_wrong_arity.scala:15: error: type mismatch; + found : ? => ? + required: T2 + def f6 = ((x) => 0): T2 + ^ sammy_wrong_arity.scala:17: error: missing parameter type def f7 = ((x) => 0): T0 ^ +sammy_wrong_arity.scala:17: error: type mismatch; + found : ? => ? + required: T0 + def f7 = ((x) => 0): T0 + ^ sammy_wrong_arity.scala:18: error: missing parameter type def f8 = ((x) => 0): T2 ^ +sammy_wrong_arity.scala:18: error: type mismatch; + found : ? => ? + required: T2 + def f8 = ((x) => 0): T2 + ^ sammy_wrong_arity.scala:20: error: missing parameter type def f9 = ((x, y) => 0): T0 ^ sammy_wrong_arity.scala:20: error: missing parameter type def f9 = ((x, y) => 0): T0 ^ +sammy_wrong_arity.scala:20: error: type mismatch; + found : (?, ?) => ? + required: T0 + def f9 = ((x, y) => 0): T0 + ^ sammy_wrong_arity.scala:21: error: missing parameter type def g0 = ((x, y) => 0): T1 ^ sammy_wrong_arity.scala:21: error: missing parameter type def g0 = ((x, y) => 0): T1 ^ -13 errors +sammy_wrong_arity.scala:21: error: type mismatch; + found : (?, ?) => ? + required: T1 + def g0 = ((x, y) => 0): T1 + ^ +18 errors diff --git a/test/files/neg/scala3-keywords.scala b/test/files/neg/scala3-keywords.scala index 23fbce36dc4c..6c37baaa5515 100644 --- a/test/files/neg/scala3-keywords.scala +++ b/test/files/neg/scala3-keywords.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // class A { val `enum`: Int = 1 diff --git a/test/files/neg/sd503.check b/test/files/neg/sd503.check index 3eb2dc22bd72..b74ef4328665 100644 --- a/test/files/neg/sd503.check +++ b/test/files/neg/sd503.check @@ -7,37 +7,37 @@ sd503.scala:23: error: type mismatch; required: Int def f7() = d.x = (42, 27) // type mismatch (same as doti) ^ -sd503.scala:9: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:9: warning: multiarg infix syntax looks like a tuple def % (i: Int, j: Int) = i + j // operator, warn ^ -sd503.scala:13: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:13: warning: multiarg infix syntax looks like a tuple def f1(t: T) = t m (1, 2) // multiarg, warn ^ -sd503.scala:15: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:15: warning: multiarg infix syntax looks like a tuple def f3(t: T) = t % (1, 2) // multiarg, warn ^ -sd503.scala:19: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:19: warning: multiarg infix syntax looks like a tuple def f5() = c x_= (42, 27) // multiarg, warn ^ -sd503.scala:54: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:54: warning: multiarg infix syntax looks like a tuple def +=(x: A, y: A, zs: A*): this.type = addAll(x +: y +: zs) // very multiarg, warn ^ -sd503.scala:59: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:59: warning: multiarg infix syntax looks like a tuple def f[A](as: Embiggen[A], x: A, y: A, z: A): as.type = as += (x, y, z) // very multiarg, warn ^ -sd503.scala:70: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:70: warning: multiarg infix syntax looks like a tuple def f(x: A, y: A, zs: A*): this.type = this += (x, y, zs: _*) // warn but could defer to deprecation ^ -sd503.scala:80: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:80: warning: multiarg infix syntax looks like a tuple def f = this lines_! (42, 27) // warn usage, of course ^ -sd503.scala:86: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:86: warning: multiarg infix syntax looks like a tuple def +(i: Int, j: Int): Adder = new Adder(c + i*j) // warn multiarg symbolic def ^ -sd503.scala:92: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:92: warning: multiarg infix syntax looks like a tuple x = x + (3, 9) // warn multiarg infix apply ^ -sd503.scala:102: warning: multiarg infix syntax looks like a tuple and will be deprecated +sd503.scala:102: warning: multiarg infix syntax looks like a tuple x += (3, 9) // warn multiarg infix assignment! ^ 11 warnings diff --git a/test/files/neg/sd503.scala b/test/files/neg/sd503.scala index dd7fbdaf28a4..50f04096cf2f 100644 --- a/test/files/neg/sd503.scala +++ b/test/files/neg/sd503.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:multiarg-infix +//> using options -Wmultiarg-infix // // lint multiarg infix syntax, e.g., vs += (1, 2, 3) // Since infix is encouraged by symbolic operator names, discourage defining def += (x: A, y: A, zs: A*) diff --git a/test/files/neg/sealed-final-neg.scala b/test/files/neg/sealed-final-neg.scala index 25ad1ed8b55c..1698f46712cc 100644 --- a/test/files/neg/sealed-final-neg.scala +++ b/test/files/neg/sealed-final-neg.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -opt:inline:** -Wopt +//> using options -Werror -opt:inline:** -Wopt // package neg1 { sealed abstract class Foo { diff --git a/test/files/neg/sealed-java-enums.scala b/test/files/neg/sealed-java-enums.scala index f22b8c44818b..7aead780d91c 100644 --- a/test/files/neg/sealed-java-enums.scala +++ b/test/files/neg/sealed-java-enums.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // import java.lang.Thread.State import java.lang.Thread.State._ diff --git a/test/files/neg/sip23-uninitialized-1.scala b/test/files/neg/sip23-uninitialized-1.scala index d6e3df1602fc..89804aafafc3 100644 --- a/test/files/neg/sip23-uninitialized-1.scala +++ b/test/files/neg/sip23-uninitialized-1.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { val f1: 1 = f1 // warning: recursive diff --git a/test/files/neg/sip23-uninitialized-3.scala b/test/files/neg/sip23-uninitialized-3.scala index 9cae9cdf1b57..bf7b7723aa13 100644 --- a/test/files/neg/sip23-uninitialized-3.scala +++ b/test/files/neg/sip23-uninitialized-3.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { var f3: 1 = f3 // warning: recursive diff --git a/test/files/neg/source3Xneg.scala b/test/files/neg/source3Xneg.scala index 9b852a5b2219..aed8fdd09a5c 100644 --- a/test/files/neg/source3Xneg.scala +++ b/test/files/neg/source3Xneg.scala @@ -1,4 +1,4 @@ -//> using options -deprecation -Xsource:3-cross -Wconf:cat=scala3-migration:w -Werror +//> using options -deprecation -Xsource:3 -Xsource-features:_ -Wconf:cat=scala3-migration:w -Werror // StringContext hygiene class SC1 { diff --git a/test/files/neg/source3XnegRefchecks.scala b/test/files/neg/source3XnegRefchecks.scala index c2f9ac623fb8..539a13b391cf 100644 --- a/test/files/neg/source3XnegRefchecks.scala +++ b/test/files/neg/source3XnegRefchecks.scala @@ -1,4 +1,4 @@ -//> using options -deprecation -Xsource:3-cross -Wconf:cat=scala3-migration:w -Werror +//> using options -deprecation -Xsource:3 -Xsource-features:_ -Wconf:cat=scala3-migration:w -Werror object NameShadowing { class A { class X } diff --git a/test/files/neg/source3cross.check b/test/files/neg/source3cross.check new file mode 100644 index 000000000000..bc7cbaa04d45 --- /dev/null +++ b/test/files/neg/source3cross.check @@ -0,0 +1,4 @@ +source3cross.scala:4: error: value + is not a member of Any + def f(a: Any) = a + "" + ^ +1 error diff --git a/test/files/neg/source3cross.scala b/test/files/neg/source3cross.scala new file mode 100644 index 000000000000..24330c76a14a --- /dev/null +++ b/test/files/neg/source3cross.scala @@ -0,0 +1,5 @@ +//> using options -Xsource:3-cross + +object T { + def f(a: Any) = a + "" +} diff --git a/test/files/neg/source3neg.check b/test/files/neg/source3neg.check index bcd2fa2d3943..f4e0cd820c3d 100644 --- a/test/files/neg/source3neg.check +++ b/test/files/neg/source3neg.check @@ -1,28 +1,26 @@ -source3neg.scala:16: warning: Unicode escapes in triple quoted strings are ignored in Scala 3; use the literal character instead +source3neg.scala:16: warning: Unicode escapes in triple quoted strings are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use the literal character instead def inTripleQuoted = """\u0041""" // error ^ -source3neg.scala:28: warning: Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +source3neg.scala:28: warning: Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. `x` (42) // error ^ -source3neg.scala:12: warning: String interpolations always use scala.StringContext in Scala 3 (SC1.StringContext is used here) +source3neg.scala:12: warning: In Scala 3 (or with -Xsource-features:string-context-scope), String interpolations always use scala.StringContext (SC1.StringContext is used here) def test = s"hello, $name" // error ^ -source3neg.scala:17: warning: Unicode escapes in raw interpolations are ignored in Scala 3; use literal characters instead +source3neg.scala:17: warning: Unicode escapes in raw interpolations are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use literal characters instead def inRawInterpolation = raw"\u0041" // error ^ -source3neg.scala:18: warning: Unicode escapes in raw interpolations are ignored in Scala 3; use literal characters instead +source3neg.scala:18: warning: Unicode escapes in raw interpolations are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use literal characters instead def inRawTripleQuoted = raw"""\u0041""" // error ^ -source3neg.scala:32: warning: access modifiers for `copy` method are copied from the case class constructor +source3neg.scala:32: warning: access modifiers for `copy` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) case class CaseCompanionMods private (x: Int) // 2 errors ^ -source3neg.scala:32: warning: access modifiers for `apply` method are copied from the case class constructor +source3neg.scala:32: warning: access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) case class CaseCompanionMods private (x: Int) // 2 errors ^ -source3neg.scala:36: warning: under -Xsource:3-cross, the inferred type changes to Object instead of String [quickfixable] +source3neg.scala:36: warning: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to Object instead of String [quickfixable] object InferredSub extends InferredBase { def f = "a" } // error ^ source3neg.scala:42: warning: Implicit definition must have explicit type (inferred String => Option[Int]) [quickfixable] @@ -34,6 +32,9 @@ source3neg.scala:44: warning: Implicit definition must have explicit type (infer source3neg.scala:43: warning: Implicit definition must have explicit type (inferred Int) [quickfixable] implicit val i = 0 // error ^ +source3neg.scala:47: warning: Converting to String for concatenation is not supported in Scala 3 (or with -Xsource-features:any2stringadd). +object AnyPlus { def f(xs: List[Int]) = xs + ";" } + ^ source3neg.scala:47: warning: method any2stringadd in object Predef is deprecated (since 2.13.0): Implicit injection of + is deprecated. Convert to String to call + object AnyPlus { def f(xs: List[Int]) = xs + ";" } ^ @@ -41,5 +42,5 @@ source3neg.scala:51: warning: shadowing a nested class of a parent is deprecated class B extends A { class X; def f = new X } ^ error: No warnings can be incurred under -Werror. -13 warnings +14 warnings 1 error diff --git a/test/files/neg/stmt-expr-discard.scala b/test/files/neg/stmt-expr-discard.scala index 35c014f6b4ca..a5c9f62627aa 100644 --- a/test/files/neg/stmt-expr-discard.scala +++ b/test/files/neg/stmt-expr-discard.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xsource:2.13 -Xlint:deprecation +//> using options -Werror -Xsource:2.13 -Xlint:deprecation // class A { def f = 1 diff --git a/test/files/neg/stringinterpolation_macro-neg.check b/test/files/neg/stringinterpolation_macro-neg.check index 47c6328613d8..ca16bc50e2c7 100644 --- a/test/files/neg/stringinterpolation_macro-neg.check +++ b/test/files/neg/stringinterpolation_macro-neg.check @@ -10,11 +10,6 @@ stringinterpolation_macro-neg.scala:15: error: too many arguments for interpolat stringinterpolation_macro-neg.scala:16: error: too few arguments for interpolated string new StringContext("", "").f() ^ -stringinterpolation_macro-neg.scala:19: error: type mismatch; - found : String - required: Boolean, Null - f"$s%b" - ^ stringinterpolation_macro-neg.scala:20: error: type mismatch; found : String required: Char, Byte, Short, Int @@ -162,6 +157,9 @@ stringinterpolation_macro-neg.scala:77: error: Missing conversion operator in '% stringinterpolation_macro-neg.scala:80: error: conversions must follow a splice; use %% for literal %, %n for newline f"${d}random-leading-junk%d" ^ +stringinterpolation_macro-neg.scala:19: warning: Boolean format is null test for non-Boolean + f"$s%b" + ^ stringinterpolation_macro-neg.scala:63: warning: Index is not this arg f"${8}%d ${9}%1$$d" ^ @@ -171,5 +169,5 @@ stringinterpolation_macro-neg.scala:64: warning: Argument index ignored if '<' f stringinterpolation_macro-neg.scala:65: warning: Index is not this arg f"$s%s $s%1$$s" ^ -3 warnings -46 errors +4 warnings +45 errors diff --git a/test/files/neg/suggest-similar.check b/test/files/neg/suggest-similar.check index 1eac32d47248..1fa8f189ba04 100644 --- a/test/files/neg/suggest-similar.check +++ b/test/files/neg/suggest-similar.check @@ -12,7 +12,7 @@ did you mean Weehawken? suggest-similar.scala:16: error: value readline is not a member of object scala.io.StdIn did you mean readLine? or perhaps readByte, readInt, or readLong? import scala.io.StdIn.{readline, readInt} - ^ + ^ suggest-similar.scala:20: error: object stdin is not a member of package io did you mean StdIn? import scala.io.stdin.{readLine => line} diff --git a/test/files/neg/switch.scala b/test/files/neg/switch.scala index 9d0defc0b5f4..428d80cce261 100644 --- a/test/files/neg/switch.scala +++ b/test/files/neg/switch.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import scala.annotation.switch diff --git a/test/files/neg/symbol-literal-deprecation.scala b/test/files/neg/symbol-literal-deprecation.scala index 4ab45cf7ce1b..296d18c377db 100644 --- a/test/files/neg/symbol-literal-deprecation.scala +++ b/test/files/neg/symbol-literal-deprecation.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // abstract class Foo { val foo = 'TestSymbol diff --git a/test/files/neg/t0903.scala b/test/files/neg/t0903.scala index 9b69dcf3cf09..799a2fa6fa1d 100644 --- a/test/files/neg/t0903.scala +++ b/test/files/neg/t0903.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object Test { val x = 1 diff --git a/test/files/neg/t10019.scala b/test/files/neg/t10019.scala index 9d9aac4e7ff3..8c4c910a588f 100644 --- a/test/files/neg/t10019.scala +++ b/test/files/neg/t10019.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Bug { sealed case class Foo(e: Option[Int]) diff --git a/test/files/neg/t10068.scala b/test/files/neg/t10068.scala index 30a1e8d25f3f..1128b68d710b 100644 --- a/test/files/neg/t10068.scala +++ b/test/files/neg/t10068.scala @@ -1,4 +1,4 @@ -// scalac: -Xelide-below WARNING -Xsource:2.13 +//> using options -Xelide-below WARNING -Xsource:2.13 // import annotation._, elidable._ diff --git a/test/files/neg/t10097.scala b/test/files/neg/t10097.scala index c12d6891c9f6..592ea5459400 100644 --- a/test/files/neg/t10097.scala +++ b/test/files/neg/t10097.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // case class C(implicit val c: Int) diff --git a/test/files/neg/t10097b.scala b/test/files/neg/t10097b.scala index 34836b52c643..d52e9be1226d 100644 --- a/test/files/neg/t10097b.scala +++ b/test/files/neg/t10097b.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // case class C(implicit val c: Int) diff --git a/test/files/neg/t10270/Main_2.scala b/test/files/neg/t10270/Main_2.scala index 34bc9849c342..e15240dd05d3 100644 --- a/test/files/neg/t10270/Main_2.scala +++ b/test/files/neg/t10270/Main_2.scala @@ -1,4 +1,4 @@ -// scalac: -Wunused:imports -Werror +//> using options -Wunused:imports -Werror object Main extends App { def f(): Any = Macro { diff --git a/test/files/neg/t10287.check b/test/files/neg/t10287.check new file mode 100644 index 000000000000..a6725dac2c44 --- /dev/null +++ b/test/files/neg/t10287.check @@ -0,0 +1,24 @@ +t10287.scala:5: warning: pattern var x in method unused_patvar is never used + Some(42) match { case x => 27 } // warn + ^ +t10287.scala:12: warning: pattern var x in value $anonfun is never used + x <- Some(42) // warn + ^ +t10287.scala:16: warning: pattern var x in value $anonfun is never used + x <- Some(42) // warn + ^ +t10287.scala:22: warning: pattern var y in value $anonfun is never used + y <- Some(27) // warn + ^ +t10287.scala:27: warning: pattern var y in value $anonfun is never used + y = 3 // warn + ^ +t10287.scala:31: warning: pattern var x in value $anonfun is never used + x <- Some(42) // warn + ^ +t10287.scala:37: warning: pattern var y in value $anonfun is never used + y = 3 // warn + ^ +error: No warnings can be incurred under -Werror. +7 warnings +1 error diff --git a/test/files/neg/t10287.scala b/test/files/neg/t10287.scala new file mode 100644 index 000000000000..e98f2400fa37 --- /dev/null +++ b/test/files/neg/t10287.scala @@ -0,0 +1,70 @@ +//> using options -Werror -Wunused:_ -Xsource:3 -Yvalidate-pos:typer + +class C { + def unused_patvar = + Some(42) match { case x => 27 } // warn + def a = + for { + x <- Some(42) // ok + } yield (x + 1) + def b = + for { + x <- Some(42) // warn + } yield 27 + def c = + for { + x <- Some(42) // warn + y <- Some(27) // ok + } yield y + def d = + for { + x <- Some(42) // ok + y <- Some(27) // warn + } yield x + def e = + for { + x <- Some(42) // ok + y = 3 // warn + } yield x + def f = + for { + x <- Some(42) // warn + y = 3 // ok + } yield y + def g = + for { + x <- Some(1 -> 2) // ok + y = 3 // warn + (a, b) = x // ok + } yield (a + b) + def h(xs: List[Int]) = + for { + x <- xs + y = x * 2 + _ = println(x) + } yield y + def i(xs: List[Int]) = + for { + x <- xs + if x > 42 + } println(".") +} + +case class K[A](a: A, i: Int) + +class Fixes { + def leavenstain(s: String, t: String) = { + val n = s.length + val m = t.length + for (i <- 1 to n; s_i = s(i - 1); j <- 1 to m) { + println("" + s_i + t(j - 1)) + } + } + + def f[A](ks: List[K[A]]): List[K[?]] = { + for { + K((s: String), j) <- ks + x = j*2 + } yield K(s*2, x) + } +} diff --git a/test/files/neg/t10296-after/Unused_2.scala b/test/files/neg/t10296-after/Unused_2.scala index 95e6234f0507..93c110c35cbb 100644 --- a/test/files/neg/t10296-after/Unused_2.scala +++ b/test/files/neg/t10296-after/Unused_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:unused -Wmacros:after +//> using options -Werror -Xlint:unused -Wmacros:after import scala.language.experimental.macros object Unused extends App { diff --git a/test/files/neg/t10296-both.check b/test/files/neg/t10296-both.check index f7d53d6482df..c16915f881eb 100644 --- a/test/files/neg/t10296-both.check +++ b/test/files/neg/t10296-both.check @@ -1,9 +1,9 @@ -Unused_2.scala:8: warning: private method k in object Unused is never used - private def k(): Int = 17 - ^ Unused_2.scala:7: warning: private method g in object Unused is never used private def g(): Int = 17 ^ +Unused_2.scala:8: warning: private method k in object Unused is never used + private def k(): Int = 17 + ^ error: No warnings can be incurred under -Werror. 2 warnings 1 error diff --git a/test/files/neg/t10296-both/Unused_2.scala b/test/files/neg/t10296-both/Unused_2.scala index 9536c774287b..860c44d2d747 100644 --- a/test/files/neg/t10296-both/Unused_2.scala +++ b/test/files/neg/t10296-both/Unused_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:unused -Wmacros:both +//> using options -Werror -Xlint:unused -Wmacros:both import scala.language.experimental.macros object Unused extends App { diff --git a/test/files/neg/t10296-warn/Unused_2.scala b/test/files/neg/t10296-warn/Unused_2.scala index e3f8ca93256e..a0fbd1ff5ce2 100644 --- a/test/files/neg/t10296-warn/Unused_2.scala +++ b/test/files/neg/t10296-warn/Unused_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:unused +//> using options -Werror -Xlint:unused import scala.language.experimental.macros object Unused { diff --git a/test/files/neg/t10474.check b/test/files/neg/t10474.check index e323be3c4f41..bcf492cd9850 100644 --- a/test/files/neg/t10474.check +++ b/test/files/neg/t10474.check @@ -4,8 +4,4 @@ t10474.scala:8: error: stable identifier required, but Test.this.Foo found. t10474.scala:15: error: stable identifier required, but hrhino.this.Foo found. val Foo.Crash = ??? ^ -t10474.scala:15: warning: Pattern definition introduces Unit-valued member of hrhino; consider wrapping it in `locally { ... }`. - val Foo.Crash = ??? - ^ -1 warning 2 errors diff --git a/test/files/neg/t10502.scala b/test/files/neg/t10502.scala index 979b8c878f04..c428adaea897 100644 --- a/test/files/neg/t10502.scala +++ b/test/files/neg/t10502.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:strict-unsealed-patmat +//> using options -Werror -Xlint:strict-unsealed-patmat object Bug { object Perhaps { def unapply[A](oa: Option[A]): Some[Option[A]] = Some(oa) diff --git a/test/files/neg/t10678.scala b/test/files/neg/t10678.scala index 7f40125cfc26..62bb3025ef06 100644 --- a/test/files/neg/t10678.scala +++ b/test/files/neg/t10678.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // trait T diff --git a/test/files/neg/t10701/Test.java b/test/files/neg/t10701/Test.java index 9eec279fa01f..ffd525b77f1d 100644 --- a/test/files/neg/t10701/Test.java +++ b/test/files/neg/t10701/Test.java @@ -1,4 +1,4 @@ -// javac: -Werror -deprecation +//> using javacOpt -Werror -deprecation public class Test { public static void main(String [] args) { Meh.whatever(); diff --git a/test/files/neg/t10731.check b/test/files/neg/t10731.check index ce3de39f1702..d554d493ae38 100644 --- a/test/files/neg/t10731.check +++ b/test/files/neg/t10731.check @@ -1,8 +1,4 @@ t10731.scala:3: error: stable identifier required, but C.this.eq found. val eq.a = 1 ^ -t10731.scala:3: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. - val eq.a = 1 - ^ -1 warning 1 error diff --git a/test/files/neg/t10733.scala b/test/files/neg/t10733.scala index 98b4864f7e18..f35a8c3dbb2e 100644 --- a/test/files/neg/t10733.scala +++ b/test/files/neg/t10733.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos -Ystop-after:parser +//> using options -Ystop-after:parser trait T[_] trait U[_, _] diff --git a/test/files/neg/t10752/Test_2.scala b/test/files/neg/t10752/Test_2.scala index 5f76ec601f72..18b74b3cb815 100644 --- a/test/files/neg/t10752/Test_2.scala +++ b/test/files/neg/t10752/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation -Werror +//> using options -Xlint:deprecation -Werror object Test extends p1.DeprecatedClass { def useC = p1.DeprecatedClass.foo def useM = p1.DeprecatedMethod.foo diff --git a/test/files/neg/t10763.check b/test/files/neg/t10763.check index 86e448366fa2..abc14f772004 100644 --- a/test/files/neg/t10763.check +++ b/test/files/neg/t10763.check @@ -1,4 +1,4 @@ -t10763.scala:6: warning: pattern var x in value $anonfun is never used: use a wildcard `_` or suppress this warning with `x@_` +t10763.scala:6: warning: pattern var x in value $anonfun is never used for (x @ 1 <- List(1.0)) () ^ error: No warnings can be incurred under -Werror. diff --git a/test/files/neg/t10763.scala b/test/files/neg/t10763.scala index c5e008582361..edf22e4e3c9f 100644 --- a/test/files/neg/t10763.scala +++ b/test/files/neg/t10763.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused +//> using options -Werror -Wunused object Test extends App { // cf test/files/pos/t10763.scala test/files/run/t11938.scala diff --git a/test/files/neg/t10790.check b/test/files/neg/t10790.check index 2facf5713ed5..3a3bb22abd43 100644 --- a/test/files/neg/t10790.check +++ b/test/files/neg/t10790.check @@ -1,12 +1,12 @@ -t10790.scala:13: warning: private val y in class X is never used - private val Some(y) = Option(answer) // warn - ^ -t10790.scala:10: warning: private class C in class X is never used - private class C // warn - ^ t10790.scala:8: warning: parameter x in method control is never used def control(x: Int) = answer // warn to verify control ^ +t10790.scala:10: warning: private class C in class X is never used + private class C // warn + ^ +t10790.scala:13: warning: pattern var y in class X is never used + private val Some(y) = Option(answer) // warn + ^ error: No warnings can be incurred under -Werror. 3 warnings 1 error diff --git a/test/files/neg/t10790.scala b/test/files/neg/t10790.scala index cc199c7b2078..8cdfccb61e36 100644 --- a/test/files/neg/t10790.scala +++ b/test/files/neg/t10790.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused +//> using options -Werror -Wunused import annotation.unused @@ -11,7 +11,7 @@ class X { @unused private class D // no warn private val Some(y) = Option(answer) // warn - @unused private val Some(z) = Option(answer) // no warn + private val Some(z @ _) = Option(answer) // no warn @unused("not updated") private var i = answer // no warn def g = i diff --git a/test/files/neg/t10806.scala b/test/files/neg/t10806.scala index 10abc6d46a32..54d4f9d53992 100644 --- a/test/files/neg/t10806.scala +++ b/test/files/neg/t10806.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror trait T { diff --git a/test/files/neg/t10820-warn.scala b/test/files/neg/t10820-warn.scala index 97796aaa90d1..57fc9bc984e1 100644 --- a/test/files/neg/t10820-warn.scala +++ b/test/files/neg/t10820-warn.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wperformance +//> using options -Werror -Wperformance // import util.Try diff --git a/test/files/neg/t10938.scala b/test/files/neg/t10938.scala index 757230ed6082..b880272378bc 100644 --- a/test/files/neg/t10938.scala +++ b/test/files/neg/t10938.scala @@ -1,4 +1,4 @@ -// scalac: -feature +//> using options -feature trait T { def f(): scala.xxx.XXX[_, _] = ??? diff --git a/test/files/neg/t11012.scala b/test/files/neg/t11012.scala index 9ac9d1d562a0..4f109c126324 100644 --- a/test/files/neg/t11012.scala +++ b/test/files/neg/t11012.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation import scala.annotation.StaticAnnotation @deprecated("class!", "") class A extends StaticAnnotation diff --git a/test/files/neg/t11374b.check b/test/files/neg/t11374b.check index f7ec70d4c1d8..aca074541fe0 100644 --- a/test/files/neg/t11374b.check +++ b/test/files/neg/t11374b.check @@ -8,6 +8,6 @@ Identifiers enclosed in backticks are not pattern variables but match the value ^ t11374b.scala:3: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. val Some(`_`) = Option(42) // was crashola - ^ + ^ 1 warning 2 errors diff --git a/test/files/neg/t11379a.check b/test/files/neg/t11379a.check index a721a3dc57ff..e02fdb938bfd 100644 --- a/test/files/neg/t11379a.check +++ b/test/files/neg/t11379a.check @@ -3,23 +3,4 @@ t11379a.scala:17: error: type mismatch; required: Unit => Unit def test4: Either[Int, Unit] = Right(()).map(Right(())) ^ -t11379a.scala:9: warning: discarded non-Unit value of type scala.util.Right[Nothing,Unit] - def test1: Either[Int, Unit] = Right(Right(())) - ^ -t11379a.scala:10: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] - def test2: Either[Int, Unit] = Right(()).map(_ => unitRight[Int]) - ^ -t11379a.scala:11: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] - def test3: Either[Int, Unit] = Right(()).map { case _ => unitRight[Int] } - ^ -t11379a.scala:20: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] - def test5: Either[Int, Unit] = Right(()).map { case _ => unitRight } - ^ -t11379a.scala:21: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] - def test6: Either[Int, Unit] = Right(()).map { _ => unitRight } - ^ -t11379a.scala:22: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] - def test7: Either[Int, Unit] = Right(()).map(_ => unitRight) - ^ -6 warnings 1 error diff --git a/test/files/neg/t11379a.scala b/test/files/neg/t11379a.scala index 3502d5cf0e89..5ed2de4b315c 100644 --- a/test/files/neg/t11379a.scala +++ b/test/files/neg/t11379a.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wvalue-discard +//> using options -Werror -Wvalue-discard object UnitOfTrust { import scala.util._ diff --git a/test/files/neg/t11379a2.check b/test/files/neg/t11379a2.check new file mode 100644 index 000000000000..06f7e46546c0 --- /dev/null +++ b/test/files/neg/t11379a2.check @@ -0,0 +1,21 @@ +t11379a2.scala:9: warning: discarded non-Unit value of type scala.util.Right[Nothing,Unit] + def test1: Either[Int, Unit] = Right(Right(())) + ^ +t11379a2.scala:10: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] + def test2: Either[Int, Unit] = Right(()).map(_ => unitRight[Int]) + ^ +t11379a2.scala:11: warning: discarded non-Unit value of type scala.util.Either[Int,Unit] + def test3: Either[Int, Unit] = Right(()).map { case _ => unitRight[Int] } + ^ +t11379a2.scala:20: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] + def test5: Either[Int, Unit] = Right(()).map { case _ => unitRight } + ^ +t11379a2.scala:21: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] + def test6: Either[Int, Unit] = Right(()).map { _ => unitRight } + ^ +t11379a2.scala:22: warning: discarded non-Unit value of type scala.util.Either[Nothing,Unit] + def test7: Either[Int, Unit] = Right(()).map(_ => unitRight) + ^ +error: No warnings can be incurred under -Werror. +6 warnings +1 error diff --git a/test/files/neg/t11379a2.scala b/test/files/neg/t11379a2.scala new file mode 100644 index 000000000000..9dad59d6cab1 --- /dev/null +++ b/test/files/neg/t11379a2.scala @@ -0,0 +1,23 @@ +//> using options -Werror -Wvalue-discard +object UnitOfTrust { + import scala.util._ + + private def unitRight[A]: Either[A, Unit] = Right(()) + + // fails with: + // discarded non-Unit value + def test1: Either[Int, Unit] = Right(Right(())) + def test2: Either[Int, Unit] = Right(()).map(_ => unitRight[Int]) + def test3: Either[Int, Unit] = Right(()).map { case _ => unitRight[Int] } + + // fails with: + // error: type mismatch; + // found : scala.util.Right[Nothing,Unit] + // required: Unit => Unit + //def test4: Either[Int, Unit] = Right(()).map(Right(())) + + // was: compiles just fine + def test5: Either[Int, Unit] = Right(()).map { case _ => unitRight } + def test6: Either[Int, Unit] = Right(()).map { _ => unitRight } + def test7: Either[Int, Unit] = Right(()).map(_ => unitRight) +} diff --git a/test/files/neg/t11379b.scala b/test/files/neg/t11379b.scala index afd5233d3c04..0e00bcf3271b 100644 --- a/test/files/neg/t11379b.scala +++ b/test/files/neg/t11379b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wvalue-discard +//> using options -Werror -Wvalue-discard class OneTypeParam[B](value: B) { def map[B1](fn: B => B1): OneTypeParam[B1] = new OneTypeParam(fn(value)) def unitValue: OneTypeParam[Unit] = new OneTypeParam(()) diff --git a/test/files/neg/t11379c.scala b/test/files/neg/t11379c.scala index 0a4f5e4925bd..c1f21547d43d 100644 --- a/test/files/neg/t11379c.scala +++ b/test/files/neg/t11379c.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wvalue-discard +//> using options -Werror -Wvalue-discard class OneTypeParam[B](value: B) { def map[B1](fn: B => B1): OneTypeParam[B1] = new OneTypeParam(fn(value)) diff --git a/test/files/neg/t11517.check b/test/files/neg/t11517.check new file mode 100644 index 000000000000..d5c41efeb8b5 --- /dev/null +++ b/test/files/neg/t11517.check @@ -0,0 +1,57 @@ +t11517.scala:6: error: missing parameter type for expanded function (() => x$1.$plus(1)) + X.f(_ + 1) + ^ +t11517.scala:6: error: overloaded method f with alternatives: + (s: String)String + (i: Int)Int + does not match arguments (? => ?) + X.f(_ + 1) + ^ +t11517.scala:17: error: missing parameter type for expanded function (() => x$2.$plus(1)) + def `quite overloaded`(s: MyString): Int = s.indexOf(_ + 1) + ^ +t11517.scala:17: error: overloaded method indexOf with alternatives: + (s: String,begin: Int,end: Int)Int + (s: String,begin: Int)Int + (s: String)Int + (c: Int,begin: Int,end: Int)Int + (c: Int,begin: Int)Int + (c: Int)Int + does not match arguments (? => ?) with expected result type Int + def `quite overloaded`(s: MyString): Int = s.indexOf(_ + 1) + ^ +t11517.scala:19: error: overloaded method f with alternatives: + (s: String)String + (i: Int)Int + cannot be applied to (String, i: Int) + X.f("hello, world", i = 42) + ^ +t11517.scala:20: error: overloaded method f with alternatives: + (s: String)String + (i: Int)Int + cannot be applied to (String, Int => Int) + X.f("hello, world", (i: Int) => i) + ^ +t11517.scala:21: error: missing parameter type + X.f((i: Int, _) => i + 1) + ^ +t11517.scala:21: error: overloaded method f with alternatives: + (s: String)String + (i: Int)Int + does not match arguments ((Int, ?) => ?) + X.f((i: Int, _) => i + 1) + ^ +t11517.scala:22: error: missing parameter type + X.g(i => i) + ^ +t11517.scala:22: error: type mismatch; + found : ? => ? + required: String + X.g(i => i) + ^ +t11517.scala:23: error: type mismatch; + found : Int => Int + required: String + X.g((i: Int) => i) + ^ +11 errors diff --git a/test/files/neg/t11517.scala b/test/files/neg/t11517.scala new file mode 100644 index 000000000000..c0429c86b88c --- /dev/null +++ b/test/files/neg/t11517.scala @@ -0,0 +1,32 @@ + +object X { def f(i: Int): Int = i; def f(s: String): String = s; def g(s: String) = s } + +// improve error message +object Test extends App { + X.f(_ + 1) + + // "abc".indexOf(_ + 1) unstable API across JDK versions + trait MyString { + def indexOf(c: Int): Int + def indexOf(c: Int, begin: Int): Int + def indexOf(c: Int, begin: Int, end: Int): Int + def indexOf(s: String): Int + def indexOf(s: String, begin: Int): Int + def indexOf(s: String, begin: Int, end: Int): Int + } + def `quite overloaded`(s: MyString): Int = s.indexOf(_ + 1) + + X.f("hello, world", i = 42) + X.f("hello, world", (i: Int) => i) + X.f((i: Int, _) => i + 1) + X.g(i => i) + X.g((i: Int) => i) +} +/* +t11517.scala:6: error: missing parameter type for expanded function (() => x$1.$plus(1)) + X.f(_ + 1) + ^ +t11517.scala:8: error: missing parameter type for expanded function (() => x$2.$plus(1)) + "abc".indexOf(_ + 1) + ^ +*/ diff --git a/test/files/neg/t11618.check b/test/files/neg/t11618.check index 863f1c95781f..7777f7b8fb37 100644 --- a/test/files/neg/t11618.check +++ b/test/files/neg/t11618.check @@ -18,19 +18,19 @@ t11618.scala:7: warning: Pattern definition introduces Unit-valued member of C; ^ t11618.scala:8: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. val Some(_) = Option(42) - ^ + ^ t11618.scala:9: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. implicit val _ = 42 ^ t11618.scala:10: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. implicit val Some(_) = Option(42) - ^ + ^ t11618.scala:23: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. val Some(_) = Option(42) - ^ + ^ t11618.scala:24: warning: Pattern definition introduces Unit-valued member of C; consider wrapping it in `locally { ... }`. implicit val Some(_) = Option(42) - ^ + ^ error: No warnings can be incurred under -Werror. 11 warnings 1 error diff --git a/test/files/neg/t11618.scala b/test/files/neg/t11618.scala index 49dbfb5bc9b7..cef5b3a36c48 100644 --- a/test/files/neg/t11618.scala +++ b/test/files/neg/t11618.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // warn about introducing Unit-valued fields instead of merely side-effecting. // warn about implicit not introducing any implicits diff --git a/test/files/neg/t11643.scala b/test/files/neg/t11643.scala index a0ec2358743c..8c5b4e0a30cb 100644 --- a/test/files/neg/t11643.scala +++ b/test/files/neg/t11643.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Wunused:params +//> using options -Werror -Wunused:params trait T { def f(implicit i: Int) = i diff --git a/test/files/neg/t11644a.scala b/test/files/neg/t11644a.scala index 3e9ef0dcb0bb..3f51e8cf667c 100644 --- a/test/files/neg/t11644a.scala +++ b/test/files/neg/t11644a.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // // eta-expansion to SAM type always warns in Scala 3 world diff --git a/test/files/neg/t11644b.scala b/test/files/neg/t11644b.scala index 299667389a50..0722aa7ab322 100644 --- a/test/files/neg/t11644b.scala +++ b/test/files/neg/t11644b.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation,eta-zero,eta-sam +//> using options -Xlint:deprecation,eta-zero,eta-sam trait AcciSamZero { def apply(): Int } diff --git a/test/files/neg/t11644c/s.scala b/test/files/neg/t11644c/s.scala index 185ba67ad221..06085452737f 100644 --- a/test/files/neg/t11644c/s.scala +++ b/test/files/neg/t11644c/s.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Werror +//> using options -Xsource:3 -Werror class C { def f(j: J): Int = j.f(42) diff --git a/test/files/neg/t11681.scala b/test/files/neg/t11681.scala index 8cface30f25d..0254fa0884d0 100644 --- a/test/files/neg/t11681.scala +++ b/test/files/neg/t11681.scala @@ -1,5 +1,5 @@ // -// scalac: -Wunused:privates -Werror +//> using options -Wunused:privates -Werror // package com diff --git a/test/files/neg/t11690.scala b/test/files/neg/t11690.scala index 20e746cb026a..79f84c9ad1b7 100644 --- a/test/files/neg/t11690.scala +++ b/test/files/neg/t11690.scala @@ -1,5 +1,5 @@ -// scalac: -Wunused:imports -Werror +//> using options -Wunused:imports -Werror object X { val v = 27 diff --git a/test/files/neg/t11746.scala b/test/files/neg/t11746.scala index c6f81d994961..9a95f427873c 100644 --- a/test/files/neg/t11746.scala +++ b/test/files/neg/t11746.scala @@ -1,5 +1,5 @@ // -// scalac: -Werror -opt:inline:** -Wopt:none,_ +//> using options -Werror -opt:inline:** -Wopt:none,_ // // compare -opt-warnings:none,at-inline-failed-summary diff --git a/test/files/neg/t11758.scala b/test/files/neg/t11758.scala index c6109ff684fc..027d4ca2d868 100644 --- a/test/files/neg/t11758.scala +++ b/test/files/neg/t11758.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation -Wunused:imports -Werror +//> using options -Xlint:deprecation -Wunused:imports -Werror import language.higherKinds diff --git a/test/files/neg/t11788.check b/test/files/neg/t11788.check new file mode 100644 index 000000000000..b378cd643cb5 --- /dev/null +++ b/test/files/neg/t11788.check @@ -0,0 +1,6 @@ +t11788/Foo.java:5: error: cannot find symbol + return java.lang.Integer.valueOf(42); + ^ + symbol: variable lang + location: variable java of type String +1 error diff --git a/test/files/neg/t11788/Bar.scala b/test/files/neg/t11788/Bar.scala new file mode 100644 index 000000000000..01c1838abe21 --- /dev/null +++ b/test/files/neg/t11788/Bar.scala @@ -0,0 +1,3 @@ +object Bar extends App { + println(new Foo().test()) +} diff --git a/test/files/neg/t11788/Foo.java b/test/files/neg/t11788/Foo.java new file mode 100644 index 000000000000..22167e26a5f4 --- /dev/null +++ b/test/files/neg/t11788/Foo.java @@ -0,0 +1,7 @@ +public class Foo { + private String java; + + public java.lang.Integer test() { + return java.lang.Integer.valueOf(42); + } +} diff --git a/test/files/neg/t11788b.check b/test/files/neg/t11788b.check new file mode 100644 index 000000000000..58db2408b5f4 --- /dev/null +++ b/test/files/neg/t11788b.check @@ -0,0 +1,4 @@ +t11788b/Foo.java:5: error: incompatible types: java.lang.Integer cannot be converted to java.lang.Integer + return Integer.valueOf(42); + ^ +1 error diff --git a/test/files/neg/t11788b/Bar.scala b/test/files/neg/t11788b/Bar.scala new file mode 100644 index 000000000000..01c1838abe21 --- /dev/null +++ b/test/files/neg/t11788b/Bar.scala @@ -0,0 +1,3 @@ +object Bar extends App { + println(new Foo().test()) +} diff --git a/test/files/neg/t11788b/Foo.java b/test/files/neg/t11788b/Foo.java new file mode 100644 index 000000000000..802929d7fc92 --- /dev/null +++ b/test/files/neg/t11788b/Foo.java @@ -0,0 +1,7 @@ +public class Foo { + private String java; + + public java.lang.Integer test() { + return Integer.valueOf(42); + } +} diff --git a/test/files/neg/t11788b/java.java b/test/files/neg/t11788b/java.java new file mode 100644 index 000000000000..2301bc90a177 --- /dev/null +++ b/test/files/neg/t11788b/java.java @@ -0,0 +1,7 @@ + +public class java { + public static class lang { + public static class Integer { + } + } +} diff --git a/test/files/neg/t11921-alias.check b/test/files/neg/t11921-alias.check index 62cb30931f84..ca9812924487 100644 --- a/test/files/neg/t11921-alias.check +++ b/test/files/neg/t11921-alias.check @@ -3,25 +3,43 @@ it is both defined in the enclosing object O and inherited in the enclosing clas In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.TT`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t2.O.D.n.x def n(x: TT) = x // ambiguous ^ +t11921-alias.scala:27: error: in Scala 3 (or with -Xsource-features:no-infer-structural), value a will no longer have a structural type: t3.A[B.this.c.type]{def n: t3.Context} + members that can be accessed with a reflective call: def n: t3.Context +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t3.B.a + val a = new A[c.type](c) { + ^ t11921-alias.scala:38: error: reference to c is ambiguous; it is both defined in the enclosing class B and inherited in the enclosing anonymous class as value c (defined in class A) In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.c`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t4.B.a def n = c // ambiguous ^ +t11921-alias.scala:37: error: in Scala 3 (or with -Xsource-features:no-infer-structural), value a will no longer have a structural type: t4.A[t4.Context]{def n: t4.Context} + members that can be accessed with a reflective call: def n: t4.Context +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t4.B.a + val a = new A(c) { + ^ +t11921-alias.scala:47: error: in Scala 3 (or with -Xsource-features:no-infer-structural), method f will no longer have a structural type: t5.K[t.type]{def test: t5.TT} + members that can be accessed with a reflective call: def test: t5.TT +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t5.C.f + def f(t: TT) = new K[t.type](t) { + ^ t11921-alias.scala:57: error: reference to name is ambiguous; it is both defined in the enclosing method m and inherited in the enclosing anonymous class as value name (defined in class C) In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.name`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t6.Test.m println(name) ^ @@ -30,8 +48,8 @@ it is both defined in the enclosing method m and inherited in the enclosing anon In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.name`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=t7.Test.m println(name) ^ -4 errors +7 errors diff --git a/test/files/neg/t11921-alias.scala b/test/files/neg/t11921-alias.scala index fab5ae9badc2..2e4131633082 100644 --- a/test/files/neg/t11921-alias.scala +++ b/test/files/neg/t11921-alias.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xsource:3 +//> using options -Werror -Xsource:3 object t1 { class C[T] { type TT = T } diff --git a/test/files/neg/t11921.check b/test/files/neg/t11921.check index e66a402a1e40..2a5dac20107e 100644 --- a/test/files/neg/t11921.check +++ b/test/files/neg/t11921.check @@ -8,7 +8,7 @@ it is both defined in the enclosing method lazyMap and inherited in the enclosin In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.coll`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C.lazyMap def iterator = coll.iterator.map(f) // coll is ambiguous ^ diff --git a/test/files/neg/t11921.scala b/test/files/neg/t11921.scala index 91093f3e7443..fe3f4fa2bfe2 100644 --- a/test/files/neg/t11921.scala +++ b/test/files/neg/t11921.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 class C { def lazyMap[A, B](coll: Iterable[A], f: A => B) = diff --git a/test/files/neg/t11921b.check b/test/files/neg/t11921b.check index c223004a3048..a6d2e0931f97 100644 --- a/test/files/neg/t11921b.check +++ b/test/files/neg/t11921b.check @@ -6,7 +6,7 @@ it is both defined in the enclosing object Test and inherited in the enclosing c In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.x`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test1.Test.D println(x) // error ^ @@ -15,7 +15,7 @@ it is both defined in the enclosing object Test and inherited in the enclosing a In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.x`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test1.Test.f println(x) // error ^ @@ -24,7 +24,7 @@ it is both defined in the enclosing method c and inherited in the enclosing anon In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.y`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test2.c println(y) // error ^ @@ -33,7 +33,7 @@ it is both defined in the enclosing method c and inherited in the enclosing clas In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `E.this.y`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test3.c.E.F println(y) // error ^ @@ -42,7 +42,7 @@ it is both defined in the enclosing package and inherited in the enclosi In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.global`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D println(global) // error ^ @@ -51,7 +51,7 @@ it is both defined in the enclosing object Uhu and inherited in the enclosing cl In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `C.this.x`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test5.Uhu.C.Inner.t def t = x // ambiguous, message mentions parent B ^ @@ -60,7 +60,7 @@ it is both defined in the enclosing class C and inherited in the enclosing trait In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.a`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test6.C.J.t val t = a // error ^ @@ -69,7 +69,7 @@ it is both defined in the enclosing object test10 and inherited in the enclosing In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.lo`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test10.C.v def v = t(lo) // error ^ diff --git a/test/files/neg/t11921b.scala b/test/files/neg/t11921b.scala index bf397ffcfadf..b30c52766c46 100644 --- a/test/files/neg/t11921b.scala +++ b/test/files/neg/t11921b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xsource:3 +//> using options -Werror -Xsource:3 object test1 { @@ -18,7 +18,7 @@ object test1 { } object test2 { - def c(y: Float) = { + def c(y: Float): AnyRef { val y: Int } = { class D { val y = 2 } diff --git a/test/files/neg/t11921c.scala b/test/files/neg/t11921c.scala index 3b38fa6c9520..280cd3eabc42 100644 --- a/test/files/neg/t11921c.scala +++ b/test/files/neg/t11921c.scala @@ -1,4 +1,4 @@ -// scalac: -Wconf:msg=legacy-binding:s -Xsource:3 +//> using options -Wconf:msg=legacy-binding:s -Xsource:3 class C { def lazyMap[A, B](coll: Iterable[A], f: A => B) = diff --git a/test/files/neg/t11938.scala b/test/files/neg/t11938.scala index b0b2b2e8348d..7c8c5bedb746 100644 --- a/test/files/neg/t11938.scala +++ b/test/files/neg/t11938.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror class Test { val a: Nil.type = (Vector(): Any) match { case n @ Nil => n } // error diff --git a/test/files/neg/t11952.scala b/test/files/neg/t11952.scala index 8a7b54498464..c24f18689ef4 100644 --- a/test/files/neg/t11952.scala +++ b/test/files/neg/t11952.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Xmaxwarns 0 +//> using options -Werror -Xlint -Xmaxwarns 0 // // nowarn should mean no warnings are emitted, // irrespective of other flags, and also no diff --git a/test/files/neg/t11952b.scala b/test/files/neg/t11952b.scala index 573def21c87a..e3d68fe62970 100644 --- a/test/files/neg/t11952b.scala +++ b/test/files/neg/t11952b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Vdebug +//> using options -Werror -Xlint -Vdebug // // Multiple errors at a location are shown under debug. // diff --git a/test/files/neg/t11962.scala b/test/files/neg/t11962.scala index db9c340ce2e2..9dd109f3e3e0 100644 --- a/test/files/neg/t11962.scala +++ b/test/files/neg/t11962.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror -Ystop-after:refchecks +//> using options -Xlint -Werror -Ystop-after:refchecks trait T extends Any { def f = println() } diff --git a/test/files/neg/t12026.scala b/test/files/neg/t12026.scala index e4dd952672f3..67e3ce7cbd50 100644 --- a/test/files/neg/t12026.scala +++ b/test/files/neg/t12026.scala @@ -1,4 +1,4 @@ -//scalac: -Wvalue-discard -Werror +//> using options -Wvalue-discard -Werror import annotation._ diff --git a/test/files/neg/t12071.check b/test/files/neg/t12071.check index 88198baf3274..82e968690ea9 100644 --- a/test/files/neg/t12071.check +++ b/test/files/neg/t12071.check @@ -7,34 +7,24 @@ This can be achieved by adding the import clause 'import scala.language.postfixO or by setting the compiler option -language:postfixOps. See the Scaladoc for value scala.language.postfixOps for a discussion why the feature needs to be explicitly enabled. -Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. `c c` i ^ -t12071.scala:20: warning: Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +t12071.scala:20: warning: Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. + 2 ^ -t12071.scala:25: warning: Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +t12071.scala:25: warning: Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. + 1 ^ -t12071.scala:28: warning: Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +t12071.scala:28: warning: Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. `test-1` + `test-2` ^ -t12071.scala:31: warning: Line starts with an operator that in future -will be taken as an infix expression continued from the previous line. -To force the previous interpretation as a separate statement, -add an explicit `;`, add an empty line, or remove spaces after the operator. +t12071.scala:31: warning: Lines starting with an operator are taken as an infix expression continued from the previous line in Scala 3 (or with -Xsource-features:leading-infix). +To force the current interpretation as a separate statement, add an explicit `;`, add an empty line, or remove spaces after the operator. `compareTo` (2 - 1) ^ 4 warnings diff --git a/test/files/neg/t12071.scala b/test/files/neg/t12071.scala index f3f9529c147b..9bc0e851ea39 100644 --- a/test/files/neg/t12071.scala +++ b/test/files/neg/t12071.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Xmigration:2.13 +//> using options -Werror -Xlint -Xmigration:2.13 class C { def `c c`(n: Int): Int = n + 1 diff --git a/test/files/neg/t12074.check b/test/files/neg/t12074.check new file mode 100644 index 000000000000..0604703cd710 --- /dev/null +++ b/test/files/neg/t12074.check @@ -0,0 +1,9 @@ +t12074.scala:5: warning: private val range in class C is never used + private val range = -700 to 700 + ^ +t12074.scala:6: warning: private val rangely in class C is never used + private val rangely = -700.to(700) + ^ +error: No warnings can be incurred under -Werror. +2 warnings +1 error diff --git a/test/files/neg/t12074.scala b/test/files/neg/t12074.scala new file mode 100644 index 000000000000..f94a138a8a1e --- /dev/null +++ b/test/files/neg/t12074.scala @@ -0,0 +1,7 @@ + +//> using options -Xlint -Werror -Yrangepos:false + +class C { + private val range = -700 to 700 + private val rangely = -700.to(700) +} diff --git a/test/files/neg/t12098.scala b/test/files/neg/t12098.scala index 78de84978a16..37454bce88a5 100644 --- a/test/files/neg/t12098.scala +++ b/test/files/neg/t12098.scala @@ -1,5 +1,5 @@ //xlint supersedes default Wconf setting, which is ws warn-summary for deprecation -//scalac: -Werror -Wconf:cat=lint-missing-interpolator:ws -Xlint +//> using options -Werror -Wconf:cat=lint-missing-interpolator:ws -Xlint class C(i: Int) { def p() = println("hi $i") diff --git a/test/files/neg/t12134/sample_2.scala b/test/files/neg/t12134/sample_2.scala index b1de02a551bc..5d3b9aadb960 100644 --- a/test/files/neg/t12134/sample_2.scala +++ b/test/files/neg/t12134/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:unplugged -d testy.jar +//> using options -Xplugin:. -Xplugin-require:unplugged -d testy.jar package sample // The unplugged plugin pre-emptively creates a read-only testy.jar. diff --git a/test/files/neg/t1215.scala b/test/files/neg/t1215.scala index ab6a6d976dd6..82480b9d3f6a 100644 --- a/test/files/neg/t1215.scala +++ b/test/files/neg/t1215.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object Test { val x = 1 += 1 diff --git a/test/files/neg/t12159/s.scala b/test/files/neg/t12159/s.scala index b8ec52070d07..9a32043d5a0b 100644 --- a/test/files/neg/t12159/s.scala +++ b/test/files/neg/t12159/s.scala @@ -1,4 +1,4 @@ -// javaVersion: 17+ +//> using jvm 17+ package p diff --git a/test/files/neg/t12159b/s_2.scala b/test/files/neg/t12159b/s_2.scala index ec5f40dba180..4569ad1458fb 100644 --- a/test/files/neg/t12159b/s_2.scala +++ b/test/files/neg/t12159b/s_2.scala @@ -1,4 +1,4 @@ -// javaVersion: 17+ +//> using jvm 17+ package p diff --git a/test/files/neg/t12159c/s_2.scala b/test/files/neg/t12159c/s_2.scala index ec9c445cad42..caba28ddab05 100644 --- a/test/files/neg/t12159c/s_2.scala +++ b/test/files/neg/t12159c/s_2.scala @@ -1,5 +1,5 @@ -// javaVersion: 17+ -// scalac: -Werror +//> using jvm 17+ +//> using options -Werror package p class C { diff --git a/test/files/neg/t12159d/t.scala b/test/files/neg/t12159d/t.scala index e57c9cd62ddc..89410685ee97 100644 --- a/test/files/neg/t12159d/t.scala +++ b/test/files/neg/t12159d/t.scala @@ -1,5 +1,5 @@ -// javaVersion: 17+ -// scalac: -Werror +//> using jvm 17+ +//> using options -Werror package p class C { diff --git a/test/files/neg/t12159e/t.scala b/test/files/neg/t12159e/t.scala index 1d5810a09f85..06b5a92391af 100644 --- a/test/files/neg/t12159e/t.scala +++ b/test/files/neg/t12159e/t.scala @@ -1,5 +1,5 @@ -// javaVersion: 17+ -// scalac: -Werror +//> using jvm 17+ +//> using options -Werror package p class C { diff --git a/test/files/neg/t12159f/t.scala b/test/files/neg/t12159f/t.scala index 1d5810a09f85..06b5a92391af 100644 --- a/test/files/neg/t12159f/t.scala +++ b/test/files/neg/t12159f/t.scala @@ -1,5 +1,5 @@ -// javaVersion: 17+ -// scalac: -Werror +//> using jvm 17+ +//> using options -Werror package p class C { diff --git a/test/files/neg/t12159g/t.scala b/test/files/neg/t12159g/t.scala index f92009287f1b..a1cbf521e0e1 100644 --- a/test/files/neg/t12159g/t.scala +++ b/test/files/neg/t12159g/t.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint package p class T { def n(a: X) = a match { case _: Y => 42 } diff --git a/test/files/neg/t12199.scala b/test/files/neg/t12199.scala index a9ceb3d07c41..822b86483688 100644 --- a/test/files/neg/t12199.scala +++ b/test/files/neg/t12199.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint class C { val a: IndexedSeq[Int] = Array(1, 2, 3) diff --git a/test/files/neg/t12226.check b/test/files/neg/t12226.check new file mode 100644 index 000000000000..444d882ff6b3 --- /dev/null +++ b/test/files/neg/t12226.check @@ -0,0 +1,18 @@ +t12226.scala:6: warning: Implicit resolves to enclosing class Elvis; the conversion adds a member of AnyRef to value a + implicit class Elvis[A](alt: => A) { def ?:(a: A): A = if (a ne null) a else alt } // warn + ^ +t12226.scala:9: warning: Implicit resolves to enclosing method f; the conversion adds a member of AnyRef to value a + implicit def f[A](a: A): String = if (a ne null) a else "nope" // warn + ^ +t12226.scala:9: warning: Implicit resolves to enclosing method f + implicit def f[A](a: A): String = if (a ne null) a else "nope" // warn + ^ +t12226.scala:13: warning: Implicit resolves to enclosing method f; the conversion adds a member of AnyRef to result of method idt + implicit def f[A](a: A): String = if (idt(x = a) ne null) "yup" else "nope" // warn + ^ +t12226.scala:25: warning: Implicit resolves to enclosing class StringOps; the enrichment wraps value s + def normal: String = s.crazy.crazy // warn + ^ +error: No warnings can be incurred under -Werror. +5 warnings +1 error diff --git a/test/files/neg/t12226.scala b/test/files/neg/t12226.scala new file mode 100644 index 000000000000..0cd38ca13d19 --- /dev/null +++ b/test/files/neg/t12226.scala @@ -0,0 +1,43 @@ +//> using options -Xlint:implicit-recursion -Werror + +import language.implicitConversions + +object X { + implicit class Elvis[A](alt: => A) { def ?:(a: A): A = if (a ne null) a else alt } // warn +} +object Y { + implicit def f[A](a: A): String = if (a ne null) a else "nope" // warn +} +object YY { + def idt[A](n: Int = 1, x: A): A = x + implicit def f[A](a: A): String = if (idt(x = a) ne null) "yup" else "nope" // warn +} +object Z { + implicit class StringOps(val s: String) extends AnyVal { + def crazy: String = s.reverse + def normal: String = s.crazy.crazy // nowarn value class + def join(other: String): String = crazy + other.crazy // nowarn + } +} +object ZZ { + implicit class StringOps(s: String) { + def crazy: String = s.reverse + def normal: String = s.crazy.crazy // warn + def join(other: String): String = crazy + other.crazy // nowarn + } +} + +object ZZZ { + class C { def f: C = this } + implicit class E(c: C) { + def bar: Int = c.f.bar // nowarn + } +} + +object sd893 { + case class C(a: Int, b: Int) { + implicit class Enrich(c2: C) { + def foo: C = c2.copy(b = 0).foo // nowarn + } + } +} diff --git a/test/files/neg/t12237.scala b/test/files/neg/t12237.scala index 480634cf86f6..0a8b27675fb8 100644 --- a/test/files/neg/t12237.scala +++ b/test/files/neg/t12237.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed trait PathAndQuery sealed trait Path extends PathAndQuery sealed trait Query extends PathAndQuery diff --git a/test/files/neg/t1224.scala b/test/files/neg/t1224.scala index 9e638b14b853..64b76a04b3a7 100644 --- a/test/files/neg/t1224.scala +++ b/test/files/neg/t1224.scala @@ -1,4 +1,4 @@ -// scalac: -Ybreak-cycles +//> using options -Ybreak-cycles // trait C[T] {} diff --git a/test/files/neg/t12240.scala b/test/files/neg/t12240.scala index c1a3b068c5f3..bebd05e8376a 100644 --- a/test/files/neg/t12240.scala +++ b/test/files/neg/t12240.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +//> using options -Xfatal-warnings -Xlint:strict-unsealed-patmat // object Test { diff --git a/test/files/neg/t12258.check b/test/files/neg/t12258.check new file mode 100644 index 000000000000..479826cac2af --- /dev/null +++ b/test/files/neg/t12258.check @@ -0,0 +1,9 @@ +sample_2.scala:2: warning: Something is wrong. +package sample + ^ +sample_2.scala:5: More is broken. +object Sample extends App { + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/t12258/ploogin_1.scala b/test/files/neg/t12258/ploogin_1.scala new file mode 100644 index 000000000000..8e4d0c8e460d --- /dev/null +++ b/test/files/neg/t12258/ploogin_1.scala @@ -0,0 +1,36 @@ + +package t12258 + +import scala.tools.nsc.{Global, Phase} +import scala.tools.nsc.plugins.{Plugin, PluginComponent} +import scala.tools.nsc.Reporting.WarningCategory.OtherDebug +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global) extends Plugin { + import global._ + + val name = "ploogin" + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + override val runsBefore = List("erasure") + val runsAfter = List("typer") + val phaseName = Ploogin.this.name + override def description = "A sample phase that emits warnings." + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit): Unit = { + currentRun.reporting.warning(unit.body.pos, "Something is wrong.", OtherDebug, site="ploog", Nil) + unit.body match { + case PackageDef(_, stats) => + currentRun.reporting.warning(stats.head.pos, "More is broken.", OtherDebug, site="ploog", Nil) + } + } + } + } +} diff --git a/test/files/neg/t12258/sample_2.scala b/test/files/neg/t12258/sample_2.scala new file mode 100644 index 000000000000..2ecd706a86de --- /dev/null +++ b/test/files/neg/t12258/sample_2.scala @@ -0,0 +1,6 @@ +//> using options -Wconf:cat=other-debug&msg=More:i -Werror -Xplugin:. -Xplugin-require:ploogin +package sample + +// just a sample that is compiled with the sample plugin enabled +object Sample extends App { +} diff --git a/test/files/neg/t12258/scalac-plugin.xml b/test/files/neg/t12258/scalac-plugin.xml new file mode 100644 index 000000000000..b0b48a4d2285 --- /dev/null +++ b/test/files/neg/t12258/scalac-plugin.xml @@ -0,0 +1,5 @@ + + ploogin + t12258.Ploogin + + diff --git a/test/files/neg/t12304.scala b/test/files/neg/t12304.scala index 1f6c3e8b715e..0e40e8fa140f 100644 --- a/test/files/neg/t12304.scala +++ b/test/files/neg/t12304.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // variant of pos/t12304 // that does warn as desired diff --git a/test/files/neg/t12320.check b/test/files/neg/t12320.check new file mode 100644 index 000000000000..cae2ed0f80b1 --- /dev/null +++ b/test/files/neg/t12320.check @@ -0,0 +1,21 @@ +t12320.scala:4: warning: a type was inferred to be `Any`; this may indicate a programming error. + def f = Option.empty[Int].contains("") || false + ^ +t12320.scala:5: warning: a type was inferred to be `Any`; this may indicate a programming error. + def g(other: Option[Int]) = other.contains("") || false + ^ +t12320.scala:6: warning: a type was inferred to be `Any`; this may indicate a programming error. + def any = Option.empty[Int].contains("") + ^ +t12320.scala:11: warning: a type was inferred to be `Any`; this may indicate a programming error. + def f = List(1 -> "a", 2 -> "b", 3) map { p => val (a,b) = p; a + " -> " + b } + ^ +t12320.scala:17: warning: a type was inferred to be `Any`; this may indicate a programming error. + def test = review.f(42) + ^ +t12320.scala:11: warning: method any2stringadd in object Predef is deprecated (since 2.13.0): Implicit injection of + is deprecated. Convert to String to call + + def f = List(1 -> "a", 2 -> "b", 3) map { p => val (a,b) = p; a + " -> " + b } + ^ +error: No warnings can be incurred under -Werror. +6 warnings +1 error diff --git a/test/files/neg/t12320.scala b/test/files/neg/t12320.scala new file mode 100644 index 000000000000..6455c7443b74 --- /dev/null +++ b/test/files/neg/t12320.scala @@ -0,0 +1,18 @@ +//> using options -Werror -Xlint:infer-any,deprecation +// +trait T { + def f = Option.empty[Int].contains("") || false + def g(other: Option[Int]) = other.contains("") || false + def any = Option.empty[Int].contains("") +} + +trait `t9211 via 5898` { + + def f = List(1 -> "a", 2 -> "b", 3) map { p => val (a,b) = p; a + " -> " + b } +} + +object review { def f(x: String) = 0; def f[T >: String](x: T) = 1 } + +trait review { + def test = review.f(42) +} diff --git a/test/files/neg/t12326.scala b/test/files/neg/t12326.scala index 233438250055..8515393c8f67 100644 --- a/test/files/neg/t12326.scala +++ b/test/files/neg/t12326.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports -Wconf:site=p.T:s +//> using options -Werror -Wunused:imports -Wconf:site=p.T:s package p diff --git a/test/files/neg/t12326b.scala b/test/files/neg/t12326b.scala index 6e261b0f257d..3b8054fd007b 100644 --- a/test/files/neg/t12326b.scala +++ b/test/files/neg/t12326b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports -Wconf:site=p.T:s,origin=scala.collection.mutable.Map:s,origin=scala.collection.mutable.Set:s +//> using options -Werror -Wunused:imports -Wconf:site=p.T:s,origin=scala.collection.mutable.Map:s,origin=scala.collection.mutable.Set:s package p diff --git a/test/files/neg/t12326c.scala b/test/files/neg/t12326c.scala index 22652417e0d1..37f8c86f1d60 100644 --- a/test/files/neg/t12326c.scala +++ b/test/files/neg/t12326c.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports -Wconf:origin=scala.collection.mutable.*:s +//> using options -Werror -Wunused:imports -Wconf:origin=scala.collection.mutable.*:s package p diff --git a/test/files/neg/t12408.scala b/test/files/neg/t12408.scala index ab5879ae5c6d..fc6ffa9899f3 100644 --- a/test/files/neg/t12408.scala +++ b/test/files/neg/t12408.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package t12408 { class Renderer[A] diff --git a/test/files/neg/t12414.scala b/test/files/neg/t12414.scala index 649fbb23e5b4..187f701d6015 100644 --- a/test/files/neg/t12414.scala +++ b/test/files/neg/t12414.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed trait Trait1 sealed trait Trait2 diff --git a/test/files/neg/t12414b/b_2.scala b/test/files/neg/t12414b/b_2.scala index 87f5694346eb..39f17177de45 100644 --- a/test/files/neg/t12414b/b_2.scala +++ b/test/files/neg/t12414b/b_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test extends App { def test(x: Trait1): Unit = diff --git a/test/files/neg/t12433.scala b/test/files/neg/t12433.scala index c1975ca848db..885b49ff3646 100644 --- a/test/files/neg/t12433.scala +++ b/test/files/neg/t12433.scala @@ -1,4 +1,4 @@ -// scalac: -Wunused:nowarn +//> using options -Wunused:nowarn import annotation.nowarn object T { @deprecated def f = 1 diff --git a/test/files/neg/t12441.check b/test/files/neg/t12441.check index 44ed77a77ec1..1636980c4879 100644 --- a/test/files/neg/t12441.check +++ b/test/files/neg/t12441.check @@ -1,3 +1,6 @@ +t12441.scala:6: warning: a type was inferred to be `Any`; this may indicate a programming error. + def f: Any = Option.empty[String].contains(1234) + ^ t12441.scala:7: warning: a type was inferred to be `Any`; this may indicate a programming error. def g = Option.empty[String].contains(1234) ^ @@ -17,5 +20,5 @@ t12441.scala:14: warning: a type was inferred to be `Any`; this may indicate a p def peskier = p == (42, List(17, "")) ^ error: No warnings can be incurred under -Werror. -5 warnings +6 warnings 1 error diff --git a/test/files/neg/t12441.scala b/test/files/neg/t12441.scala index 86b9eec048e4..900e748d84c6 100644 --- a/test/files/neg/t12441.scala +++ b/test/files/neg/t12441.scala @@ -1,5 +1,5 @@ -// scalac: -Xlint -Werror +//> using options -Werror -Xlint trait T { def k(u: => Unit): Unit = u diff --git a/test/files/neg/t12494.scala b/test/files/neg/t12494.scala index 4d2f27e99b85..a54f436aba99 100644 --- a/test/files/neg/t12494.scala +++ b/test/files/neg/t12494.scala @@ -1,4 +1,4 @@ -// scalac: -Ylog:superaccessors -Ydebug +//> using options -Ylog:superaccessors -Ydebug object X { def m: Int = { trait C { diff --git a/test/files/neg/t12495.check b/test/files/neg/t12495.check index 52c058692538..bf735c969070 100644 --- a/test/files/neg/t12495.check +++ b/test/files/neg/t12495.check @@ -1,12 +1,12 @@ -t12495.scala:4: warning: discarded non-Unit value of type (Int, Int) - def g = f(42, 27) - ^ t12495.scala:4: warning: adapted the argument list to expected Unit type: arguments will be discarded signature: Function1.apply(v1: T1): R given arguments: 42, 27 after adaptation: Function1((42, 27): Unit) def g = f(42, 27) ^ +t12495.scala:4: warning: discarded non-Unit value of type (Int, Int) + def g = f(42, 27) + ^ error: No warnings can be incurred under -Werror. 2 warnings 1 error diff --git a/test/files/neg/t12495.scala b/test/files/neg/t12495.scala index 5be5e3796c22..5d24b25a486f 100644 --- a/test/files/neg/t12495.scala +++ b/test/files/neg/t12495.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:arg-discard,adapted-args -Wvalue-discard +//> using options -Werror -Xlint:arg-discard,adapted-args -Wvalue-discard class C { val f = (u: Unit) => println(s"[$u]") def g = f(42, 27) diff --git a/test/files/neg/t12499.scala b/test/files/neg/t12499.scala index 91f397f12b24..be5e60cbe1d8 100644 --- a/test/files/neg/t12499.scala +++ b/test/files/neg/t12499.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Ystop-after:patmat -Ypatmat-exhaust-depth 30 +//> using options -Werror -Ystop-after:patmat -Ypatmat-exhaust-depth 30 sealed trait Phantom[A] {} object Phantom { diff --git a/test/files/neg/t12513/predefer_2.scala b/test/files/neg/t12513/predefer_2.scala index 6688ec5acbad..1872ff9d82fe 100644 --- a/test/files/neg/t12513/predefer_2.scala +++ b/test/files/neg/t12513/predefer_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:p.MyPredef,scala.Predef,scala +//> using options -Yimports:p.MyPredef,scala.Predef,scala package p { object Test extends App { diff --git a/test/files/neg/t12513b.scala b/test/files/neg/t12513b.scala index 51038b82a06d..c4dc17f02a7f 100644 --- a/test/files/neg/t12513b.scala +++ b/test/files/neg/t12513b.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xsource:3 +//> using options -Werror -Xsource:3 object X { type T = annotation.tailrec } object Y { type T = annotation.tailrec } diff --git a/test/files/neg/t12543.scala b/test/files/neg/t12543.scala index 3bb916938105..6d4cd1a540fa 100644 --- a/test/files/neg/t12543.scala +++ b/test/files/neg/t12543.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -release 8 +//> using options -Werror -release 8 import scala.jdk.CollectionConverters._ //import jdk.CollectionConverters._ // scala/bug/issues/12566 diff --git a/test/files/neg/t12565.scala b/test/files/neg/t12565.scala index 6336f90a4dd4..f9d9b0b76231 100644 --- a/test/files/neg/t12565.scala +++ b/test/files/neg/t12565.scala @@ -1,5 +1,5 @@ -// scalac: -Werror --release 8 -// javaVersion: 9+ +//> using options -Werror --release 8 +//> using jvm 9+ class C { def f = new java.time.Instant diff --git a/test/files/neg/t12590.scala b/test/files/neg/t12590.scala index 059391320087..2339f3411412 100644 --- a/test/files/neg/t12590.scala +++ b/test/files/neg/t12590.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:locals +//> using options -Werror -Wunused:locals class C { def unusedLocal = { val a = 27 diff --git a/test/files/neg/t12591.scala b/test/files/neg/t12591.scala index ad8e91e5fa54..c66259aa9393 100644 --- a/test/files/neg/t12591.scala +++ b/test/files/neg/t12591.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Wunused:synthetics -trait Context[A] +//> using options -Werror -Wunused:synthetics +trait Context[A] { def m(a: A): A = a } // Context has a member, so warn if unused object Example { def g[A: Context] = f diff --git a/test/files/neg/t12647/Macro_1.scala b/test/files/neg/t12647/Macro_1.scala index 748657682eec..da6431cd2ae2 100644 --- a/test/files/neg/t12647/Macro_1.scala +++ b/test/files/neg/t12647/Macro_1.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import scala.reflect.macros.blackbox.Context diff --git a/test/files/neg/t12647/Resolve_2.scala b/test/files/neg/t12647/Resolve_2.scala index dab65c6a310b..97cc4c354007 100644 --- a/test/files/neg/t12647/Resolve_2.scala +++ b/test/files/neg/t12647/Resolve_2.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import language.experimental.macros diff --git a/test/files/neg/t12647/Test_3.scala b/test/files/neg/t12647/Test_3.scala index 152e5ddc4aa4..e2fc19f46853 100644 --- a/test/files/neg/t12647/Test_3.scala +++ b/test/files/neg/t12647/Test_3.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 object Test extends App { val resolver = new ValueResolver diff --git a/test/files/neg/t12648/LogConfig_2.scala b/test/files/neg/t12648/LogConfig_2.scala index 13d621ce0358..c8ff61d95df8 100644 --- a/test/files/neg/t12648/LogConfig_2.scala +++ b/test/files/neg/t12648/LogConfig_2.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xlint -Xsource:3 +//> using options -Werror -Xlint -Xsource:3 import annotation.* diff --git a/test/files/neg/t12664.check b/test/files/neg/t12664.check new file mode 100644 index 000000000000..e3315946e96c --- /dev/null +++ b/test/files/neg/t12664.check @@ -0,0 +1,11 @@ +t12664.scala:4: warning: side-effecting nullary methods are discouraged: suggest defining as `def f()` instead [quickfixable] + def f: Unit = 42 + ^ +t12664.scala:4: warning: a pure expression does nothing in statement position + def f: Unit = 42 + ^ +warning: 1 deprecation (since 1.0); re-run enabling -deprecation for details, or try -help +warning: 1 lint warning; change -Wconf for cat=lint to display individual messages +error: No warnings can be incurred under -Werror. +4 warnings +1 error diff --git a/test/files/neg/t12664.scala b/test/files/neg/t12664.scala new file mode 100644 index 000000000000..8b965d64ea44 --- /dev/null +++ b/test/files/neg/t12664.scala @@ -0,0 +1,12 @@ +//> using options -Wconf:cat=lint-missing-interpolator:ws,cat=deprecation:ws -Werror -Xlint + +class C { + def f: Unit = 42 + + def oops = "$f" + + @deprecated("old stuff", since="1.0") + def old = 17 + + def stale = old +} diff --git a/test/files/neg/t12690b.scala b/test/files/neg/t12690b.scala index 30b6ccab7604..95cace46d190 100644 --- a/test/files/neg/t12690b.scala +++ b/test/files/neg/t12690b.scala @@ -1,5 +1,5 @@ -// scalac: -Wunused:imports -Werror +//> using options -Wunused:imports -Werror object X { val v = 27 diff --git a/test/files/neg/t12704.scala b/test/files/neg/t12704.scala index db43b888d029..d481cc21635e 100644 --- a/test/files/neg/t12704.scala +++ b/test/files/neg/t12704.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class Out { sealed trait P case class K(x: Int) extends P diff --git a/test/files/neg/t12720.check b/test/files/neg/t12720.check deleted file mode 100644 index 603ba26094e4..000000000000 --- a/test/files/neg/t12720.check +++ /dev/null @@ -1,40 +0,0 @@ -t12720.scala:15: error: missing argument list for method f*** in class D*** -Unapplied methods are only converted to functions when a function type is expected. -You can make this conversion explicit by writing `f _` or `f(_)` instead of `f`. - def f = d.f - ^ -t12720.scala:10: warning: private constructor in class Test*** is never used - private def this(stuff: Int) = this() - ^ -t12720.scala:20: warning: local method m*** in method forgone*** is never used - def m = 17 - ^ -t12720.scala:21: warning: local object j*** in method forgone*** is never used - object j - ^ -t12720.scala:22: warning: local var totally*** in method forgone*** is never used - var totally = 27 - ^ -t12720.scala:24: warning: local val z*** in method forgone*** is never used - val z = unset - ^ -t12720.scala:28: warning: private var misbegotten*** in class Test*** is never used - private var misbegotten: Int = 42 - ^ -t12720.scala:30: warning: private var forgotten (forgotten_=***) in class Test*** is never updated: consider using immutable val - private var forgotten: Int = 42 - ^ -t12720.scala:12: warning: private class Subtle*** in class Test*** is never used - private class Subtle - ^ -t12720.scala:23: warning: local var unset*** in method forgone*** is never updated: consider using immutable val - var unset: Int = 0 - ^ -t12720.scala:16: warning: parameter x*** in method g*** is never used - def g(x: Int) = println("error") - ^ -t12720.scala:25: warning: parameter y*** in anonymous function is never used - for (x <- Option(42); y <- Option(27) if x < i; res = x - y) yield res - ^ -11 warnings -1 error diff --git a/test/files/neg/t12720.scala b/test/files/neg/t12720.scala deleted file mode 100644 index 48c659065c4f..000000000000 --- a/test/files/neg/t12720.scala +++ /dev/null @@ -1,32 +0,0 @@ -// scalac: -uniqid -Werror -Wunused -// hide: #\d+ -class C { - def f(x: Int) = "" -} -class D extends C { - def f(x: String) = "" -} -final class Test { - private def this(stuff: Int) = this() - - private class Subtle - - val d = new D - def f = d.f - def g(x: Int) = println("error") - - // -Vprint shows two symbols `y` - def forgone(i: Int) = { - def m = 17 - object j - var totally = 27 - var unset: Int = 0 - val z = unset - for (x <- Option(42); y <- Option(27) if x < i; res = x - y) yield res - } - - private var misbegotten: Int = 42 - def touch() = misbegotten = 17 - private var forgotten: Int = 42 - def fetch = forgotten -} diff --git a/test/files/neg/t12728.scala b/test/files/neg/t12728.scala index 6ccb0f19d639..3b2730b7add6 100644 --- a/test/files/neg/t12728.scala +++ b/test/files/neg/t12728.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint class C { val u = () diff --git a/test/files/neg/t12734.check b/test/files/neg/t12734.check new file mode 100644 index 000000000000..8b9eb155464c --- /dev/null +++ b/test/files/neg/t12734.check @@ -0,0 +1,12 @@ +[ERROR] [RangePosition(t12734.scala, 94, 94, 108)]: object AssertionErrer is not a member of package java.lang +did you mean AssertionError? +[ERROR] [RangePosition(t12734.scala, 176, 182, 192)]: object connection is not a member of package scala +did you mean collection? +[WARNING] [RangePosition(t12734.scala, 110, 110, 125)]: Unused import +[WARNING] [RangePosition(t12734.scala, 127, 127, 133)]: Unused import +[WARNING] [RangePosition(t12734.scala, 167, 167, 168)]: Unused import +[WARNING] [RangePosition(t12734.scala, 193, 193, 194)]: Unused import +[WARNING] [RangePosition(t12734.scala, 397, 397, 403)]: Unused import +[WARNING] [RangePosition(t12734.scala, 489, 489, 494)]: Unused import +6 warnings +2 errors diff --git a/test/files/neg/t12734.scala b/test/files/neg/t12734.scala new file mode 100644 index 000000000000..cf159a93a46f --- /dev/null +++ b/test/files/neg/t12734.scala @@ -0,0 +1,32 @@ +//> using options -Xlint -Xreporter:scala.tools.partest.nest.PlainReporter + +import java.lang.{AssertionErrer, Integer => JInt, String, Thread} +import scala.annotation._ +import scala.connection._ + +trait T { + def t: Thread +} + +// these import infos are not seen in position order +// warnings are not sorted later +class C { + def f(): Int = { + def compute(): Int = { + import scala.concurrent.Future + //Future(42).get + 42 + } + compute() + } + import scala.util.matching.Regex + //def g: Regex = "(\\d+)".r + def g = "(\\d+)".r +} + +/* +Previous result shows the selectors with same range but different points. +[ERROR] [RangePosition(t12734.scala, 76, 83, 117)]: object AssertionErrer is not a member of package java.lang +did you mean AssertionError? +[WARNING] [RangePosition(t12734.scala, 76, 94, 117)]: Unused import +*/ diff --git a/test/files/neg/t12735a.check b/test/files/neg/t12735a.check index 9e9c1b325ff6..421d088e7274 100644 --- a/test/files/neg/t12735a.check +++ b/test/files/neg/t12735a.check @@ -1,6 +1,6 @@ -[ERROR] [RangePosition(t12735a.scala, 97, 97, 98)]: class B needs to be abstract. +[ERROR] [RangePosition(t12735a.scala, 104, 104, 105)]: class B needs to be abstract. Missing implementation for member of trait A: def x: String = ??? -[ERROR] [RangePosition(t12735a.scala, 123, 123, 127)]: covariant type T occurs in contravariant position in type T of value t +[ERROR] [RangePosition(t12735a.scala, 130, 130, 134)]: covariant type T occurs in contravariant position in type T of value t 2 errors diff --git a/test/files/neg/t12735a.scala b/test/files/neg/t12735a.scala index e6f998e098b6..67594fcf7a18 100644 --- a/test/files/neg/t12735a.scala +++ b/test/files/neg/t12735a.scala @@ -1,4 +1,4 @@ -// scalac: -Xreporter:scala.tools.partest.nest.PlainReporter +//> using options -Xreporter:scala.tools.partest.nest.PlainReporter trait A { def x: String diff --git a/test/files/neg/t12735b.check b/test/files/neg/t12735b.check index 2e8b8cf6ab79..6a5138333fe2 100644 --- a/test/files/neg/t12735b.check +++ b/test/files/neg/t12735b.check @@ -1,7 +1,7 @@ -[WARNING] [RangePosition(t12735b.scala, 112, 112, 113)]: private method m in class UnusedMethod is never used -[WARNING] [RangePosition(t12735b.scala, 216, 216, 217)]: private object X in object UnusedObject is never used -[WARNING] [RangePosition(t12735b.scala, 228, 228, 253)]: side-effecting nullary methods are discouraged: suggest defining as `def stuff to create a range()` instead -[WARNING] [RangePosition(t12735b.scala, 128, 132, 135)]: match may not be exhaustive. +[WARNING] [RangePosition(t12735b.scala, 119, 119, 120)]: private method m in class UnusedMethod is never used +[WARNING] [RangePosition(t12735b.scala, 223, 223, 224)]: private object X in object UnusedObject is never used +[WARNING] [RangePosition(t12735b.scala, 235, 235, 260)]: side-effecting nullary methods are discouraged: suggest defining as `def stuff to create a range()` instead +[WARNING] [RangePosition(t12735b.scala, 135, 139, 142)]: match may not be exhaustive. It would fail on the following input: List(_) [ERROR] [NoPosition]: No warnings can be incurred under -Werror. 4 warnings diff --git a/test/files/neg/t12735b.scala b/test/files/neg/t12735b.scala index a27496be6f21..3b8fa184005d 100644 --- a/test/files/neg/t12735b.scala +++ b/test/files/neg/t12735b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Xreporter:scala.tools.partest.nest.PlainReporter +//> using options -Werror -Xlint -Xreporter:scala.tools.partest.nest.PlainReporter class UnusedMethod { private def m: String = diff --git a/test/files/neg/t12735c.check b/test/files/neg/t12735c.check index 41e43646cce2..fcbb3b774ccd 100644 --- a/test/files/neg/t12735c.check +++ b/test/files/neg/t12735c.check @@ -1,20 +1,20 @@ -[WARNING] [RangePosition(t12735c.scala, 109, 109, 110)]: private val v in class UnusedVal is never used -[WARNING] [RangePosition(t12735c.scala, 207, 207, 208)]: private val v in class UnusedVals is never used -[WARNING] [RangePosition(t12735c.scala, 210, 210, 211)]: private val w in class UnusedVals is never used -[WARNING] [RangePosition(t12735c.scala, 213, 213, 214)]: private val x in class UnusedVals is never used -[WARNING] [RangePosition(t12735c.scala, 216, 216, 217)]: private val y in class UnusedVals is never used -[WARNING] [RangePosition(t12735c.scala, 219, 219, 220)]: private val z in class UnusedVals is never used -[WARNING] [RangePosition(t12735c.scala, 319, 319, 320)]: private val v in class UnusedIdents is never used -[WARNING] [RangePosition(t12735c.scala, 322, 322, 323)]: private val w in class UnusedIdents is never used -[WARNING] [RangePosition(t12735c.scala, 325, 325, 326)]: private val x in class UnusedIdents is never used -[WARNING] [RangePosition(t12735c.scala, 328, 328, 329)]: private val y in class UnusedIdents is never used -[WARNING] [RangePosition(t12735c.scala, 331, 331, 332)]: private val z in class UnusedIdents is never used -[WARNING] [RangePosition(t12735c.scala, 424, 424, 427)]: private type int in object UnusedAlias is never used -[WARNING] [RangePosition(t12735c.scala, 125, 129, 132)]: match may not be exhaustive. +[WARNING] [RangePosition(t12735c.scala, 116, 116, 117)]: private val v in class UnusedVal is never used +[WARNING] [RangePosition(t12735c.scala, 214, 214, 215)]: private val v in class UnusedVals is never used +[WARNING] [RangePosition(t12735c.scala, 217, 217, 218)]: private val w in class UnusedVals is never used +[WARNING] [RangePosition(t12735c.scala, 220, 220, 221)]: private val x in class UnusedVals is never used +[WARNING] [RangePosition(t12735c.scala, 223, 223, 224)]: private val y in class UnusedVals is never used +[WARNING] [RangePosition(t12735c.scala, 226, 226, 227)]: private val z in class UnusedVals is never used +[WARNING] [RangePosition(t12735c.scala, 326, 326, 327)]: private val v in class UnusedIdents is never used +[WARNING] [RangePosition(t12735c.scala, 329, 329, 330)]: private val w in class UnusedIdents is never used +[WARNING] [RangePosition(t12735c.scala, 332, 332, 333)]: private val x in class UnusedIdents is never used +[WARNING] [RangePosition(t12735c.scala, 335, 335, 336)]: private val y in class UnusedIdents is never used +[WARNING] [RangePosition(t12735c.scala, 338, 338, 339)]: private val z in class UnusedIdents is never used +[WARNING] [RangePosition(t12735c.scala, 431, 431, 434)]: private type int in object UnusedAlias is never used +[WARNING] [RangePosition(t12735c.scala, 132, 136, 139)]: match may not be exhaustive. It would fail on the following input: List(_) -[WARNING] [source-t12735c.scala,line-12,offset=239]: match may not be exhaustive. +[WARNING] [source-t12735c.scala,line-12,offset=246]: match may not be exhaustive. It would fail on the following input: List(_) -[WARNING] [source-t12735c.scala,line-19,offset=343]: match may not be exhaustive. +[WARNING] [source-t12735c.scala,line-19,offset=350]: match may not be exhaustive. It would fail on the following input: List(_) [ERROR] [NoPosition]: No warnings can be incurred under -Werror. 15 warnings diff --git a/test/files/neg/t12735c.scala b/test/files/neg/t12735c.scala index 1c8bb56b58a6..8b1b3e29f6a5 100644 --- a/test/files/neg/t12735c.scala +++ b/test/files/neg/t12735c.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -Xreporter:scala.tools.partest.nest.PlainReporter +//> using options -Werror -Xlint -Xreporter:scala.tools.partest.nest.PlainReporter class UnusedVal { private val v: String = diff --git a/test/files/neg/t12770.scala b/test/files/neg/t12770.scala index b1059aadb9b4..8119777134e8 100644 --- a/test/files/neg/t12770.scala +++ b/test/files/neg/t12770.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint object Test { def doesntWarn(input: String) = input match { diff --git a/test/files/neg/t12785.scala b/test/files/neg/t12785.scala index aa1716f6dae9..19609b1fa59d 100644 --- a/test/files/neg/t12785.scala +++ b/test/files/neg/t12785.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import scala.Predef._ diff --git a/test/files/neg/t12798-migration.check b/test/files/neg/t12798-migration.check index 2e229140359e..50f11360d649 100644 --- a/test/files/neg/t12798-migration.check +++ b/test/files/neg/t12798-migration.check @@ -3,48 +3,70 @@ Note that assignments in argument position are no longer allowed since Scala 2.1 To express the assignment expression, wrap it in brackets, e.g., `{ z = ... }`. f(42, z = 27) ^ -t12798-migration.scala:25: warning: unary prefix operator definition with empty parameter list is unsupported: instead, remove () to declare as `def unary_- = -42` [quickfixable] +t12798-migration.scala:25: error: unary prefix operator definition with empty parameter list is unsupported: instead, remove () to declare as `def unary_- = -42` [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def unary_-() = -42 ^ -t12798-migration.scala:33: warning: procedure syntax is deprecated for constructors: add `=`, as in method definition [quickfixable] +t12798-migration.scala:33: error: procedure syntax is deprecated for constructors: add `=`, as in method definition [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def this(s: String) { this() } ^ -t12798-migration.scala:34: warning: procedure syntax is unsupported: instead, add `: Unit =` to explicitly declare `f`'s return type [quickfixable] +t12798-migration.scala:34: error: procedure syntax is unsupported: instead, add `: Unit =` to explicitly declare `f`'s return type [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f() { println() } ^ -t12798-migration.scala:35: warning: procedure syntax is unsupported: instead, add `: Unit` to explicitly declare `g`'s return type [quickfixable] +t12798-migration.scala:35: error: procedure syntax is unsupported: instead, add `: Unit` to explicitly declare `g`'s return type [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def g() ^ -t12798-migration.scala:39: warning: parentheses are required around the parameter of a lambda +t12798-migration.scala:39: error: parentheses are required around the parameter of a lambda Use '-Wconf:msg=lambda-parens:s' to silence this warning. [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f = List(42).map { x: Int => x + 1 } ^ -t12798-migration.scala:43: warning: type application is not allowed for infix operators [quickfixable] +t12798-migration.scala:43: error: type application is not allowed for infix operators [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f = List(42) map [Int] (_ + 1) - ^ -t12798-migration.scala:46: warning: Top-level wildcard is not allowed + ^ +t12798-migration.scala:46: error: Top-level wildcard is not allowed +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration class `misuse of underscore`[_] ^ -t12798-migration.scala:48: warning: early initializers are deprecated; use trait parameters instead. +t12798-migration.scala:48: error: early initializers are deprecated; use trait parameters instead. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration class `early bird` extends { val x = "hello, world" } with Runnable { def run() = println(x) } ^ -t12798-migration.scala:17: warning: Unicode escapes in raw interpolations are ignored in Scala 3; use literal characters instead +t12798-migration.scala:17: error: Unicode escapes in raw interpolations are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use literal characters instead +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=interpolated unicode such as C.f def f = raw"\u0043 is for $entry" ^ -t12798-migration.scala:18: warning: Unicode escapes in raw interpolations are ignored in Scala 3; use literal characters instead +t12798-migration.scala:18: error: Unicode escapes in raw interpolations are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use literal characters instead +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=interpolated unicode such as C.g def g = raw"""\u0043 is for Cat""" ^ -t12798-migration.scala:50: warning: access modifiers for `copy` method are copied from the case class constructor +t12798-migration.scala:50: error: access modifiers for `copy` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=case mods propagate case class `case mods propagate` private (s: String) ^ -t12798-migration.scala:60: warning: under -Xsource:3-cross, the inferred type changes to Option[Int] instead of Some[Int] [quickfixable] +t12798-migration.scala:60: error: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to Option[Int] instead of Some[Int] [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Child.f override def f = Some(27) ^ -t12798-migration.scala:50: warning: access modifiers for `apply` method are copied from the case class constructor -case class `case mods propagate` private (s: String) - ^ -t12798-migration.scala:52: warning: access modifiers for `apply` method are copied from the case class constructor +t12798-migration.scala:52: error: access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=copyless case mods propagate.apply case class `copyless case mods propagate` private (s: String) { ^ -14 warnings -1 error +14 errors diff --git a/test/files/neg/t12798-migration.scala b/test/files/neg/t12798-migration.scala index 2bf590c0f9ef..69f82fd7a820 100644 --- a/test/files/neg/t12798-migration.scala +++ b/test/files/neg/t12798-migration.scala @@ -1,4 +1,4 @@ -// scalac: -Xmigration -Xsource:3 +//> using options -Xsource:3 // Demonstrate migration warnings at typer for -Xsource:3 diff --git a/test/files/neg/t12798.check b/test/files/neg/t12798.check index 39620c5b0f2c..c9d3bf826934 100644 --- a/test/files/neg/t12798.check +++ b/test/files/neg/t12798.check @@ -4,68 +4,68 @@ To express the assignment expression, wrap it in brackets, e.g., `{ z = ... }`. f(42, z = 27) ^ t12798.scala:25: error: unary prefix operator definition with empty parameter list is unsupported: instead, remove () to declare as `def unary_- = -42` [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def unary_-() = -42 ^ t12798.scala:33: error: procedure syntax is deprecated for constructors: add `=`, as in method definition [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def this(s: String) { this() } ^ t12798.scala:34: error: procedure syntax is unsupported: instead, add `: Unit =` to explicitly declare `f`'s return type [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f() { println() } ^ t12798.scala:35: error: procedure syntax is unsupported: instead, add `: Unit` to explicitly declare `g`'s return type [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def g() ^ t12798.scala:39: error: parentheses are required around the parameter of a lambda Use '-Wconf:msg=lambda-parens:s' to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f = List(42).map { x: Int => x + 1 } ^ t12798.scala:43: error: type application is not allowed for infix operators [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f = List(42) map [Int] (_ + 1) - ^ + ^ t12798.scala:46: error: Top-level wildcard is not allowed -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration class `misuse of underscore`[_] ^ t12798.scala:48: error: early initializers are deprecated; use trait parameters instead. -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration class `early bird` extends { val x = "hello, world" } with Runnable { def run() = println(x) } ^ -t12798.scala:17: error: Unicode escapes in raw interpolations are ignored in Scala 3; use literal characters instead -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t12798.scala:17: error: Unicode escapes in raw interpolations are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use literal characters instead +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=interpolated unicode such as C.f def f = raw"\u0043 is for $entry" ^ -t12798.scala:18: error: Unicode escapes in raw interpolations are ignored in Scala 3; use literal characters instead -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t12798.scala:18: error: Unicode escapes in raw interpolations are ignored in Scala 3 (or with -Xsource-features:unicode-escapes-raw); use literal characters instead +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=interpolated unicode such as C.g def g = raw"""\u0043 is for Cat""" ^ -t12798.scala:50: error: access modifiers for `copy` method are copied from the case class constructor -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t12798.scala:50: error: access modifiers for `copy` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=case mods propagate case class `case mods propagate` private (s: String) ^ -t12798.scala:60: error: under -Xsource:3-cross, the inferred type changes to Option[Int] instead of Some[Int] [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t12798.scala:60: error: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to Option[Int] instead of Some[Int] [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Child.f override def f = Some(27) ^ -t12798.scala:52: error: access modifiers for `apply` method are copied from the case class constructor -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t12798.scala:52: error: access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=copyless case mods propagate.apply case class `copyless case mods propagate` private (s: String) { ^ diff --git a/test/files/neg/t12798.scala b/test/files/neg/t12798.scala index 95b9ce3a246e..69f82fd7a820 100644 --- a/test/files/neg/t12798.scala +++ b/test/files/neg/t12798.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // Demonstrate migration warnings at typer for -Xsource:3 diff --git a/test/files/neg/t12798b.check b/test/files/neg/t12798b.check index e55dddaac937..e80848b73354 100644 --- a/test/files/neg/t12798b.check +++ b/test/files/neg/t12798b.check @@ -1,10 +1,10 @@ t12798b.scala:9: error: shadowing a nested class of a parent is deprecated but class P shadows class P defined in class HasP; rename the class to something else -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=AnotherP.P class P extends super.P ^ t12798b.scala:15: error: shadowing a nested class of a parent is deprecated but class Q shadows class Q defined in class HasQ; rename the class to something else -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=AnotherQ.Q class Q ^ diff --git a/test/files/neg/t12798b.scala b/test/files/neg/t12798b.scala index c7aec47dc999..448135c1c09f 100644 --- a/test/files/neg/t12798b.scala +++ b/test/files/neg/t12798b.scala @@ -1,4 +1,4 @@ -// scalac: -Wconf:cat=scala3-migration:e -Xmigration -Xsource:3 +//> using options -Xsource:3 // Demonstrate migration warnings at refchecks for -Xsource:3 diff --git a/test/files/neg/t12799/Test_2.scala b/test/files/neg/t12799/Test_2.scala index 4f1ddfe5e3d1..a4d6d5e9fa23 100644 --- a/test/files/neg/t12799/Test_2.scala +++ b/test/files/neg/t12799/Test_2.scala @@ -1,6 +1,6 @@ -// scalac: -Werror -Xlint -// javaVersion: 9+ +//> using options -Werror -Xlint +//> using jvm 9+ import example._ diff --git a/test/files/neg/t12800/matcher_1.scala b/test/files/neg/t12800/matcher_1.scala index 47d287a248ff..186acb763fb4 100644 --- a/test/files/neg/t12800/matcher_1.scala +++ b/test/files/neg/t12800/matcher_1.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xsource:3 +//> using options -Werror -Xsource:3 import JetBrains.* diff --git a/test/files/neg/t12813b.check b/test/files/neg/t12813b.check index 34f9a5d0fabc..a3d73ea2cb01 100644 --- a/test/files/neg/t12813b.check +++ b/test/files/neg/t12813b.check @@ -21,8 +21,5 @@ import O.{given, toString, a, _} // error 3 ^ t12813b.scala:18: error: duplicate wildcard selector import O.{a, given, *, _} // error 3 - ^ -t12813b.scala:19: error: given requires a wildcard selector -import O.{a, given} // error 3 - ^ -9 errors + ^ +8 errors diff --git a/test/files/neg/t12813b.scala b/test/files/neg/t12813b.scala index da65e1b90364..c59c401e65c9 100644 --- a/test/files/neg/t12813b.scala +++ b/test/files/neg/t12813b.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 object O { val a = 1 } @@ -16,4 +16,4 @@ import O.{given, toString, a, _} // error 3 import O.{a, given, *} // ok import O.{a, *, given} // ok import O.{a, given, *, _} // error 3 -import O.{a, given} // error 3 +import O.{a, given} // ok diff --git a/test/files/neg/t12815.scala b/test/files/neg/t12815.scala index 945e0b18d1e3..dd477e487c76 100644 --- a/test/files/neg/t12815.scala +++ b/test/files/neg/t12815.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import scala.beans.BeanProperty diff --git a/test/files/neg/t12816.check b/test/files/neg/t12816.check index d4192cedca69..d78566930c28 100644 --- a/test/files/neg/t12816.check +++ b/test/files/neg/t12816.check @@ -3,7 +3,7 @@ it is both defined in the enclosing package p and inherited in the enclosing tra In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.c`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=p.RR.m3 def m3 = c // warn ^ @@ -12,7 +12,7 @@ it is both defined in the enclosing package p and inherited in the enclosing tra In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.Z`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=p.RR.n3 def n3: Z // warn ^ diff --git a/test/files/neg/t12816.scala b/test/files/neg/t12816.scala index ccac64ed5765..fa9e74543167 100644 --- a/test/files/neg/t12816.scala +++ b/test/files/neg/t12816.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Werror +//> using options -Xsource:3 -Werror trait U { def a: Int = 0 diff --git a/test/files/neg/t12816b.check b/test/files/neg/t12816b.check index 770e50f8834a..eb80167ae660 100644 --- a/test/files/neg/t12816b.check +++ b/test/files/neg/t12816b.check @@ -3,7 +3,7 @@ it is both defined in the enclosing package p and inherited in the enclosing tra In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.c`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=p.RR.m3 def m3 = c // warn ^ @@ -12,7 +12,7 @@ it is both defined in the enclosing package p and inherited in the enclosing tra In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.Z`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=p.RR.n3 def n3: Z // warn ^ diff --git a/test/files/neg/t12816b/B.scala b/test/files/neg/t12816b/B.scala index f4c12477b262..1ea81921e114 100644 --- a/test/files/neg/t12816b/B.scala +++ b/test/files/neg/t12816b/B.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Werror +//> using options -Xsource:3 -Werror package p { object c diff --git a/test/files/neg/t12843.check b/test/files/neg/t12843.check new file mode 100644 index 000000000000..77f74bf37dc2 --- /dev/null +++ b/test/files/neg/t12843.check @@ -0,0 +1,21 @@ +t12843.scala:4: error: ambiguous reference to overloaded definition, +both method remove in class ListBuffer of type (idx: Int, count: Int): Unit +and method remove in class ListBuffer of type (idx: Int): Int +match expected type ? + def f = b.remove + ^ +t12843.scala:5: error: missing argument list for method update in class ListBuffer of type (idx: Int, elem: Int): Unit +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `update _` or `update(_,_)` instead of `update`. + def g = b.update + ^ +t12843.scala:10: error: missing argument list for method map in class BitSet +with overloaded members in scala.collection.immutable.BitSet + (f: Int => Int): scala.collection.immutable.BitSet + [B](f: Int => B)(implicit ev: Ordering[B]): scala.collection.immutable.SortedSet[B] + [B](f: Int => B): scala.collection.immutable.Set[B] +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `map _` or `map(_)` instead of `map`. + def f = c.map + ^ +3 errors diff --git a/test/files/neg/t12843.scala b/test/files/neg/t12843.scala new file mode 100644 index 000000000000..5838811763e5 --- /dev/null +++ b/test/files/neg/t12843.scala @@ -0,0 +1,11 @@ + +class C { + val b = collection.mutable.ListBuffer.empty[Int] + def f = b.remove + def g = b.update +} + +class D { + val c = collection.immutable.BitSet(1, 2, 3) + def f = c.map +} diff --git a/test/files/neg/t12851b/C_2.scala b/test/files/neg/t12851b/C_2.scala index c6d4b70f2960..39536ddec310 100644 --- a/test/files/neg/t12851b/C_2.scala +++ b/test/files/neg/t12851b/C_2.scala @@ -1,2 +1,2 @@ -// scalac: -Werror +//> using options -Werror class C extends T1 with T2 diff --git a/test/files/neg/t12879/Test.scala b/test/files/neg/t12879/Test.scala index 72814765e9fb..d3e755560921 100644 --- a/test/files/neg/t12879/Test.scala +++ b/test/files/neg/t12879/Test.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Werror +//> using options -deprecation -Werror class C { val x: A = A.Foo val y: A = A.Bar diff --git a/test/files/neg/t12883.check b/test/files/neg/t12883.check index 91d1b03fe62f..664d25d0d3d6 100644 --- a/test/files/neg/t12883.check +++ b/test/files/neg/t12883.check @@ -1,5 +1,5 @@ -t12883.scala:3: error: access modifiers for `apply` method are copied from the case class constructor -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t12883.scala:3: error: access modifiers for `apply` method are copied from the case class constructor under Scala 3 (or with -Xsource-features:case-apply-copy-access) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C.apply case class C private (c: Int) { ^ diff --git a/test/files/neg/t12919-3cross.check b/test/files/neg/t12919-3cross.check index 4d315c7bde26..c32d670a1342 100644 --- a/test/files/neg/t12919-3cross.check +++ b/test/files/neg/t12919-3cross.check @@ -1,4 +1,4 @@ -t12919-3cross.scala:24: error: No implicit Ordering defined for a.A. +t12919-3cross.scala:24: error: could not find implicit value for parameter ord: Ordering[a.A] def f(xs: List[a.A]) = xs.sorted // not found ^ 1 error diff --git a/test/files/neg/t12919-3cross.scala b/test/files/neg/t12919-3cross.scala index 2e178724670f..aa2a5dcb74a1 100644 --- a/test/files/neg/t12919-3cross.scala +++ b/test/files/neg/t12919-3cross.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:package-prefix-implicits package object a { implicit val aOrd: Ordering[A] = null diff --git a/test/files/neg/t12919.check b/test/files/neg/t12919.check index 47b2e04301ae..0c06daaf2e80 100644 --- a/test/files/neg/t12919.check +++ b/test/files/neg/t12919.check @@ -1,7 +1,13 @@ -t12919.scala:24: error: Implicit value aOrd was found in a package prefix of the required type, which is not part of the implicit scope in Scala 3. +t12919.scala:24: error: Implicit value aOrd was found in a package prefix of the required type, which is not part of the implicit scope in Scala 3 (or with -Xsource-features:package-prefix-implicits). For migration, add `import a.aOrd`. -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=b.V.f def f(xs: List[a.A]) = xs.sorted // warn ^ -1 error +t12919.scala:48: error: Implicit method myClassToSeq was found in a package prefix of the required type, which is not part of the implicit scope in Scala 3 (or with -Xsource-features:package-prefix-implicits). +For migration, add `import a1.a2.myClassToSeq`. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=a1.Main.f + def f[A](x: Seq[a1.a2.MyClass[A]]): Seq[A] = x.flatten + ^ +2 errors diff --git a/test/files/neg/t12919.scala b/test/files/neg/t12919.scala index 609ad2221b82..ea35a2d6ba4b 100644 --- a/test/files/neg/t12919.scala +++ b/test/files/neg/t12919.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Werror +//> using options -Xsource:3 -Werror package object a { implicit val aOrd: Ordering[A] = null @@ -34,3 +34,17 @@ package c { } } +package a1 { + + package object a2 { + implicit def myClassToSeq[A](a: MyClass[A]): Seq[A] = a.values + } + + package a2 { + case class MyClass[A](values: Seq[A]) + } + + object Main { + def f[A](x: Seq[a1.a2.MyClass[A]]): Seq[A] = x.flatten + } +} diff --git a/test/files/neg/t12953-expandee.check b/test/files/neg/t12953-expandee.check new file mode 100644 index 000000000000..dc4fccd9fbb9 --- /dev/null +++ b/test/files/neg/t12953-expandee.check @@ -0,0 +1,9 @@ +Client_2.scala:10: warning: possible missing interpolator: detected interpolated identifier `$unusedVariable` + println("hello, world of $unusedVariable") + ^ +Client_2.scala:9: warning: local val unusedVariable in value is never used + val unusedVariable = "42".toInt + ^ +error: No warnings can be incurred under -Werror. +2 warnings +1 error diff --git a/test/files/neg/t12953-expandee/Client_2.scala b/test/files/neg/t12953-expandee/Client_2.scala new file mode 100644 index 000000000000..175eab07ef1f --- /dev/null +++ b/test/files/neg/t12953-expandee/Client_2.scala @@ -0,0 +1,13 @@ + +//> using options -Werror -Wunused:locals -Xlint:missing-interpolator -Wmacros:before + +import Macro.id + +object Test extends App { + println { + id { + val unusedVariable = "42".toInt + println("hello, world of $unusedVariable") + } + } +} diff --git a/test/files/neg/t12953-expandee/Macro_1.scala b/test/files/neg/t12953-expandee/Macro_1.scala new file mode 100644 index 000000000000..9b3204041783 --- /dev/null +++ b/test/files/neg/t12953-expandee/Macro_1.scala @@ -0,0 +1,11 @@ + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macro { + def id[A](body: A): A = macro impl[A] + + def impl[A: c.WeakTypeTag](c: Context)(body: c.Expr[A]) = { + body + } +} diff --git a/test/files/neg/t12953-expansion-b.check b/test/files/neg/t12953-expansion-b.check new file mode 100644 index 000000000000..dcf0eb37fcc4 --- /dev/null +++ b/test/files/neg/t12953-expansion-b.check @@ -0,0 +1,9 @@ +Client_2.scala:8: warning: possible missing interpolator: detected interpolated identifier `$unusedVariable` + id { + ^ +Client_2.scala:8: warning: local val unusedVariable in value is never used + id { + ^ +error: No warnings can be incurred under -Werror. +2 warnings +1 error diff --git a/test/files/neg/t12953-expansion-b/Client_2.scala b/test/files/neg/t12953-expansion-b/Client_2.scala new file mode 100644 index 000000000000..732242fcf7d9 --- /dev/null +++ b/test/files/neg/t12953-expansion-b/Client_2.scala @@ -0,0 +1,12 @@ + +//> using options -Werror -Wunused:locals -Xlint:missing-interpolator -Wmacros:after + +import Macro.id + +object Test extends App { + println { + id { + println("goodbye, cruel world of $unusedVariable") + } + } +} diff --git a/test/files/neg/t12953-expansion-b/Macro_1.scala b/test/files/neg/t12953-expansion-b/Macro_1.scala new file mode 100644 index 000000000000..9e5d8467520c --- /dev/null +++ b/test/files/neg/t12953-expansion-b/Macro_1.scala @@ -0,0 +1,13 @@ + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +// with unused interpolator check in typer, the variable and literal must be typechecked together to warn +object Macro { + def id[A](body: A): A = macro impl[A] + + def impl[A: c.WeakTypeTag](c: Context)(body: c.Expr[A]) = { + import c.universe._ + q"""val unusedVariable = "42".toInt; println("hello, world of $$unusedVariable"); $body""" + } +} diff --git a/test/files/neg/t12953-expansion.check b/test/files/neg/t12953-expansion.check new file mode 100644 index 000000000000..4b1a987128dc --- /dev/null +++ b/test/files/neg/t12953-expansion.check @@ -0,0 +1,6 @@ +Client_2.scala:8: warning: local val unusedVariable in value is never used + id { + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/t12953-expansion/Client_2.scala b/test/files/neg/t12953-expansion/Client_2.scala new file mode 100644 index 000000000000..522dd9411865 --- /dev/null +++ b/test/files/neg/t12953-expansion/Client_2.scala @@ -0,0 +1,12 @@ + +//> using options -Werror -Wunused:locals -Xlint:missing-interpolator -Wmacros:after + +import Macro.id + +object Test extends App { + println { + id { + println("hello, world of $unusedVariable") + } + } +} diff --git a/test/files/neg/t12953-expansion/Macro_1.scala b/test/files/neg/t12953-expansion/Macro_1.scala new file mode 100644 index 000000000000..4159c22a76d0 --- /dev/null +++ b/test/files/neg/t12953-expansion/Macro_1.scala @@ -0,0 +1,13 @@ + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +// with unused interpolator check in typer, the variable and literal must be typechecked together to warn +object Macro { + def id[A](body: A): A = macro impl[A] + + def impl[A: c.WeakTypeTag](c: Context)(body: c.Expr[A]) = { + import c.universe._ + q"""val unusedVariable = "42".toInt; $body""" + } +} diff --git a/test/files/neg/t12984.check b/test/files/neg/t12984.check new file mode 100644 index 000000000000..238af71422db --- /dev/null +++ b/test/files/neg/t12984.check @@ -0,0 +1,6 @@ +t12984.scala:12: warning: class D is deprecated (since 2.0): Will be phased out eventually someday. + def d = new D + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/t12984.scala b/test/files/neg/t12984.scala new file mode 100644 index 000000000000..f62ae8c2ab37 --- /dev/null +++ b/test/files/neg/t12984.scala @@ -0,0 +1,13 @@ + +//> using options -deprecation -Wconf:cat=deprecation&origin=C:s -Werror -Xlint + +@deprecated("Just say no.", since="1.0") +class C + +@deprecated("Will be phased out eventually someday.", since="2.0") +class D + +trait Test { + def c = new C + def d = new D +} diff --git a/test/files/neg/t13004b.check b/test/files/neg/t13004b.check new file mode 100644 index 000000000000..da72f763e67d --- /dev/null +++ b/test/files/neg/t13004b.check @@ -0,0 +1,9 @@ +t13004b.scala:14: applied implicit conversion from Money to ?{def + : ?} = final implicit def any2stringadd[A](self: A): any2stringadd[A] + Money(3.14) + Money(1.7) + ^ +t13004b.scala:14: error: type mismatch; + found : Money + required: String + Money(3.14) + Money(1.7) + ^ +1 error diff --git a/test/files/neg/t13004b.scala b/test/files/neg/t13004b.scala new file mode 100644 index 000000000000..850a5cef4544 --- /dev/null +++ b/test/files/neg/t13004b.scala @@ -0,0 +1,16 @@ +//> using options -Vimplicit-conversions -Xlint -Xsource:3 -Xsource-features:any2stringadd + +import scala.Predef.* + +case class Money(value: Double) +object Money { + implicit class MoneySyntax(private val self: Money) extends AnyVal { + def +(other: Money): Money = Money(self.value + other.value) + } +} + +object Test extends App { + println { + Money(3.14) + Money(1.7) + } +} diff --git a/test/files/neg/t13006.check b/test/files/neg/t13006.check new file mode 100644 index 000000000000..4d46b2624997 --- /dev/null +++ b/test/files/neg/t13006.check @@ -0,0 +1,30 @@ +t13006.scala:7: warning: class C is deprecated + type X[T] = C[T] // warn + ^ +t13006.scala:17: warning: class C is deprecated + def t3 = C.apply(20) // warn + ^ +t13006.scala:18: warning: class C is deprecated + def t4 = new C(10) // warn + ^ +t13006.scala:21: warning: constructor D in class D is deprecated + def u1 = A.Y.apply(10) // warn + ^ +t13006.scala:22: warning: constructor D in class D is deprecated + def u2 = new A.Y(10) // warn + ^ +t13006.scala:23: warning: constructor D in class D is deprecated + def u3 = D.apply(10) // warn + ^ +t13006.scala:24: warning: constructor D in class D is deprecated + def u4 = new D(10) // warn + ^ +t13006.scala:34: warning: class C in object oho is deprecated + def t1 = oho.C(10) // warn + ^ +t13006.scala:35: warning: constructor D in class D is deprecated + def t2 = oho.D(10) // warn + ^ +error: No warnings can be incurred under -Werror. +9 warnings +1 error diff --git a/test/files/neg/t13006.scala b/test/files/neg/t13006.scala new file mode 100644 index 000000000000..dd0bd589bcda --- /dev/null +++ b/test/files/neg/t13006.scala @@ -0,0 +1,36 @@ +//> using options -deprecation -Werror + +@deprecated case class C[T](x: T) +case class D @deprecated() (x: Int) + +object A { + type X[T] = C[T] // warn + val X = C // no warn + + type Y = D // no warn + val Y = D // no warn +} + +class T { + def t1 = A.X.apply(10) // no warn + def t2 = new A.X(10) // no warn + def t3 = C.apply(20) // warn + def t4 = new C(10) // warn + def t5 = C.hashCode // no warn + + def u1 = A.Y.apply(10) // warn + def u2 = new A.Y(10) // warn + def u3 = D.apply(10) // warn + def u4 = new D(10) // warn + def u5(d: D) = 10 // no warn +} + +object oho { + @deprecated case class C private[oho] (x: Int) + case class D @deprecated() private[oho] (x: Int) +} + +class T1 { + def t1 = oho.C(10) // warn + def t2 = oho.D(10) // warn +} diff --git a/test/files/neg/t13007.check b/test/files/neg/t13007.check new file mode 100644 index 000000000000..b57af0ea8f82 --- /dev/null +++ b/test/files/neg/t13007.check @@ -0,0 +1,10 @@ +Test.scala:9: error: Unable to emit reference to method j in class J, class J is not accessible in trait T + def t4 = j() + ^ +Test.scala:10: error: Unable to emit reference to method j in class J, class J is not accessible in trait T + def t5 = this.j() + ^ +Test.scala:11: error: Unable to emit reference to method j in class J, class J is not accessible in trait T + def t6 = self.j() + ^ +3 errors diff --git a/test/files/neg/t13007/J.java b/test/files/neg/t13007/J.java new file mode 100644 index 000000000000..da76473a48c0 --- /dev/null +++ b/test/files/neg/t13007/J.java @@ -0,0 +1,7 @@ +package j; + +public class J { + protected boolean i() { return false; } + protected boolean j() { return false; } + public boolean k() { return false; } +} diff --git a/test/files/neg/t13007/Test.scala b/test/files/neg/t13007/Test.scala new file mode 100644 index 000000000000..a2f219accaad --- /dev/null +++ b/test/files/neg/t13007/Test.scala @@ -0,0 +1,18 @@ +package s + +trait T { self: j.J => + override def i(): Boolean = true + def t1 = i() + def t2 = this.i() + def t3 = self.i() + + def t4 = j() + def t5 = this.j() + def t6 = self.j() + + def t7 = k() + def t8 = this.k() + def t9 = self.k() +} + +class C extends j.J with T diff --git a/test/files/neg/t13014.check b/test/files/neg/t13014.check new file mode 100644 index 000000000000..0f0c6012e815 --- /dev/null +++ b/test/files/neg/t13014.check @@ -0,0 +1,5 @@ +t13014.scala:2: error: could not find implicit value for parameter blup: String +Error occurred in an application involving default arguments. +class D extends C(y = 1) + ^ +1 error diff --git a/test/files/neg/t13014.scala b/test/files/neg/t13014.scala new file mode 100644 index 000000000000..575d434432e4 --- /dev/null +++ b/test/files/neg/t13014.scala @@ -0,0 +1,2 @@ +class C(x: Int = 0, y: Int = 0)(implicit blup: String) +class D extends C(y = 1) diff --git a/test/files/neg/t13055.check b/test/files/neg/t13055.check new file mode 100644 index 000000000000..26f5e77f5799 --- /dev/null +++ b/test/files/neg/t13055.check @@ -0,0 +1,10 @@ +t13055.scala:15: error: missing argument list for method forAll in object Main +with overloaded members in Main.type + [A1, P](f: A1 => P)(implicit p: P => Main.Prop): Main.Prop + [T1, P](g: Main.Gen[T1])(f: T1 => P)(implicit p: P => Main.Prop): Main.Prop +Unapplied methods are only converted to functions when a function type is expected. +Use -Xsource-features:eta-expand-always to convert even if the expected type is not a function type. +You can make this conversion explicit by writing `forAll _` or `forAll(_)(_)(_)` instead of `forAll`. + def what() = forAll { + ^ +1 error diff --git a/test/files/neg/t13055.scala b/test/files/neg/t13055.scala new file mode 100644 index 000000000000..4a236a092af8 --- /dev/null +++ b/test/files/neg/t13055.scala @@ -0,0 +1,28 @@ +//> using options -Xsource:3 + +//import org.scalacheck._, Prop._ + +object Main extends App { + class Prop + class Gen[A] + object Gen { + implicit def const[T](x: T): Gen[T] = ??? + } + + def forAll[T1, P](g: Gen[T1])(f: T1 => P)(implicit p: P => Prop): Prop = ??? + def forAll[A1, P](f: A1 => P)(implicit p: P => Prop): Prop = ??? + + def what() = forAll { + (a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, + a8: Int, + a9: Int, + ) => false + } + +} + +/* + def what(): (((Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean) => Nothing) => Main.Prop = { + val eta$0$1: Main.Gen[(Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean] = Main.this.Gen.const[(Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean](((a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int, a9: Int) => false)); + ((f: ((Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean) => Nothing) => Main.this.forAll[(Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean, Nothing](eta$0$1)(f)(scala.Predef.$conforms[Nothing])) +*/ diff --git a/test/files/neg/t13070.check b/test/files/neg/t13070.check new file mode 100644 index 000000000000..33fab290c580 --- /dev/null +++ b/test/files/neg/t13070.check @@ -0,0 +1,18 @@ +t13070.scala:7: warning: pattern var i in value $anonfun is never used + (i, j) = ns // warn // warn + ^ +t13070.scala:7: warning: pattern var j in value $anonfun is never used + (i, j) = ns // warn // warn + ^ +t13070.scala:16: warning: pattern var j in value $anonfun is never used + (i, j) = ns // warn + ^ +t13070.scala:23: warning: pattern var i in object pat vardef are patvars is never used + private var (i, j) = (42, 27) // warn // warn + ^ +t13070.scala:23: warning: pattern var j in object pat vardef are patvars is never used + private var (i, j) = (42, 27) // warn // warn + ^ +error: No warnings can be incurred under -Werror. +5 warnings +1 error diff --git a/test/files/neg/t13070.scala b/test/files/neg/t13070.scala new file mode 100644 index 000000000000..4b84fbfc9212 --- /dev/null +++ b/test/files/neg/t13070.scala @@ -0,0 +1,59 @@ +//> using options -Wunused:patvars -Werror +class C { + def g = { + val t = Option((27, 42)) + for { + ns <- t + (i, j) = ns // warn // warn + } yield 42 + } +} +class D { + def g = { + val t = Option((27, 42)) + for { + ns <- t + (i, j) = ns // warn + } yield 42 + i + } +} + +// previously, the following do not warn under -Wunused:patvars in Scala 2 (but Scala 3 does) +object `pat vardef are patvars` { + private var (i, j) = (42, 27) // warn // warn +} + +object `patvar is assignable` { + var (i, j) = (42, 27) // no warn nonprivate + j += 1 + println((i, j)) +} + +object `privy patvar is assignable` { + private var (i, j) = (42, 27) // warn + j += 1 + println((i, j)) +} + +object `local patvar is assignable` { + def f() = { + var (i, j) = (42, 27) // warn + j += 1 + println((i, j)) + } +} + +object `mutable patvar in for` { + def f(xs: List[Int]) = { + for (x <- xs; y = x + 1 if y > 10) + yield { + var z :: Nil = y :: Nil: @unchecked // warn + z + 10 + } + } +} + +class `unset var requires -Wunused` { + private var i = 0 // no warn as we didn't ask for it + def f = println(i) +} diff --git a/test/files/neg/t13095.check b/test/files/neg/t13095.check new file mode 100644 index 000000000000..ab88b56a87a6 --- /dev/null +++ b/test/files/neg/t13095.check @@ -0,0 +1,21 @@ +t13095.scala:12: warning: pattern var z in object Main is never used + private val A(w, z) = A(42, 27) // warn + ^ +t13095.scala:13: warning: pattern var r in object Main is never used + private[this] val A(q, r) = A(42, 27) // warn + ^ +t13095.scala:42: warning: pattern var s in method spam is never used + case email(s, addr) => // warn // warn each, multiple extraction + ^ +t13095.scala:42: warning: pattern var addr in method spam is never used + case email(s, addr) => // warn // warn each, multiple extraction + ^ +t13095.scala:52: warning: pattern var v in method scala-dev#902 is never used + case (i, v @ (_, _)) => i // warn multiple patvars + ^ +t13095.scala:52: warning: a pure expression does nothing in statement position + case (i, v @ (_, _)) => i // warn multiple patvars + ^ +error: No warnings can be incurred under -Werror. +6 warnings +1 error diff --git a/test/files/neg/t13095.scala b/test/files/neg/t13095.scala new file mode 100644 index 000000000000..a044a6a19d6a --- /dev/null +++ b/test/files/neg/t13095.scala @@ -0,0 +1,65 @@ +//> using options -Wunused:patvars -Werror + +case class A(x: Int, y: Int) + +object Main { + for { + a <- List.empty[A] + A(x, y) = a + } yield x + y + + private val A(x, y) = A(42, 27) // nowarn for canonical name + private val A(w, z) = A(42, 27) // warn + private[this] val A(q, r) = A(42, 27) // warn + def W = w + def Q = q +} + +class C { + def f(x: Any) = + x match { + case x: String => // nowarn because x is not a new reference but an alias + case _ => + } + def g(x: Any) = + (x: @unchecked) match { + case x: String => // nowarn because x is not a new reference but an alias + case _ => + } + def s(x: Option[String]) = + x match { + case x: Some[String] => // nowarn because x is not a new reference but an alias + case _ => + } + def t(x: Option[String]) = + x match { + case Some(x) => // nowarn because x is not a new reference but an alias of sorts + case _ => + } + val email = "(.*)@(.*)".r + def spam(s: String) = + s match { + case email(s, addr) => // warn // warn each, multiple extraction + case _ => + } + def border(s: String) = + s match { + case email(s, _) => // nowarn only one patvar + case _ => + } + def `scala-dev#902`(v: (Int, (Boolean, String))): Unit = + v match { + case (i, v @ (_, _)) => i // warn multiple patvars + } +} + +final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { + def f = + (xs: Array[_]) match { + case xs => + } +} + +class Publix { + val A(w, z) = A(42, 27) // nowarn if an accessor is neither private nor local +} diff --git a/test/files/neg/t13307b.check b/test/files/neg/t13307b.check new file mode 100644 index 000000000000..4959408a56e8 --- /dev/null +++ b/test/files/neg/t13307b.check @@ -0,0 +1,9 @@ +Test.scala:8: error: Implementation restriction: trait T accesses protected method j inside a concrete trait method. +Add an accessor in a class extending class J as a workaround. + def t4 = j() + ^ +Test.scala:9: error: Implementation restriction: trait T accesses protected method j inside a concrete trait method. +Add an accessor in a class extending class J as a workaround. + def t5 = this.j() + ^ +2 errors diff --git a/test/files/neg/t13307b/J.java b/test/files/neg/t13307b/J.java new file mode 100644 index 000000000000..da76473a48c0 --- /dev/null +++ b/test/files/neg/t13307b/J.java @@ -0,0 +1,7 @@ +package j; + +public class J { + protected boolean i() { return false; } + protected boolean j() { return false; } + public boolean k() { return false; } +} diff --git a/test/files/neg/t13307b/Test.scala b/test/files/neg/t13307b/Test.scala new file mode 100644 index 000000000000..2025b035ecae --- /dev/null +++ b/test/files/neg/t13307b/Test.scala @@ -0,0 +1,15 @@ +package s + +trait T extends j.J { + override def i(): Boolean = true + def t1 = i() + def t2 = this.i() + + def t4 = j() + def t5 = this.j() + + def t7 = k() + def t8 = this.k() +} + +class C extends j.J with T diff --git a/test/files/neg/t1371.scala b/test/files/neg/t1371.scala index f90942fb345a..6e7e5009bbd8 100644 --- a/test/files/neg/t1371.scala +++ b/test/files/neg/t1371.scala @@ -1,3 +1,3 @@ -// scalac: -Yrangepos +// trait A[T <: (_)] diff --git a/test/files/neg/t1503.scala b/test/files/neg/t1503.scala index e5be752475a0..c8cf90f52960 100644 --- a/test/files/neg/t1503.scala +++ b/test/files/neg/t1503.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror -Wvalue-discard +//> using options -Xlint -Werror -Wvalue-discard // object Whatever { override def equals(x: Any) = true @@ -30,7 +30,7 @@ class Test { def h(x: Any): String = x match { case s @ "hello, world" => s } def h2(x: Any): String = x match { case s @ (_: "hello, world") => s } - //def h3(x: Any): "hello, world" = x match { case s @ "hello, world" => s } // crash + def h3(x: Any): "hello, world" = x match { case s @ "hello, world" => s } //def j(x: Any): Array[Int] = x match { case xs @ Array(42) => xs } // found Array[T] required Array[Int] } diff --git a/test/files/neg/t1909-object.scala b/test/files/neg/t1909-object.scala index 6b6e0247557b..cbce3bc84a77 100644 --- a/test/files/neg/t1909-object.scala +++ b/test/files/neg/t1909-object.scala @@ -1,4 +1,4 @@ -// scalac: -Xdev -Xfatal-warnings +//> using options -Xdev -Xfatal-warnings // class Kaboom(a: Any) { def this() = { diff --git a/test/files/neg/t2442/t2442.scala b/test/files/neg/t2442/t2442.scala index 3909905229cf..738e12485936 100644 --- a/test/files/neg/t2442/t2442.scala +++ b/test/files/neg/t2442/t2442.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class Test { import MyEnum._ diff --git a/test/files/neg/t2458/test.scala b/test/files/neg/t2458/test.scala index a2cae880a158..bc0d25957984 100644 --- a/test/files/neg/t2458/test.scala +++ b/test/files/neg/t2458/test.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 import q.X package p { diff --git a/test/files/neg/t2458b/test.scala b/test/files/neg/t2458b/test.scala index 087aca4668b0..767187d14276 100644 --- a/test/files/neg/t2458b/test.scala +++ b/test/files/neg/t2458b/test.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 import q._ package q.qq { diff --git a/test/files/neg/t2458c/test.scala b/test/files/neg/t2458c/test.scala index ec082fadf31e..8e5ea67c6def 100644 --- a/test/files/neg/t2458c/test.scala +++ b/test/files/neg/t2458c/test.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 import q.X._ package p { diff --git a/test/files/neg/t2462b.scala b/test/files/neg/t2462b.scala index 5c80e62dfd34..d1c826d81644 100644 --- a/test/files/neg/t2462b.scala +++ b/test/files/neg/t2462b.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:implicit-not-found -Xfatal-warnings +//> using options -Xlint:implicit-not-found -Xfatal-warnings // package test diff --git a/test/files/neg/t2462c.scala b/test/files/neg/t2462c.scala index d059a47ceb09..f229a76e577b 100644 --- a/test/files/neg/t2462c.scala +++ b/test/files/neg/t2462c.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // import annotation._ diff --git a/test/files/neg/t2509-2.scala b/test/files/neg/t2509-2.scala index 6023d1c85640..4a2fadfde231 100644 --- a/test/files/neg/t2509-2.scala +++ b/test/files/neg/t2509-2.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution class A class B extends A class C extends B diff --git a/test/files/neg/t2509-3.scala b/test/files/neg/t2509-3.scala index 5ca13fc1f62e..efb736aab7ae 100644 --- a/test/files/neg/t2509-3.scala +++ b/test/files/neg/t2509-3.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution class A class B extends A diff --git a/test/files/neg/t2509-7b.scala b/test/files/neg/t2509-7b.scala index 31ed5c6b49c6..f1bb32aa0e2a 100644 --- a/test/files/neg/t2509-7b.scala +++ b/test/files/neg/t2509-7b.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution class Both[-A, +B] trait Factory[A] { diff --git a/test/files/neg/t2773.check b/test/files/neg/t2773.check index 44fc66051962..0974769451a2 100644 --- a/test/files/neg/t2773.check +++ b/test/files/neg/t2773.check @@ -1,6 +1,6 @@ t2773.scala:5: error: value x is not a member of C import c.x - ^ + ^ t2773.scala:6: error: not found: value x println(x) ^ diff --git a/test/files/neg/t2796.scala b/test/files/neg/t2796.scala index 4bf0d2168baf..7a718fc0cade 100644 --- a/test/files/neg/t2796.scala +++ b/test/files/neg/t2796.scala @@ -1,5 +1,5 @@ // -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // trait Base { val abstractVal: String diff --git a/test/files/neg/t2799.scala b/test/files/neg/t2799.scala index abf78ab17a28..85bce2a27b94 100644 --- a/test/files/neg/t2799.scala +++ b/test/files/neg/t2799.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror @deprecated("other mother", "") trait T[A] diff --git a/test/files/neg/t284.scala b/test/files/neg/t284.scala index 26fd20167559..40118ca29612 100644 --- a/test/files/neg/t284.scala +++ b/test/files/neg/t284.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait B[T] { def f1(a: T): Unit { } diff --git a/test/files/neg/t3098/a.scala b/test/files/neg/t3098/a.scala index 9f8fb295f5c0..d2ee7048fd56 100644 --- a/test/files/neg/t3098/a.scala +++ b/test/files/neg/t3098/a.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed trait T trait A extends T diff --git a/test/files/neg/t3420b.scala b/test/files/neg/t3420b.scala index 33d907594145..a6c9ff90170e 100644 --- a/test/files/neg/t3420b.scala +++ b/test/files/neg/t3420b.scala @@ -1,5 +1,5 @@ -// scalac: --release 8 -opt:inline:** -Wopt -Werror +//> using options --release 8 -opt:inline:** -Wopt -Werror // class C { val cv = Map[Int, Int](1 -> 2) diff --git a/test/files/neg/t3664.check b/test/files/neg/t3664.check index c305f04de069..36da8817db82 100644 --- a/test/files/neg/t3664.check +++ b/test/files/neg/t3664.check @@ -1,6 +1,11 @@ -t3664.scala:9: warning: Synthetic case companion used as a Function, use explicit object with Function parent - def f(xs: List[Int]): List[C] = xs.map(C) +t3664.scala:10: error: Synthetic case companion used as a function. In Scala 3 (or with -Xsource-features:case-companion-function), case companions no longer extend FunctionN. Use C.apply instead. [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Test.f + def f(xs: List[Int]): List[C] = xs.map(C) // ident ^ -error: No warnings can be incurred under -Werror. -1 warning -1 error +t3664.scala:11: error: Synthetic case companion used as a function. In Scala 3 (or with -Xsource-features:case-companion-function), case companions no longer extend FunctionN. Use D.apply instead. [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Test.g + def g(xs: List[Int]): List[O.D] = xs.map(O.D) // select + ^ +2 errors diff --git a/test/files/neg/t3664.scala b/test/files/neg/t3664.scala index 2282eaabc92b..60ccc8462d57 100644 --- a/test/files/neg/t3664.scala +++ b/test/files/neg/t3664.scala @@ -1,10 +1,12 @@ -//> using options -Werror -Xlint -Xsource:3 +//> using options -Xsource:3 // use -Xsource:3 to warn that implicitly extending Function is deprecated -// use -Xsource:3-cross for dotty behavior: no extend Function, yes adapt C.apply.tupled +// use -Xsource-features for dotty behavior: no extend Function, yes adapt C.apply.tupled case class C(i: Int) +object O { case class D(i: Int) } class Test { - def f(xs: List[Int]): List[C] = xs.map(C) + def f(xs: List[Int]): List[C] = xs.map(C) // ident + def g(xs: List[Int]): List[O.D] = xs.map(O.D) // select } diff --git a/test/files/neg/t3664b.check b/test/files/neg/t3664b.check index 6f105a9d079b..9119412b0e91 100644 --- a/test/files/neg/t3664b.check +++ b/test/files/neg/t3664b.check @@ -1,6 +1,9 @@ -t3664b.scala:9: warning: The method `apply` is inserted. The auto insertion will be deprecated, please write `C.apply` explicitly. - def f(xs: List[Int]): List[C] = xs.map(C) +t3664b.scala:10: warning: The method `apply` is inserted. The auto insertion will be deprecated, please write `C.apply` explicitly. + def f(xs: List[Int]): List[C] = xs.map(C) // ident ^ +t3664b.scala:11: warning: The method `apply` is inserted. The auto insertion will be deprecated, please write `D.apply` explicitly. + def g(xs: List[Int]): List[O.D] = xs.map(O.D) // select + ^ error: No warnings can be incurred under -Werror. -1 warning +2 warnings 1 error diff --git a/test/files/neg/t3664b.scala b/test/files/neg/t3664b.scala index 26181da99a12..d13a2eb32c80 100644 --- a/test/files/neg/t3664b.scala +++ b/test/files/neg/t3664b.scala @@ -1,10 +1,12 @@ -//> using options -Werror -Xlint -Xsource:3-cross +//> using options -Werror -Xsource:3 -Xsource-features:case-companion-function -deprecation // use -Xsource:3 to warn that implicitly extending Function is deprecated -// use -Xsource:3-cross for dotty behavior: no extend Function, yes adapt C.apply.tupled +// use -Xsource-features for dotty behavior: no extend Function, yes adapt C.apply.tupled case class C(i: Int) +object O { case class D(i: Int) } class Test { - def f(xs: List[Int]): List[C] = xs.map(C) + def f(xs: List[Int]): List[C] = xs.map(C) // ident + def g(xs: List[Int]): List[O.D] = xs.map(O.D) // select } diff --git a/test/files/neg/t3664c.check b/test/files/neg/t3664c.check index ff0a0b1870df..614526c15ef5 100644 --- a/test/files/neg/t3664c.check +++ b/test/files/neg/t3664c.check @@ -15,10 +15,10 @@ t3664c.scala:24: error: type mismatch; ^ t3664c.scala:26: warning: An unapplied 0-arity method was eta-expanded (due to the expected type () => E), rather than applied to `()`. Write E.apply() to invoke method apply, or change the expected type. - val e: () => E = E + val e: () => E = E // apply insertion warning, plus lint warning about 0-arity eta expansion ^ t3664c.scala:26: warning: The method `apply` is inserted. The auto insertion will be deprecated, please write `E.apply` explicitly. - val e: () => E = E + val e: () => E = E // apply insertion warning, plus lint warning about 0-arity eta expansion ^ t3664c.scala:28: warning: The method `apply` is inserted. The auto insertion will be deprecated, please write `F.apply` explicitly. def ov(xs: List[Int]): List[F] = xs.map(F) diff --git a/test/files/neg/t3664c.scala b/test/files/neg/t3664c.scala index 470fc7f725fa..16b5ab08931a 100644 --- a/test/files/neg/t3664c.scala +++ b/test/files/neg/t3664c.scala @@ -1,7 +1,7 @@ -//> using options -Werror -Xlint -Xsource:3-cross +//> using options -Werror -Xlint -Xsource:3 -Xsource-features:case-companion-function // use -Xsource:3 to warn that implicitly extending Function is deprecated -// use -Xsource:3-cross for dotty behavior: no extend Function, yes adapt C.apply.tupled +// use -Xsource-features for dotty behavior: no extend Function, yes adapt C.apply.tupled case class C(i: Int, j: Int) @@ -23,7 +23,7 @@ class Test { def d(xs: List[(Int, Int)]): List[D] = xs.map(D) // hard error - val e: () => E = E + val e: () => E = E // apply insertion warning, plus lint warning about 0-arity eta expansion def ov(xs: List[Int]): List[F] = xs.map(F) } diff --git a/test/files/neg/t3683a.scala b/test/files/neg/t3683a.scala index 8047d4b172a1..cf06ef26094c 100644 --- a/test/files/neg/t3683a.scala +++ b/test/files/neg/t3683a.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait Foo sealed trait Bar extends Foo diff --git a/test/files/neg/t3692-new.scala b/test/files/neg/t3692-new.scala index 063e141cb4a3..3a3531270cda 100644 --- a/test/files/neg/t3692-new.scala +++ b/test/files/neg/t3692-new.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // import scala.reflect.{ClassTag, classTag} import java.lang.Integer diff --git a/test/files/neg/t4302.scala b/test/files/neg/t4302.scala index 6498a0f29ced..233250d212d9 100644 --- a/test/files/neg/t4302.scala +++ b/test/files/neg/t4302.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def hasMatch[T](x: AnyRef) = x.isInstanceOf[T] diff --git a/test/files/neg/t4440.scala b/test/files/neg/t4440.scala index 8fe7346e315e..21d99b89d804 100644 --- a/test/files/neg/t4440.scala +++ b/test/files/neg/t4440.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // constructors used to drop outer fields when they were not accessed // however, how can you know (respecting separate compilation) that they're not accessed!? diff --git a/test/files/neg/t4691_exhaust_extractor.scala b/test/files/neg/t4691_exhaust_extractor.scala index 683aca76f7af..c1f8bd498ab5 100644 --- a/test/files/neg/t4691_exhaust_extractor.scala +++ b/test/files/neg/t4691_exhaust_extractor.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait Foo class Bar1 extends Foo diff --git a/test/files/neg/t4701.scala b/test/files/neg/t4701.scala index 54ec087dd07f..f14cae85fd63 100644 --- a/test/files/neg/t4701.scala +++ b/test/files/neg/t4701.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// trait HL[A] object HN { def :: [A](x: A): HL[A] = new HL[A] {} @@ -7,4 +7,4 @@ object Test { import Predef.{identity => hasType} final val nnn = 1 hasType[HL[String]](nnn :: HN) // type mismatch error should have position at `nnn` -} \ No newline at end of file +} diff --git a/test/files/neg/t4749.scala b/test/files/neg/t4749.scala index 858937f78740..f9521d47ddce 100644 --- a/test/files/neg/t4749.scala +++ b/test/files/neg/t4749.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // package bippy { object Fail1 { diff --git a/test/files/neg/t4762.scala b/test/files/neg/t4762.scala index 7fb73ee13780..c56924bea198 100644 --- a/test/files/neg/t4762.scala +++ b/test/files/neg/t4762.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Xfatal-warnings +//> using options -Xlint -Xfatal-warnings // // https://github.com/scala/bug/issues/4762 diff --git a/test/files/neg/t4851/S.scala b/test/files/neg/t4851/S.scala index ba22f93452e4..3ebe93a9d775 100644 --- a/test/files/neg/t4851/S.scala +++ b/test/files/neg/t4851/S.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:adapted-args -Xfatal-warnings -deprecation +//> using options -Xlint:adapted-args -Xfatal-warnings -deprecation // object Test { val x1 = new J diff --git a/test/files/neg/t4940.check b/test/files/neg/t4940.check new file mode 100644 index 000000000000..3b26c3117d0c --- /dev/null +++ b/test/files/neg/t4940.check @@ -0,0 +1,31 @@ +t4940.scala:3: error: type mismatch; + found : String("x") + required: Int + val f: PartialFunction[String, Int] = (x: Int) => x match { case "x" => 3 } // error + ^ +t4940.scala:3: error: type mismatch; + found : scala.runtime.AbstractPartialFunction[Int,Int] with java.io.Serializable + required: PartialFunction[String,Int] + val f: PartialFunction[String, Int] = (x: Int) => x match { case "x" => 3 } // error + ^ +t4940.scala:5: error: type mismatch; + found : String("x") + required: X + val g: PartialFunction[String, Int] = (x: X) => x match { case "x" => 3 } // error + ^ +t4940.scala:5: error: type mismatch; + found : scala.runtime.AbstractPartialFunction[X,Int] with java.io.Serializable + required: PartialFunction[String,Int] + val g: PartialFunction[String, Int] = (x: X) => x match { case "x" => 3 } // error + ^ +t4940.scala:7: error: type mismatch; + found : scala.runtime.AbstractPartialFunction[Double,Int] with java.io.Serializable + required: PartialFunction[Int,Int] + val m: PartialFunction[Int, Int] = (x: Double) => x match { case 3.14 => 3 } // error + ^ +t4940.scala:9: error: type mismatch; + found : scala.runtime.AbstractPartialFunction[X,Int] with java.io.Serializable + required: PartialFunction[Y,Int] + val g3: PartialFunction[Y, Int] = (x: X) => x match { case _: X => 3 } // error + ^ +6 errors diff --git a/test/files/neg/t4940.scala b/test/files/neg/t4940.scala new file mode 100644 index 000000000000..6c8d1c7bafd4 --- /dev/null +++ b/test/files/neg/t4940.scala @@ -0,0 +1,21 @@ +//> using options -Werror -Xlint +class C { + val f: PartialFunction[String, Int] = (x: Int) => x match { case "x" => 3 } // error + + val g: PartialFunction[String, Int] = (x: X) => x match { case "x" => 3 } // error + + val m: PartialFunction[Int, Int] = (x: Double) => x match { case 3.14 => 3 } // error + + val g3: PartialFunction[Y, Int] = (x: X) => x match { case _: X => 3 } // error +} + +class Y +class X extends Y + +object Test extends App { + val c = new C + println(c.f.applyOrElse("hello, world", (s: String) => -1)) + println(c.f.applyOrElse("x", (s: String) => -1)) + println(c.g.applyOrElse("hello, world", (s: String) => -1)) + println(c.m.applyOrElse(42, (n: Int) => -1)) +} diff --git a/test/files/neg/t5182.scala b/test/files/neg/t5182.scala index 32f2ed534830..2eeb0960cfa2 100644 --- a/test/files/neg/t5182.scala +++ b/test/files/neg/t5182.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class test { @java.lang.Deprecated(qwe = "wer") def ok(q:Int) = 1 diff --git a/test/files/neg/t5197.scala b/test/files/neg/t5197.scala index 8e568ea47660..61f2a535220a 100644 --- a/test/files/neg/t5197.scala +++ b/test/files/neg/t5197.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -feature +//> using options -Werror -feature // Periodic reminder that the feature is not required for implicit function values. //import scala.language.implicitConversions diff --git a/test/files/neg/t521.scala b/test/files/neg/t521.scala index c6afebc0be0b..9ee529e9d8a7 100644 --- a/test/files/neg/t521.scala +++ b/test/files/neg/t521.scala @@ -11,7 +11,7 @@ class PlainFile(val file : File) extends AbstractFile {} class VirtualFile(val name : String, val path : String) extends AbstractFile {} final class ZipArchive(val file : File, archive : ZipFile) extends PlainFile(file) { - class Entry(name : String, path : String) extends VirtualFile(name, path) { + class Entry(name : String, path0 : String) extends VirtualFile(name, path0) { override def path = ""; } } diff --git a/test/files/neg/t521b.check b/test/files/neg/t521b.check new file mode 100644 index 000000000000..0b120275927f --- /dev/null +++ b/test/files/neg/t521b.check @@ -0,0 +1,6 @@ +t521b.scala:16: error: Double definition will be detected in Scala 3; the conflicting value path is defined at 15:30 +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=test.ZipArchive.Entry + override def path = ""; + ^ +1 error diff --git a/test/files/neg/t521b.scala b/test/files/neg/t521b.scala new file mode 100644 index 000000000000..064e59825d97 --- /dev/null +++ b/test/files/neg/t521b.scala @@ -0,0 +1,18 @@ +//> using options -Xsource:3 +package test + +import java.io.File +import java.util.zip.ZipFile + +abstract class AbstractFile { + def path : String; +} + +class PlainFile(val file : File) extends AbstractFile {} +class VirtualFile(val name : String, val path : String) extends AbstractFile {} + +final class ZipArchive(val file : File, archive : ZipFile) extends PlainFile(file) { + class Entry(name : String, path : String) extends VirtualFile(name, path) { + override def path = ""; + } +} diff --git a/test/files/neg/t5265a.scala b/test/files/neg/t5265a.scala index 80b127e1adeb..42984206bdf5 100644 --- a/test/files/neg/t5265a.scala +++ b/test/files/neg/t5265a.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror trait T[A] class C[A: T] diff --git a/test/files/neg/t5265b.check b/test/files/neg/t5265b.check index 2bc7768075fb..7e761d661c4a 100644 --- a/test/files/neg/t5265b.check +++ b/test/files/neg/t5265b.check @@ -1,11 +1,11 @@ t5265b.scala:7: error: Implicit definition must have explicit type (inferred T[String]) [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Missing.tsMissing implicit val tsMissing = new T[String] {} // warn val in trait ^ -t5265b.scala:20: error: under -Xsource:3-cross, the inferred type changes to T[String] [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +t5265b.scala:20: error: Implicit definition must have explicit type (inferred T[String]) [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Child.tsChild - implicit val tsChild = new T[String] {} // nowarn because inferred from overridden + implicit val tsChild = new T[String] {} // warn (no warn with -Xsource-features:infer-override) ^ 2 errors diff --git a/test/files/neg/t5265b.scala b/test/files/neg/t5265b.scala index 59d0d1c7e522..45b2170fc7d9 100644 --- a/test/files/neg/t5265b.scala +++ b/test/files/neg/t5265b.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 trait T[A] class C[A: T] @@ -17,6 +17,6 @@ trait Parent { def tsChild: T[String] } trait Child extends Parent { - implicit val tsChild = new T[String] {} // nowarn because inferred from overridden + implicit val tsChild = new T[String] {} // warn (no warn with -Xsource-features:infer-override) def f = new C[String] } diff --git a/test/files/neg/t5352.scala b/test/files/neg/t5352.scala index 5e54d345b36c..2dd99003d0bc 100644 --- a/test/files/neg/t5352.scala +++ b/test/files/neg/t5352.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object boop { abstract class Bar { protected def f(): Any } diff --git a/test/files/neg/t5357.check b/test/files/neg/t5357.check index 96f40026eb95..29d5a3a04337 100644 --- a/test/files/neg/t5357.check +++ b/test/files/neg/t5357.check @@ -1,4 +1,4 @@ t5357.scala:5: error: Pattern variables must start with a lower-case letter. (SLS 8.1.1.) case A: N => 1 - ^ + ^ 1 error diff --git a/test/files/neg/t5365.scala b/test/files/neg/t5365.scala index 25a6dcc8cf67..087635454d3f 100644 --- a/test/files/neg/t5365.scala +++ b/test/files/neg/t5365.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings class C { def nonExhautiveIfWeAssumeGuardsTrueOrFalse(x: Option[Int]): Int = x match { case Some(n) if n % 2 == 0 => n diff --git a/test/files/neg/t5365b.scala b/test/files/neg/t5365b.scala index 25a6dcc8cf67..087635454d3f 100644 --- a/test/files/neg/t5365b.scala +++ b/test/files/neg/t5365b.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings class C { def nonExhautiveIfWeAssumeGuardsTrueOrFalse(x: Option[Int]): Int = x match { case Some(n) if n % 2 == 0 => n diff --git a/test/files/neg/t5365c.scala b/test/files/neg/t5365c.scala index d79cd905c0d4..3c460b59d56d 100644 --- a/test/files/neg/t5365c.scala +++ b/test/files/neg/t5365c.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +//> using options -Xfatal-warnings -Xlint:strict-unsealed-patmat object C { trait Z final case class Q(i: Int) extends Z diff --git a/test/files/neg/t5365d.scala b/test/files/neg/t5365d.scala index eab29e7ecead..6f84c2eaf2b8 100644 --- a/test/files/neg/t5365d.scala +++ b/test/files/neg/t5365d.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings object D { sealed trait T final case class C(i: Int) extends T diff --git a/test/files/neg/t5365e.scala b/test/files/neg/t5365e.scala index 5975587cbf94..f06c70b11a60 100644 --- a/test/files/neg/t5365e.scala +++ b/test/files/neg/t5365e.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings sealed trait Exh final case class Foo(xs: String*) extends Exh final case class Bar(x: String) extends Exh diff --git a/test/files/neg/t5426.scala b/test/files/neg/t5426.scala index 14a24529142f..de8480f8b826 100644 --- a/test/files/neg/t5426.scala +++ b/test/files/neg/t5426.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A { def f1 = Some(5) == 5 diff --git a/test/files/neg/t5440.scala b/test/files/neg/t5440.scala index c0322af55841..dbbad683338e 100644 --- a/test/files/neg/t5440.scala +++ b/test/files/neg/t5440.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def merge(list1: List[Long], list2: List[Long]): Boolean = diff --git a/test/files/neg/t5507.scala b/test/files/neg/t5507.scala index 912fad66702d..63a9e6604de9 100644 --- a/test/files/neg/t5507.scala +++ b/test/files/neg/t5507.scala @@ -1,5 +1,5 @@ // -// scalac: -Xlint:unit-special -Werror +//> using options -Xlint:unit-special -Werror // warn once final class C[@specialized A, @specialized B](a: A, b: B) diff --git a/test/files/neg/t556.check b/test/files/neg/t556.check index 90fdda442f91..98f0443a5642 100644 --- a/test/files/neg/t556.check +++ b/test/files/neg/t556.check @@ -4,4 +4,9 @@ t556.scala:3: error: missing parameter type t556.scala:3: error: missing parameter type def g: Int = f((x, y) => x) ^ -2 errors +t556.scala:3: error: type mismatch; + found : (?, ?) => ? + required: Int => Int + def g: Int = f((x, y) => x) + ^ +3 errors diff --git a/test/files/neg/t5606.check b/test/files/neg/t5606.check index 0d80bad04fc2..5d68161a431b 100644 --- a/test/files/neg/t5606.check +++ b/test/files/neg/t5606.check @@ -5,22 +5,22 @@ t5606.scala:23: error: using `?` as a type name requires backticks. [quickfixabl def regress_?[F[?]] = 2 ^ t5606.scala:3: error: Top-level wildcard is not allowed -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration case class CaseTest[_](someData: String) ^ t5606.scala:8: error: Top-level wildcard is not allowed -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration case class CaseTest2[_, _](someData: String) ^ t5606.scala:8: error: Top-level wildcard is not allowed -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration case class CaseTest2[_, _](someData: String) ^ t5606.scala:11: error: Top-level wildcard is not allowed -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f[_](x: Int) = ??? ^ diff --git a/test/files/neg/t5606.scala b/test/files/neg/t5606.scala index c44b1e96e378..fed05b645f69 100644 --- a/test/files/neg/t5606.scala +++ b/test/files/neg/t5606.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // was: _ taken as ident of type param, but poor interactions below case class CaseTest[_](someData: String) diff --git a/test/files/neg/t5606b.scala b/test/files/neg/t5606b.scala index 3931de26d43b..eef807300770 100644 --- a/test/files/neg/t5606b.scala +++ b/test/files/neg/t5606b.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror // // was: _ taken as ident of type param, now a fresh name case class CaseTest[_](someData: String) diff --git a/test/files/neg/t5663-badwarneq.scala b/test/files/neg/t5663-badwarneq.scala index f920d6e88f42..4646b9fd011d 100644 --- a/test/files/neg/t5663-badwarneq.scala +++ b/test/files/neg/t5663-badwarneq.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // alias diff --git a/test/files/neg/t5675.scala b/test/files/neg/t5675.scala index baaabaf89ef0..1e414307798a 100644 --- a/test/files/neg/t5675.scala +++ b/test/files/neg/t5675.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // without -feature, don't double-count the warning // diff --git a/test/files/neg/t5689.scala b/test/files/neg/t5689.scala index e973c6f74c26..23462a860ee6 100644 --- a/test/files/neg/t5689.scala +++ b/test/files/neg/t5689.scala @@ -1,4 +1,4 @@ -// scalac: -language:experimental.macros +//> using options -language:experimental.macros // import scala.reflect.macros.blackbox.Context diff --git a/test/files/neg/t5691.scala b/test/files/neg/t5691.scala index 42cc75e45f0f..3624e200910d 100644 --- a/test/files/neg/t5691.scala +++ b/test/files/neg/t5691.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:type-parameter-shadow -language:higherKinds -Xfatal-warnings +//> using options -Xlint:type-parameter-shadow -language:higherKinds -Xfatal-warnings // class B { diff --git a/test/files/neg/t5715.scala b/test/files/neg/t5715.scala index fe76dee9b53a..5ea9c2a3af7a 100644 --- a/test/files/neg/t5715.scala +++ b/test/files/neg/t5715.scala @@ -1,5 +1,5 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror package example diff --git a/test/files/neg/t5762.scala b/test/files/neg/t5762.scala index 8290920d0e7a..a2341860f600 100644 --- a/test/files/neg/t5762.scala +++ b/test/files/neg/t5762.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class D[-A] diff --git a/test/files/neg/t5801.check b/test/files/neg/t5801.check index f1e672c02e46..d8156d3f6340 100644 --- a/test/files/neg/t5801.check +++ b/test/files/neg/t5801.check @@ -1,6 +1,6 @@ t5801.scala:1: error: object sth is not a member of package scala import scala.sth - ^ + ^ t5801.scala:4: error: not found: value sth def foo(a: Int)(implicit b: sth.Sth): Unit = {} ^ diff --git a/test/files/neg/t5830.scala b/test/files/neg/t5830.scala index 9c46e2bcd90b..8a3f96485f95 100644 --- a/test/files/neg/t5830.scala +++ b/test/files/neg/t5830.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import scala.annotation.switch diff --git a/test/files/neg/t5898.scala b/test/files/neg/t5898.scala index b4eed38e3388..23057bc7b09e 100644 --- a/test/files/neg/t5898.scala +++ b/test/files/neg/t5898.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:valpattern -Xfatal-warnings +//> using options -Xlint:valpattern -Xfatal-warnings // sealed trait T case class C(i: Int) extends T diff --git a/test/files/neg/t5956.scala b/test/files/neg/t5956.scala index 3c189fe8e541..507e721f4043 100644 --- a/test/files/neg/t5956.scala +++ b/test/files/neg/t5956.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // object O { case class C[T](); class C() } object T { case class C[T](); case class C() } diff --git a/test/files/neg/t6011.scala b/test/files/neg/t6011.scala index 3cd7f7c62500..c909c4e4691b 100644 --- a/test/files/neg/t6011.scala +++ b/test/files/neg/t6011.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def f(ch: Char): Any = ch match { diff --git a/test/files/neg/t6048.scala b/test/files/neg/t6048.scala index e21bfeee0836..431cb6adde64 100644 --- a/test/files/neg/t6048.scala +++ b/test/files/neg/t6048.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A { def f1(x: Int) = x match { diff --git a/test/files/neg/t6120.scala b/test/files/neg/t6120.scala index 51c007d8af54..dc86ef752102 100644 --- a/test/files/neg/t6120.scala +++ b/test/files/neg/t6120.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xmigration:2.10 -Xfatal-warnings +//> using options -deprecation -Werror -Xmigration:2.10 // // showing that multiple warnings at same location are reported // diff --git a/test/files/neg/t6123-explaintypes-macros/BadMac_2.scala b/test/files/neg/t6123-explaintypes-macros/BadMac_2.scala index 65303fb6e6dd..c9d33756d6a7 100644 --- a/test/files/neg/t6123-explaintypes-macros/BadMac_2.scala +++ b/test/files/neg/t6123-explaintypes-macros/BadMac_2.scala @@ -1,4 +1,4 @@ -// scalac: -explaintypes +//> using options -explaintypes import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/neg/t6123-explaintypes-macros/Macros.scala b/test/files/neg/t6123-explaintypes-macros/Macros.scala index 21979a86207d..a6feb5b88dbc 100644 --- a/test/files/neg/t6123-explaintypes-macros/Macros.scala +++ b/test/files/neg/t6123-explaintypes-macros/Macros.scala @@ -1,4 +1,4 @@ -// scalac: -explaintypes +//> using options -explaintypes import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/neg/t6159.scala b/test/files/neg/t6159.scala index 2e7477a299c7..71abea905e54 100644 --- a/test/files/neg/t6159.scala +++ b/test/files/neg/t6159.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // like test/files/pos/t6159.scala // but with T2 not private trait A { diff --git a/test/files/neg/t6162-inheritance/defn.scala b/test/files/neg/t6162-inheritance/defn.scala index 8b77690c0ac2..673ea4dbfd1b 100644 --- a/test/files/neg/t6162-inheritance/defn.scala +++ b/test/files/neg/t6162-inheritance/defn.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Werror +//> using options -deprecation -Werror package scala.t6126 @deprecatedInheritance("`Foo` will be made final in a future version.", "2.10.0") diff --git a/test/files/neg/t6162-overriding.scala b/test/files/neg/t6162-overriding.scala index 4667536ae9f3..17932569c129 100644 --- a/test/files/neg/t6162-overriding.scala +++ b/test/files/neg/t6162-overriding.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation // package scala.t6162 diff --git a/test/files/neg/t6217.scala b/test/files/neg/t6217.scala index 931fe8c13930..58cce7844fbe 100644 --- a/test/files/neg/t6217.scala +++ b/test/files/neg/t6217.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package p { package _root_ { package scala { diff --git a/test/files/neg/t6217b.scala b/test/files/neg/t6217b.scala index a33cae6eca7e..923effa94171 100644 --- a/test/files/neg/t6217b.scala +++ b/test/files/neg/t6217b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package p package _root_ object Test { diff --git a/test/files/neg/t6217c.scala b/test/files/neg/t6217c.scala index f27162811d96..439aad07c106 100644 --- a/test/files/neg/t6217c.scala +++ b/test/files/neg/t6217c.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package b { class B } diff --git a/test/files/neg/t6264.scala b/test/files/neg/t6264.scala index fdef3eb18ded..f7be7eff0f01 100644 --- a/test/files/neg/t6264.scala +++ b/test/files/neg/t6264.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class Foo { def foo(x: AnyRef): Unit = { diff --git a/test/files/neg/t6276.scala b/test/files/neg/t6276.scala index 76f8a00cc687..d236ee69885f 100644 --- a/test/files/neg/t6276.scala +++ b/test/files/neg/t6276.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def foo(a: Int, b: Int, c: Int): Unit = { diff --git a/test/files/neg/t6323a.scala b/test/files/neg/t6323a.scala index 182c31c609a1..a0d6324f8bb8 100644 --- a/test/files/neg/t6323a.scala +++ b/test/files/neg/t6323a.scala @@ -1,4 +1,4 @@ -// scalac: -Vimplicits +//> using options -Vimplicits // import scala.reflect.runtime.universe._ import scala.reflect.runtime.{currentMirror => m} diff --git a/test/files/neg/t6340.check b/test/files/neg/t6340.check index 329e860f020d..f2367a824f78 100644 --- a/test/files/neg/t6340.check +++ b/test/files/neg/t6340.check @@ -1,10 +1,16 @@ t6340.scala:11: error: value D is not a member of object Foo - import Foo.{ A, B, C, D, E, X, Y, Z } - ^ + import Foo.{ A, B, C, D, E, F => G, X, Y, Z } + ^ +t6340.scala:11: error: value E is not a member of object Foo + import Foo.{ A, B, C, D, E, F => G, X, Y, Z } + ^ +t6340.scala:11: error: value F is not a member of object Foo + import Foo.{ A, B, C, D, E, F => G, X, Y, Z } + ^ t6340.scala:16: error: not found: type D val d = new D ^ t6340.scala:17: error: not found: type W val w = new W ^ -3 errors +5 errors diff --git a/test/files/neg/t6340.scala b/test/files/neg/t6340.scala index 8934d5c15d6f..1d56ac2134df 100644 --- a/test/files/neg/t6340.scala +++ b/test/files/neg/t6340.scala @@ -8,7 +8,7 @@ object Foo { } object Test { - import Foo.{ A, B, C, D, E, X, Y, Z } + import Foo.{ A, B, C, D, E, F => G, X, Y, Z } val a = new A val b = new B diff --git a/test/files/neg/t6446-additional/sample_2.scala b/test/files/neg/t6446-additional/sample_2.scala index 597b70cc65ac..f9d2a3e52360 100644 --- a/test/files/neg/t6446-additional/sample_2.scala +++ b/test/files/neg/t6446-additional/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Vphases +//> using options -Xplugin:. -Vphases package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t6446-list/sample_2.scala b/test/files/neg/t6446-list/sample_2.scala index e3bf6cd14603..55d8bb1625d7 100644 --- a/test/files/neg/t6446-list/sample_2.scala +++ b/test/files/neg/t6446-list/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-list +//> using options -Xplugin:. -Xplugin-list package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t6446-missing/sample_2.scala b/test/files/neg/t6446-missing/sample_2.scala index 597b70cc65ac..f9d2a3e52360 100644 --- a/test/files/neg/t6446-missing/sample_2.scala +++ b/test/files/neg/t6446-missing/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Vphases +//> using options -Xplugin:. -Vphases package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t6446-show-phases.scala b/test/files/neg/t6446-show-phases.scala index d0bd64b20973..016067364f1d 100644 --- a/test/files/neg/t6446-show-phases.scala +++ b/test/files/neg/t6446-show-phases.scala @@ -1,4 +1,4 @@ -// scalac: -Vphases +//> using options -Vphases // // testing compiler flag output only diff --git a/test/files/neg/t6534.scala b/test/files/neg/t6534.scala index 14144fd375b9..c80af5fc4c4b 100644 --- a/test/files/neg/t6534.scala +++ b/test/files/neg/t6534.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint +//> using options -Xlint // trait Foo extends Any { override def equals(x: Any) = false } trait Ding extends Any { override def hashCode = -1 } diff --git a/test/files/neg/t6567.scala b/test/files/neg/t6567.scala index 43d46231ca4e..3e300f9f7053 100644 --- a/test/files/neg/t6567.scala +++ b/test/files/neg/t6567.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:option-implicit -Xfatal-warnings +//> using options -Xlint:option-implicit -Xfatal-warnings // class A class B diff --git a/test/files/neg/t6582_exhaust_big.scala b/test/files/neg/t6582_exhaust_big.scala index ee0649c2b4e2..6f53cd24f28a 100644 --- a/test/files/neg/t6582_exhaust_big.scala +++ b/test/files/neg/t6582_exhaust_big.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class Z object Z { diff --git a/test/files/neg/t6593.check b/test/files/neg/t6593.check new file mode 100644 index 000000000000..1554440bd723 --- /dev/null +++ b/test/files/neg/t6593.check @@ -0,0 +1,147 @@ +t6593.scala:69: warning: comparing values of types Any and Int using `equals` unsafely bypasses cooperative equality; use `==` instead + any equals 1 // w: bypass + ^ +t6593.scala:77: warning: Cls and FinCls are unrelated: they will most likely never compare equal + cls == fin // w: unrelated + ^ +t6593.scala:78: warning: Cls and Eqs are unrelated: they will most likely never compare equal + cls == eqs // w: unrelated + ^ +t6593.scala:79: warning: Cls and String are unrelated: they will most likely never compare equal + cls == str // w: unrelated + ^ +t6593.scala:80: warning: Cls and List[Int] are unrelated: they will most likely never compare equal + cls == lst // w: unrelated + ^ +t6593.scala:81: warning: Cls and scala.collection.immutable.Nil.type are unrelated: they will most likely never compare equal + cls == Nil // w: unrelated + ^ +t6593.scala:82: warning: Cls and Int are unrelated: they will most likely never compare equal + cls == 1 // w: unrelated + ^ +t6593.scala:83: warning: Cls and Integer are unrelated: they will most likely never compare equal + cls == intB // w: unrelated + ^ +t6593.scala:90: warning: SubCls and FinCls are unrelated: they will most likely never compare equal + sub == fin // w: unrelated + ^ +t6593.scala:94: warning: FinCls and Cls are unrelated: they will most likely never compare equal + fin == cls // w: unrelated + ^ +t6593.scala:95: warning: comparing values of types FinCls and Int using `==` will always yield false + fin == 1 // w: non-sensible + ^ +t6593.scala:96: warning: comparing values of types FinCls and String using `==` will always yield false + fin == str // w: non-sensible + ^ +t6593.scala:97: warning: FinCls and List[Int] are unrelated: they will most likely never compare equal + fin == lst // w: unrelated + ^ +t6593.scala:98: warning: comparing values of types FinCls and scala.collection.immutable.Nil.type using `==` will always yield false + fin == Nil // w: non-sensible (both are final, unlike the line above) + ^ +t6593.scala:99: warning: comparing a fresh object using `==` will always yield false + fin == new AnyRef() // w: final receiver, fresh + ^ +t6593.scala:110: warning: comparing values of types CC and Cls using `==` will always yield false + cc == cls // w: non-sensible + ^ +t6593.scala:111: warning: comparing values of types CC and Cls using `==` will always yield false + scc == cls // w: non-sensible (wrong) + ^ +t6593.scala:112: warning: comparing values of types CC and Int using `==` will always yield false + cc == 1 // w: non-sensible + ^ +t6593.scala:117: warning: comparing values of types String and Cls using `==` will always yield false + str == cls // w: non-sensible + ^ +t6593.scala:118: warning: comparing values of types String and Int using `==` will always yield false + str == 1 // w: non-sensible + ^ +t6593.scala:120: warning: comparing values of types String and Option[Int] using `!=` will always yield true + str != opt // w: non-sensible + ^ +t6593.scala:130: warning: Option[Int] and Cls are unrelated: they will most likely never compare equal + opt == cls // w: unrelated + ^ +t6593.scala:131: warning: Option[Int] and Int are unrelated: they will most likely never compare equal + opt == 1 // w: unrelated + ^ +t6593.scala:132: warning: Option[Int] and String are unrelated: they will most likely never compare equal + opt == str // w: unrelated + ^ +t6593.scala:133: warning: Option[Int] and List[Int] are unrelated: they will most likely never compare equal + opt == lst // w: unrelated + ^ +t6593.scala:137: warning: comparing values of types Some[Int] and Cls using `==` will always yield false + som == cls // w: non-sensible + ^ +t6593.scala:138: warning: comparing values of types Some[Int] and Int using `==` will always yield false + som == 1 // w: non-sensible + ^ +t6593.scala:139: warning: comparing values of types Some[Int] and String using `==` will always yield false + som == str // w: non-sensible + ^ +t6593.scala:144: warning: comparing values of types List[Int] and Cls using `==` will always yield false + lst == cls // w: non-sensible (collections) + ^ +t6593.scala:145: warning: comparing values of types List[Int] and Int using `==` will always yield false + lst == 1 // w: non-sensible (collections) + ^ +t6593.scala:146: warning: comparing values of types List[Int] and Option[Int] using `==` will always yield false + lst == opt // w: non-sensible (collections) + ^ +t6593.scala:147: warning: comparing values of types List[Int] and String using `==` will always yield false + lst == str // w: non-sensible (collections) + ^ +t6593.scala:148: warning: comparing values of types List[Int] and scala.collection.immutable.Set[Int] using `==` will always yield false + lst == set // w: non-sensible (collections) + ^ +t6593.scala:150: warning: comparing values of types List[Int] and scala.collection.mutable.Map[Int,Int] using `==` will always yield false + lst == map // w: non-sensible (collections) + ^ +t6593.scala:151: warning: comparing values of types List[Int] and Eqs using `==` will always yield false + lst == eqs // w: non-sensible (collections) + ^ +t6593.scala:153: warning: comparing values of types List[Int] and Iterator[Int] using `==` will always yield false + lst == itr // w: non-sensible (collections) + ^ +t6593.scala:159: warning: comparing values of types Int and Cls using `==` will always yield false + int == cls // w: non-sensible + ^ +t6593.scala:160: warning: comparing values of types Int and String using `==` will always yield false + int == "" // w: non-sensible + ^ +t6593.scala:162: warning: comparing values of types Int and Boolean using `==` will always yield false + int == true // w: non-sensible + ^ +t6593.scala:164: warning: comparing values of types Int and Boolean using `==` will always yield false + int == booB // w: non-sensible + ^ +t6593.scala:165: warning: comparing values of types Int and Unit using `==` will always yield false + int == () // w: non-sensible + ^ +t6593.scala:166: warning: comparing values of types Int and scala.runtime.BoxedUnit using `==` will always yield false + int == uniB // w: non-sensible + ^ +t6593.scala:172: warning: comparing values of types Null and Int using `==` will always yield false + null == int // w: non-sensible + ^ +t6593.scala:178: warning: comparing values of types Integer and Cls using `==` will always yield false + intB == cls // w: non-sensible + ^ +t6593.scala:179: warning: comparing values of types Integer and String using `==` will always yield false + intB == str // w: non-sensible + ^ +t6593.scala:183: warning: comparing values of types Integer and Boolean using `==` will always yield false + intB == true // w: non-sensible + ^ +t6593.scala:184: warning: comparing values of types Integer and Boolean using `==` will always yield false + intB == booB // w: non-sensible + ^ +t6593.scala:185: warning: comparing values of types Integer and Unit using `==` will always yield false + intB == () // w: non-sensible + ^ +error: No warnings can be incurred under -Werror. +48 warnings +1 error diff --git a/test/files/neg/t6593.scala b/test/files/neg/t6593.scala new file mode 100644 index 000000000000..c7685a219f25 --- /dev/null +++ b/test/files/neg/t6593.scala @@ -0,0 +1,198 @@ +//> using options -Xfatal-warnings -deprecation + +class Cls +class SubCls extends Cls + +final class FinCls + +class Eqs { + override def equals(o: Any): Boolean = super.equals(o) +} + +case class CC(x: Int) +class SubCC(x: Int) extends CC(x) { override def equals(o: Any) = true } + +class Hello2024 { + + // operations: ==, !=, eq, ne + // - todo: cover `eq/ne` extensively in this test + // - no "non-sensible" warnings when using equals + + // inventory + + val obj = new AnyRef + val any: Any = obj + + val cls = new Cls + val sub = new SubCls + val fin = new FinCls + + val eqs = new Eqs + + val cc = CC(1) + val scc: CC = new SubCC(1) + + val str = "kno" + val opt = Option(1) + val lst = List(1) + val set = Set(1) + val map = collection.mutable.Map(1 -> 1) + + // primitives: 1, true, () + val int = 1 + val boo = true + val uni = () + // null + + val intB = Integer.valueOf(1) + val booB = java.lang.Boolean.TRUE + val uniB = scala.runtime.BoxedUnit.UNIT + + // fresh: `new Cls`, () => 1 + + + // obj + locally { + // obj == any, references: doesn't warn, no need to test + obj == 1 // n + obj equals 1 // n + obj == () // n + obj == intB // n + obj == new Cls // n: no warn here, obj can be anything + obj == (() => 1) // n + } + + // any: same as obj. additional warning for "bypasses cooperative equality" when using equals + // instead of ==. not extensively tested here, this test is about a different warning. + locally { + any == 1 // n + any equals 1 // w: bypass + } + + // warning for unrelated classes ("will most likely never compare equal") + locally { + cls == obj // n + cls == any // n + cls == sub // n: related + cls == fin // w: unrelated + cls == eqs // w: unrelated + cls == str // w: unrelated + cls == lst // w: unrelated + cls == Nil // w: unrelated + cls == 1 // w: unrelated + cls == intB // w: unrelated + cls == new AnyRef() // n + } + + locally { + sub == cls // n: related + sub == obj // n + sub == fin // w: unrelated + } + + locally { + fin == cls // w: unrelated + fin == 1 // w: non-sensible + fin == str // w: non-sensible + fin == lst // w: unrelated + fin == Nil // w: non-sensible (both are final, unlike the line above) + fin == new AnyRef() // w: final receiver, fresh + } + + locally { + eqs == obj // n + eqs == cls // n: unrelated but custom equality (note that inverse warns "unrelated"). TODO scala/bug#6593 + eqs == 1 // n: but inverse warns "non-sensible" + } + + locally { + cc == obj // n + cc == cls // w: non-sensible + scc == cls // w: non-sensible (wrong) + cc == 1 // w: non-sensible + } + + locally { + str == obj // n + str == cls // w: non-sensible + str == 1 // w: non-sensible + str == "" // n + str != opt // w: non-sensible + str == null // n + val cs: CharSequence = "oy" + str == cs // n + cs == str // n + } + + locally { + // Option has no `equals` override, unlike List. Some has synthetic case-equals + opt == obj // n + opt == cls // w: unrelated + opt == 1 // w: unrelated + opt == str // w: unrelated + opt == lst // w: unrelated + + val som = Some(1) + som == obj //n + som == cls // w: non-sensible + som == 1 // w: non-sensible + som == str // w: non-sensible + } + + locally { + lst == obj // n + lst == cls // w: non-sensible (collections) + lst == 1 // w: non-sensible (collections) + lst == opt // w: non-sensible (collections) + lst == str // w: non-sensible (collections) + lst == set // w: non-sensible (collections) + lst == Seq(1) // n, both are Seqs + lst == map // w: non-sensible (collections) + lst == eqs // w: non-sensible (collections) + val itr = Iterator(1) + lst == itr // w: non-sensible (collections) + lst == (itr: scala.collection.IterableOnce[Int]) // n + } + + locally { + int == obj // n + int == cls // w: non-sensible + int == "" // w: non-sensible + int == 1L // n + int == true // w: non-sensible + int == intB // n + int == booB // w: non-sensible + int == () // w: non-sensible + int == uniB // w: non-sensible + } + + locally { + null == obj // n + null == cls // n + null == int // w: non-sensible + null == intB // n + } + + locally { + intB == obj // n + intB == cls // w: non-sensible + intB == str // w: non-sensible + intB == int // n + intB == 1L // n + intB == null // n + intB == true // w: non-sensible + intB == booB // w: non-sensible + intB == () // w: non-sensible + } +} + +/* +cooperative equality + - used when `primitive == Any/AnyRef` + - primitive is boxed, so it's a java.lang.Number + - if both java.lang.Number + - maintain scala semantics for boxed: (1: Any) equals (1L: Any) is true + - if one is ScalaNumber, always use its `equals`. to support `1 == BigInt(1)` + - also special cases java.lang.Character for ('a': Any) == 97 + - no special casing for strings / CharSequence +*/ diff --git a/test/files/neg/t6595.scala b/test/files/neg/t6595.scala index f64275ba794b..4cdc0f6d89a4 100644 --- a/test/files/neg/t6595.scala +++ b/test/files/neg/t6595.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation // import scala.annotation.switch diff --git a/test/files/neg/t6666.scala b/test/files/neg/t6666.scala index 077a79083d03..cf3d0010c96c 100644 --- a/test/files/neg/t6666.scala +++ b/test/files/neg/t6666.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline // class C(a: Any) object F { diff --git a/test/files/neg/t6666c.scala b/test/files/neg/t6666c.scala index 693eeff2eeee..7a8ec5e23b36 100644 --- a/test/files/neg/t6666c.scala +++ b/test/files/neg/t6666c.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline // class C(a: Any) class D extends C({def x = 0; object X { x }}) diff --git a/test/files/neg/t6675.scala b/test/files/neg/t6675.scala index 879fc6d5a41e..7cc97f36cdef 100644 --- a/test/files/neg/t6675.scala +++ b/test/files/neg/t6675.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object X { def unapply(s: String): Option[(Int,Int,Int)] = Some((1,2,3)) diff --git a/test/files/neg/t6675b.scala b/test/files/neg/t6675b.scala index 7ade88fbf2b4..2f494e08b539 100644 --- a/test/files/neg/t6675b.scala +++ b/test/files/neg/t6675b.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xlint +//> using options -deprecation -Xlint // object LeftOrRight { def unapply[A](value: Either[A, A]): Option[A] = value match { diff --git a/test/files/neg/t6714.scala b/test/files/neg/t6714.scala index 9a2b229588fa..9e9e41d51ecd 100644 --- a/test/files/neg/t6714.scala +++ b/test/files/neg/t6714.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // case class A(a: Int, index: Int) { diff --git a/test/files/neg/t6902.scala b/test/files/neg/t6902.scala index e2e7a5084dbe..680e6108481c 100644 --- a/test/files/neg/t6902.scala +++ b/test/files/neg/t6902.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { Some(Some(1)) collect { diff --git a/test/files/neg/t7014/t7014_2.scala b/test/files/neg/t7014/t7014_2.scala index f8c903128d13..94f8f1c05237 100644 --- a/test/files/neg/t7014/t7014_2.scala +++ b/test/files/neg/t7014/t7014_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package t7014 import ThreadSafetyLevel_1.COMPLETELY_THREADSAFE // refer to annotation so it gets parsed diff --git a/test/files/neg/t7020.scala b/test/files/neg/t7020.scala index 871938be8d82..f323456a9bca 100644 --- a/test/files/neg/t7020.scala +++ b/test/files/neg/t7020.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { // warning was non-deterministic diff --git a/test/files/neg/t7110.scala b/test/files/neg/t7110.scala index 3b62a05ac6b7..66aa076681c0 100644 --- a/test/files/neg/t7110.scala +++ b/test/files/neg/t7110.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { try { ??? } // warn diff --git a/test/files/neg/t7171.scala b/test/files/neg/t7171.scala index f259826e6343..aa3aaa9ef32d 100644 --- a/test/files/neg/t7171.scala +++ b/test/files/neg/t7171.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait T { final case class A() diff --git a/test/files/neg/t7171b.scala b/test/files/neg/t7171b.scala index 94cfa7826d1c..236603c02ce8 100644 --- a/test/files/neg/t7171b.scala +++ b/test/files/neg/t7171b.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait T { final case class A() diff --git a/test/files/neg/t7187-3.check b/test/files/neg/t7187-3.check index cd6125f0e9f3..64304640d40d 100644 --- a/test/files/neg/t7187-3.check +++ b/test/files/neg/t7187-3.check @@ -18,7 +18,7 @@ Write m2() to invoke method m2, or change the expected type. val t2: () => Any = m2 // eta-expanded with lint warning ^ t7187-3.scala:27: error: Methods without a parameter list and by-name params can no longer be converted to functions as `m _`, write a function literal `() => m` instead [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=EtaExpand214.t7 val t7 = m1 _ // error: eta-expanding a nullary method ^ diff --git a/test/files/neg/t7187-3.scala b/test/files/neg/t7187-3.scala index a3bc502ba6b1..c6291f9b96d9 100644 --- a/test/files/neg/t7187-3.scala +++ b/test/files/neg/t7187-3.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Xlint:eta-zero +//> using options -Xsource:3 -Xlint:eta-zero -Xsource-features:eta-expand-always // trait AcciSamZero { def apply(): Int } diff --git a/test/files/neg/t7187-deprecation.check b/test/files/neg/t7187-deprecation.check index 5b93c40b1c86..3e143bcb89f9 100644 --- a/test/files/neg/t7187-deprecation.check +++ b/test/files/neg/t7187-deprecation.check @@ -19,7 +19,7 @@ In Scala 3, an unapplied method like this will be eta-expanded into a function. val t5 = m2 // warn: apply, ()-insertion ^ t7187-deprecation.scala:31: error: Methods without a parameter list and by-name params can no longer be converted to functions as `m _`, write a function literal `() => m` instead [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=EtaExpand214.t7 val t7 = m1 _ // error: eta-expanding a nullary method ^ diff --git a/test/files/neg/t7187-deprecation.scala b/test/files/neg/t7187-deprecation.scala index 7808df726e59..6991036176ee 100644 --- a/test/files/neg/t7187-deprecation.scala +++ b/test/files/neg/t7187-deprecation.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -deprecation -Werror +//> using options -Xsource:3 -deprecation -Werror -Xsource-features:eta-expand-always // trait AcciSamZero { def apply(): Int } diff --git a/test/files/neg/t7187.check b/test/files/neg/t7187.check index aa6ea7a2f2a0..518f031589e5 100644 --- a/test/files/neg/t7187.check +++ b/test/files/neg/t7187.check @@ -17,7 +17,7 @@ Unspecified value parameter i. t7187.scala:29: error: _ must follow method; cannot follow String val t3d: Any = baz() _ // error: _ must follow method ^ -t7187.scala:38: error: missing argument list for method zup in class EtaExpandZeroArg +t7187.scala:38: error: missing argument list for method zup in class EtaExpandZeroArg of type (x: Int): Int Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `zup _` or `zup(_)` instead of `zup`. val t5a = zup // error in 2.13, eta-expansion in 3.0 diff --git a/test/files/neg/t7187.scala b/test/files/neg/t7187.scala index f58d7e49cb98..42ad461bf8b1 100644 --- a/test/files/neg/t7187.scala +++ b/test/files/neg/t7187.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation,eta-zero,eta-sam +//> using options -Xlint:deprecation,eta-zero,eta-sam // trait AcciSamOne { def apply(x: Int): Int } diff --git a/test/files/neg/t7212.check b/test/files/neg/t7212.check index 951569cfec3d..9b1be1c6ea89 100644 --- a/test/files/neg/t7212.check +++ b/test/files/neg/t7212.check @@ -1,12 +1,16 @@ -t7212.scala:5: warning: under -Xsource:3-cross, the inferred type changes to Object instead of String [quickfixable] +t7212.scala:5: error: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to Object instead of String [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=K.f class K extends T { def f = "" } ^ -t7212.scala:11: warning: under -Xsource:3-cross, the inferred type changes to Object instead of String [quickfixable] +t7212.scala:11: error: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to Object instead of String [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=F.f class F extends T { val f = "" } ^ -t7212.scala:17: warning: under -Xsource:3-cross, the inferred type changes to Object instead of String [quickfixable] +t7212.scala:17: error: in Scala 3 (or with -Xsource-features:infer-override), the inferred type changes to Object instead of String [quickfixable] +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=V.f trait V extends T { var f = "" } ^ -error: No warnings can be incurred under -Werror. -3 warnings -1 error +3 errors diff --git a/test/files/neg/t7212.scala b/test/files/neg/t7212.scala index 033123c69cd2..ad690794a743 100644 --- a/test/files/neg/t7212.scala +++ b/test/files/neg/t7212.scala @@ -1,5 +1,5 @@ -//> using options -Werror -Xmigration -Xsource:3 +//> using options -Xsource:3 trait T { def f: Object } class K extends T { def f = "" } @@ -20,3 +20,12 @@ object W { val w = new W val s: String = w.f } + +object refinement { + trait X { def f: Int } + trait T { def f: X } + // inferred: RefinedType(List(T, AnyRef), Nil) + // parent type: TypeRef(T) + // `=:=` is false, but `<:<` is true in both directions + class C extends T { def f = new X { def f = 1 } } +} diff --git a/test/files/neg/t7212b.check b/test/files/neg/t7212b.check index 181f58769da4..fe26946bb497 100644 --- a/test/files/neg/t7212b.check +++ b/test/files/neg/t7212b.check @@ -1,14 +1,14 @@ -t7212b.scala:8: error: type mismatch; +t7212b.scala:7: error: type mismatch; found : Object required: String val s: String = k.f ^ -t7212b.scala:14: error: type mismatch; +t7212b.scala:13: error: type mismatch; found : Object required: String val s: String = f.f ^ -t7212b.scala:21: error: type mismatch; +t7212b.scala:20: error: type mismatch; found : Object required: String val s: String = w.f diff --git a/test/files/neg/t7212b.scala b/test/files/neg/t7212b.scala index bbc684381fee..0dd0c9a1781b 100644 --- a/test/files/neg/t7212b.scala +++ b/test/files/neg/t7212b.scala @@ -1,5 +1,4 @@ - -//> using options -Xmigration -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:infer-override trait T { def f: Object } class K extends T { def f = "" } diff --git a/test/files/neg/t7285.scala b/test/files/neg/t7285.scala index 6c31a7b96907..9204c1ded393 100644 --- a/test/files/neg/t7285.scala +++ b/test/files/neg/t7285.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class Base diff --git a/test/files/neg/t7290.scala b/test/files/neg/t7290.scala index fcc5a561db8f..1d3c774119af 100644 --- a/test/files/neg/t7290.scala +++ b/test/files/neg/t7290.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test extends App { val y = (0: Int) match { diff --git a/test/files/neg/t7369.scala b/test/files/neg/t7369.scala index 094a7d576b30..91ba91ffee3b 100644 --- a/test/files/neg/t7369.scala +++ b/test/files/neg/t7369.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { val X, Y = true diff --git a/test/files/neg/t7415.check b/test/files/neg/t7415.check new file mode 100644 index 000000000000..bc0a3d1b9023 --- /dev/null +++ b/test/files/neg/t7415.check @@ -0,0 +1,38 @@ +t7415.scala:10: warning: Calls to parameterless method foo will be easy to mistake for calls to def foo(implicit a: T): Int, which has a single implicit parameter list. + def foo = 0 // warn + ^ +t7415.scala:14: warning: Usages of value foo will be easy to mistake for calls to def foo(implicit a: T): Int, which has a single implicit parameter list. + val foo = 0 // warn + ^ +t7415.scala:18: warning: Usages of value foo will be easy to mistake for calls to def foo(implicit a: T): Int, which has a single implicit parameter list. + private[this] val foo = 42 // warn + ^ +t7415.scala:31: warning: Calls to parameterless method foo will be easy to mistake for calls to def foo(implicit a: T): Int, which has a single implicit parameter list. +class Mixed extends Base with T1 // warn here + ^ +t7415.scala:41: warning: Usages of value foo will be easy to mistake for calls to overloads which have a single implicit parameter list: + def foo(implicit e: String): Int + def foo(implicit e: Int): Int + val foo = 0 // warn + ^ +t7415.scala:54: warning: Usages of value x will be easy to mistake for calls to def x(implicit t: T): Int, which has a single implicit parameter list. + def x(implicit t: T) = 27 // warn + ^ +t7415.scala:65: warning: Usages of value i will be easy to mistake for calls to def i(implicit t: T): Int, which has a single implicit parameter list. +class R(val i: Int) extends Q // warn + ^ +t7415.scala:66: warning: Usages of value i will be easy to mistake for calls to def i(implicit t: T): Int, which has a single implicit parameter list. +class S(i: Int) extends R(i) { // warn + ^ +t7415.scala:66: warning: Usages of value i will be easy to mistake for calls to def i(implicit t: T): Int, which has a single implicit parameter list. +class S(i: Int) extends R(i) { // warn + ^ +t7415.scala:76: warning: Calls to parameterless method f will be easy to mistake for calls to def f[A](implicit t: T): Int, which has a single implicit parameter list. + def f[A] = 27 // warn + ^ +t7415.scala:82: warning: Calls to parameterless method foo will be easy to mistake for calls to def foo(implicit a: T): Int, which has a single implicit parameter list. + val d1 = new Derived1 {} // warn + ^ +error: No warnings can be incurred under -Werror. +11 warnings +1 error diff --git a/test/files/neg/t7415.scala b/test/files/neg/t7415.scala new file mode 100644 index 000000000000..b36a514388e6 --- /dev/null +++ b/test/files/neg/t7415.scala @@ -0,0 +1,88 @@ +//> using options -Werror -Xlint:overload + +trait T + +trait Base { + def foo(implicit a: T) = 0 +} + +trait Derived1 extends Base { + def foo = 0 // warn +} + +trait Derived2 extends Base { + val foo = 0 // warn +} + +class C extends Base { + private[this] val foo = 42 // warn +} + +/* private local cannot directly conflict +class C2 extends Derived2 { + private[this] val foo = 42 // weaker access privileges in overriding +} +*/ + +trait T1 { + def foo = 0 +} + +class Mixed extends Base with T1 // warn here + +class D { + def foo(a: List[Int])(implicit d: DummyImplicit) = 0 + def foo(a: List[String]) = 1 +} + +class CleverLukas { + def foo(implicit e: String) = 1 + def foo(implicit e: Int) = 2 + val foo = 0 // warn +} + +class MoreInspiration { + def foo(implicit a: T) = 0 + def foo() = 1 // has parens but Scala 2 allows `foo` with adaptation +} + +class X { + val x = 42 +} + +class Y extends X { + def x(implicit t: T) = 27 // warn +} + +class J(val i: Int) +class K(i: Int) extends J(i) { // no warn local i shadows member i that is not implicit method + def f = i +} + +class Q { + def i(implicit t: T) = 42 +} +class R(val i: Int) extends Q // warn +class S(i: Int) extends R(i) { // warn + def f = i +} + +trait PBase { + def f[A](implicit t: T) = 42 + def g[A](s: String) = s.toInt +} + +trait PDerived extends PBase { + def f[A] = 27 // warn + def g[A] = f[A] // no warn +} + +object Test extends App { + implicit val t: T = new T {} + val d1 = new Derived1 {} // warn + println(d1.foo) // ! + val more = new MoreInspiration + println(more.foo) // ? + val y = new Y + println(y.x) // you have been warned! +} diff --git a/test/files/neg/t7494-after-terminal.check b/test/files/neg/t7494-after-terminal.check index de95de761dd3..efdf150eb06e 100644 --- a/test/files/neg/t7494-after-terminal.check +++ b/test/files/neg/t7494-after-terminal.check @@ -1,2 +1 @@ -error: [phase assembly, after dependency on terminal phase not allowed: afterterminal => terminal] -1 error +fatal error: Phases form a cycle: terminal -> afterterminal -> terminal diff --git a/test/files/neg/t7494-after-terminal/sample_2.scala b/test/files/neg/t7494-after-terminal/sample_2.scala index 774b9aed4545..d2583c1b5524 100644 --- a/test/files/neg/t7494-after-terminal/sample_2.scala +++ b/test/files/neg/t7494-after-terminal/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:afterterminal +//> using options -Xplugin:. -Xplugin-require:afterterminal package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7494-before-parser.check b/test/files/neg/t7494-before-parser.check index c5ba82faff81..f2b944d252f1 100644 --- a/test/files/neg/t7494-before-parser.check +++ b/test/files/neg/t7494-before-parser.check @@ -1,2 +1,7 @@ -error: [phase assembly, before dependency on parser phase not allowed: parser => beforeparser] +warning: Dropping phase beforeparser, it is not reachable from parser +sample_2.scala:8: error: type mismatch; + found : String("") + required: Int + def f: Int = "" + ^ 1 error diff --git a/test/files/neg/t7494-before-parser/sample_2.scala b/test/files/neg/t7494-before-parser/sample_2.scala index 10b67355cc5d..0eae2ded199c 100644 --- a/test/files/neg/t7494-before-parser/sample_2.scala +++ b/test/files/neg/t7494-before-parser/sample_2.scala @@ -1,6 +1,9 @@ -// scalac: -Xplugin:. -Xplugin-require:beforeparser +//> using options -Xplugin:. -Xplugin-require:beforeparser package sample // just a sample that is compiled with the sample plugin enabled object Sample extends App { + // because `-Werror` doesn't work; after phase assembly warnings are issued, + // Run.compileUnits resets the reporter (and its warning count) + def f: Int = "" } diff --git a/test/files/neg/t7494-multi-right-after.check b/test/files/neg/t7494-multi-right-after.check index 654f35fa156d..b5dd2b8f71d1 100644 --- a/test/files/neg/t7494-multi-right-after.check +++ b/test/files/neg/t7494-multi-right-after.check @@ -1 +1 @@ -fatal error: Multiple phases want to run right after explicitouter; followers: erasure,multi-rafter; created phase-order.dot +fatal error: Phases multi-rafter and erasure both immediately follow explicitouter diff --git a/test/files/neg/t7494-multi-right-after/sample_2.scala b/test/files/neg/t7494-multi-right-after/sample_2.scala index 9bf136ad27a6..2c9cfa861a9b 100644 --- a/test/files/neg/t7494-multi-right-after/sample_2.scala +++ b/test/files/neg/t7494-multi-right-after/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:multi-rafter +//> using options -Xplugin:. -Xplugin-require:multi-rafter package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7494-no-options/sample_2.scala b/test/files/neg/t7494-no-options/sample_2.scala index d756032b43c9..47a206b7b3de 100644 --- a/test/files/neg/t7494-no-options/sample_2.scala +++ b/test/files/neg/t7494-no-options/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Vphases -P:ploogin:inploog +//> using options -Xplugin:. -Vphases -P:ploogin:inploog package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7494-right-after-before.check b/test/files/neg/t7494-right-after-before.check index 06690b9112c1..695073496674 100644 --- a/test/files/neg/t7494-right-after-before.check +++ b/test/files/neg/t7494-right-after-before.check @@ -1 +1,27 @@ -fatal error: Phase erasure can't follow explicitouter, created phase-order.dot + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + namer 2 resolve names, attach symbols to named trees + packageobjects 3 load package objects + typer 4 the meat and potatoes: type the trees + superaccessors 5 add super accessors in traits and nested classes + extmethods 6 add extension methods for inline classes + pickler 7 serialize symbol tables + refchecks 8 reference/override checking, translate nested objects + patmat 9 translate match expressions +rafter-before-1 10 hey it works + uncurry 11 uncurry, translate function values to anonymous classes + fields 12 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 13 replace tail calls by jumps + specialize 14 @specialized-driven class and method specialization + explicitouter 15 this refs to outer pointers + erasure 16 erase types, add interfaces for traits + posterasure 17 clean up erased inline classes + lambdalift 18 move nested functions to top level + constructors 19 move field definitions into constructors + flatten 20 eliminate inner classes + mixin 21 mixin composition + cleanup 22 platform-specific cleanups, generate reflective calls + delambdafy 23 remove lambdas + jvm 24 generate JVM bytecode + terminal 25 the last phase during a compilation run diff --git a/test/files/neg/t7494-right-after-before/ThePlugin.scala b/test/files/neg/t7494-right-after-before/ThePlugin.scala index 967c1fb30705..cc4670b2fe66 100644 --- a/test/files/neg/t7494-right-after-before/ThePlugin.scala +++ b/test/files/neg/t7494-right-after-before/ThePlugin.scala @@ -10,11 +10,12 @@ class ThePlugin(val global: Global) extends Plugin { import global._ val name = "rafter-before-1" - val description = "" + val description = "hey it works" val components = List[PluginComponent](thePhase1) private object thePhase1 extends PluginComponent { val global = ThePlugin.this.global + override def description = ThePlugin.this.description val runsAfter = List[String]("refchecks") override val runsBefore = List[String]("erasure") diff --git a/test/files/neg/t7494-right-after-before/sample_2.scala b/test/files/neg/t7494-right-after-before/sample_2.scala index ebe48c4e8911..bc9a8d934c1f 100644 --- a/test/files/neg/t7494-right-after-before/sample_2.scala +++ b/test/files/neg/t7494-right-after-before/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:rafter-before-1 +//> using options -Xplugin:. -Xplugin-require:rafter-before-1 -Vphases package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7494-right-after-terminal.check b/test/files/neg/t7494-right-after-terminal.check index 191f087b2804..95a92ffe6010 100644 --- a/test/files/neg/t7494-right-after-terminal.check +++ b/test/files/neg/t7494-right-after-terminal.check @@ -1,2 +1 @@ -error: [phase assembly, right after dependency on terminal phase not allowed: rightafterterminal => terminal] -1 error +fatal error: Phases form a cycle: terminal -> rightafterterminal -> terminal diff --git a/test/files/neg/t7494-right-after-terminal/sample_2.scala b/test/files/neg/t7494-right-after-terminal/sample_2.scala index c705cf912e0c..e0f367078bfa 100644 --- a/test/files/neg/t7494-right-after-terminal/sample_2.scala +++ b/test/files/neg/t7494-right-after-terminal/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:rightafterterminal +//> using options -Xplugin:. -Xplugin-require:rightafterterminal package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7622-cyclic-dependency.check b/test/files/neg/t7622-cyclic-dependency.check index a339c6bc37cf..c824e07ecbd8 100644 --- a/test/files/neg/t7622-cyclic-dependency.check +++ b/test/files/neg/t7622-cyclic-dependency.check @@ -1 +1 @@ -fatal error: Cycle in phase dependencies detected at cyclicdependency2, created phase-cycle.dot +fatal error: Phases form a cycle: cyclicdependency2 -> cyclicdependency1 -> cyclicdependency2 diff --git a/test/files/neg/t7622-cyclic-dependency/sample_2.scala b/test/files/neg/t7622-cyclic-dependency/sample_2.scala index 3d5db665f8c5..798bebc4a23e 100644 --- a/test/files/neg/t7622-cyclic-dependency/sample_2.scala +++ b/test/files/neg/t7622-cyclic-dependency/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:cyclicdependency +//> using options -Xplugin:. -Xplugin-require:cyclicdependency package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7622-missing-dependency/sample_2.scala b/test/files/neg/t7622-missing-dependency/sample_2.scala index e03e32d9a7f2..9bff3616a847 100644 --- a/test/files/neg/t7622-missing-dependency/sample_2.scala +++ b/test/files/neg/t7622-missing-dependency/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:myplugin +//> using options -Xplugin:. -Xplugin-require:myplugin package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7622-missing-required.scala b/test/files/neg/t7622-missing-required.scala index 0025feb680ac..76d381981d6e 100644 --- a/test/files/neg/t7622-missing-required.scala +++ b/test/files/neg/t7622-missing-required.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin-require:special-plugin +//> using options -Xplugin-require:special-plugin // // the amazing features of this trait diff --git a/test/files/neg/t7622-multi-followers.check b/test/files/neg/t7622-multi-followers.check index 4ef80ffdba1d..82eb0ee03ff4 100644 --- a/test/files/neg/t7622-multi-followers.check +++ b/test/files/neg/t7622-multi-followers.check @@ -1 +1 @@ -fatal error: Multiple phases want to run right after parser; followers: multi1,multi2; created phase-order.dot +fatal error: Phases multi1 and multi2 both immediately follow parser diff --git a/test/files/neg/t7622-multi-followers/sample_2.scala b/test/files/neg/t7622-multi-followers/sample_2.scala index 392e2ad7c0cd..941a6da13e39 100644 --- a/test/files/neg/t7622-multi-followers/sample_2.scala +++ b/test/files/neg/t7622-multi-followers/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:multi +//> using options -Xplugin:. -Xplugin-require:multi package sample // just a sample that is compiled with the sample plugin enabled diff --git a/test/files/neg/t7623.scala b/test/files/neg/t7623.scala index fb36d0b5d737..8fae4fcf13f5 100644 --- a/test/files/neg/t7623.scala +++ b/test/files/neg/t7623.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:stars-align -Xfatal-warnings +//> using options -Xlint:stars-align -Xfatal-warnings // diff --git a/test/files/neg/t7669.scala b/test/files/neg/t7669.scala index 7ad88eba563d..2033b37b89a0 100644 --- a/test/files/neg/t7669.scala +++ b/test/files/neg/t7669.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { diff --git a/test/files/neg/t7721.scala b/test/files/neg/t7721.scala index 61b66503b5a1..7d1b40ad6450 100644 --- a/test/files/neg/t7721.scala +++ b/test/files/neg/t7721.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import scala.language.reflectiveCalls diff --git a/test/files/neg/t7756b.scala b/test/files/neg/t7756b.scala index b3364aa86087..6feab9ba5c87 100644 --- a/test/files/neg/t7756b.scala +++ b/test/files/neg/t7756b.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { 0 match { diff --git a/test/files/neg/t7783.scala b/test/files/neg/t7783.scala index c9412fe8cb7a..85ae75dafd1a 100644 --- a/test/files/neg/t7783.scala +++ b/test/files/neg/t7783.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object O { class C; @deprecated("", "") type D = C; def foo: Seq[D] = Nil } diff --git a/test/files/neg/t7808.check b/test/files/neg/t7808.check new file mode 100644 index 000000000000..4c72decfa294 --- /dev/null +++ b/test/files/neg/t7808.check @@ -0,0 +1,4 @@ +t7808.scala:5: error: recursive value ls needs type + val (ls, rs) = z match { + ^ +1 error diff --git a/test/files/neg/t7808.scala b/test/files/neg/t7808.scala new file mode 100644 index 000000000000..d01aea925188 --- /dev/null +++ b/test/files/neg/t7808.scala @@ -0,0 +1,18 @@ +//> using options -Vcyclic +class C { + type OI = Option[Int] + def f(z: OI, ls: List[OI], rs: List[OI]): (List[OI], List[OI]) = { + val (ls, rs) = z match { + case Some(_) => (z::ls, rs) + case _ => (ls, z::rs) + } + (ls, rs) + } +} + +/* +t7808.scala:5: error: recursive value x$1 needs type + val (ls, rs) = z match { + ^ +1 error +*/ diff --git a/test/files/neg/t7808b.check b/test/files/neg/t7808b.check new file mode 100644 index 000000000000..1ece6555fe49 --- /dev/null +++ b/test/files/neg/t7808b.check @@ -0,0 +1,4 @@ +t7808b.scala:5: error: recursive value x$1 needs type; value x$1 is synthetic; use -Vcyclic to find which definition needs an explicit type + val (ls, rs) = z match { + ^ +1 error diff --git a/test/files/neg/t7808b.scala b/test/files/neg/t7808b.scala new file mode 100644 index 000000000000..986587f582fb --- /dev/null +++ b/test/files/neg/t7808b.scala @@ -0,0 +1,18 @@ + +class C { + type OI = Option[Int] + def f(z: OI, ls: List[OI], rs: List[OI]): (List[OI], List[OI]) = { + val (ls, rs) = z match { + case Some(_) => (z::ls, rs) + case _ => (ls, z::rs) + } + (ls, rs) + } +} + +/* +t7808.scala:5: error: recursive value x$1 needs type + val (ls, rs) = z match { + ^ +1 error +*/ diff --git a/test/files/neg/t7848-interp-warn.check b/test/files/neg/t7848-interp-warn.check deleted file mode 100644 index c002144f2614..000000000000 --- a/test/files/neg/t7848-interp-warn.check +++ /dev/null @@ -1,33 +0,0 @@ -t7848-interp-warn.scala:20: warning: possible missing interpolator: detected interpolated identifier `$foo` - "An important $foo message!" // warn on ident in scope - ^ -t7848-interp-warn.scala:24: warning: possible missing interpolator: detected an interpolated expression - "A doubly important ${foo * 2} message!" // warn on some expr, see below - ^ -t7848-interp-warn.scala:27: warning: possible missing interpolator: detected interpolated identifier `$bar` - def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test - ^ -t7848-interp-warn.scala:28: warning: possible missing interpolator: detected interpolated identifier `$bar` - def j = s"Try using '${ "something like $bar" }' instead." // warn - ^ -t7848-interp-warn.scala:34: warning: possible missing interpolator: detected an interpolated expression - def v = "${baz}${bar}" // warn on second expr - ^ -t7848-interp-warn.scala:35: warning: possible missing interpolator: detected an interpolated expression - def w = "${ op_* }" // warn, only cheap ident parsing - ^ -t7848-interp-warn.scala:36: warning: possible missing interpolator: detected an interpolated expression - def x = "${ bar }" // warn, a cheap ident in scope - ^ -t7848-interp-warn.scala:38: warning: possible missing interpolator: detected an interpolated expression - def z = "${ baz * 3}" // warn, no expr parsing - ^ -t7848-interp-warn.scala:40: warning: possible missing interpolator: detected interpolated identifier `$this` - def thisly = "$this" - ^ -t7848-interp-warn.scala:41: warning: possible missing interpolator: detected an interpolated expression - def exprly = "${this}" - ^ -error: No warnings can be incurred under -Werror. -10 warnings -1 error diff --git a/test/files/neg/t7848-interp-warn.scala b/test/files/neg/t7848-interp-warn.scala deleted file mode 100644 index af087ff1ac52..000000000000 --- a/test/files/neg/t7848-interp-warn.scala +++ /dev/null @@ -1,42 +0,0 @@ -// scalac: -Xlint:missing-interpolator -Xfatal-warnings -// - -package test - -package pancake { } - -object Test { - type NonVal = Int - - def ok = "Don't warn on $nosymbol interpolated." - - def pass = "Don't warn on $pancake package names." - - def types = "Or $NonVal type symbols either." - - def bar = "bar" - def f = { - val foo = "bar" - "An important $foo message!" // warn on ident in scope - } - def g = { - val foo = "bar" - "A doubly important ${foo * 2} message!" // warn on some expr, see below - } - def h = s"Try using '$$bar' instead." // no warn - def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test - def j = s"Try using '${ "something like $bar" }' instead." // warn - def k = f"Try using '$bar' instead." // no warn on other std interps - def p = "Template ${} {}" // no warn on unlikely or empty expressions - def q = "${}$bar" // disables subsequent checks! (a feature) - def r = "${}${bar}" // disables subsequent checks! (a feature) - - def v = "${baz}${bar}" // warn on second expr - def w = "${ op_* }" // warn, only cheap ident parsing - def x = "${ bar }" // warn, a cheap ident in scope - def y = "${ baz }" // no warn, cheap ident not in scope - def z = "${ baz * 3}" // warn, no expr parsing - - def thisly = "$this" - def exprly = "${this}" -} diff --git a/test/files/neg/t7860.scala b/test/files/neg/t7860.scala index 905dc3854f7b..7eaf1f7b09ba 100644 --- a/test/files/neg/t7860.scala +++ b/test/files/neg/t7860.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Ywarn-unused:privates +//> using options -Xfatal-warnings -Ywarn-unused:privates // class Test diff --git a/test/files/neg/t7879.check b/test/files/neg/t7879.check new file mode 100644 index 000000000000..d64d37be30b9 --- /dev/null +++ b/test/files/neg/t7879.check @@ -0,0 +1,6 @@ +t7879.scala:2: error: case `copy` method is allowed to have by-name parameters under Scala 3 (or with -Xsource-features:case-copy-by-name) +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=C +case class C(i: Int)(j: => Int)(k: => Int) { def sum = i + j + k } + ^ +1 error diff --git a/test/files/neg/t7879.scala b/test/files/neg/t7879.scala new file mode 100644 index 000000000000..e873120e5ef2 --- /dev/null +++ b/test/files/neg/t7879.scala @@ -0,0 +1,2 @@ +//> using options -Xsource:3 +case class C(i: Int)(j: => Int)(k: => Int) { def sum = i + j + k } diff --git a/test/files/neg/t7879b.check b/test/files/neg/t7879b.check new file mode 100644 index 000000000000..89579285661d --- /dev/null +++ b/test/files/neg/t7879b.check @@ -0,0 +1,4 @@ +t7879b.scala:5: error: value copy is not a member of C + def f(c: C): C = c.copy(42)(Seq(9, 9, 9): _*) + ^ +1 error diff --git a/test/files/neg/t7879b.scala b/test/files/neg/t7879b.scala new file mode 100644 index 000000000000..d23e5dea0927 --- /dev/null +++ b/test/files/neg/t7879b.scala @@ -0,0 +1,6 @@ +//> using options -Xsource:3 -Xsource-features:case-copy-by-name +case class C(i: Int)(js: Int*) { def sum = i + js.sum } + +class Usage { + def f(c: C): C = c.copy(42)(Seq(9, 9, 9): _*) +} diff --git a/test/files/neg/t7879c.check b/test/files/neg/t7879c.check new file mode 100644 index 000000000000..29754cfca1b6 --- /dev/null +++ b/test/files/neg/t7879c.check @@ -0,0 +1,4 @@ +t7879c.scala:6: error: value copy is not a member of C + C(42)(27)(1).copy() + ^ +1 error diff --git a/test/files/neg/t7879c.scala b/test/files/neg/t7879c.scala new file mode 100644 index 000000000000..b16a74067350 --- /dev/null +++ b/test/files/neg/t7879c.scala @@ -0,0 +1,8 @@ +//> using options -Werror -Xlint +case class C(i: Int)(j: => Int)(k: => Int) { def sum = i + j + k } + +object Test extends App { + println { + C(42)(27)(1).copy() + } +} diff --git a/test/files/neg/t7984.scala b/test/files/neg/t7984.scala index 9e6c5e6b9d5a..c53dd1633eb8 100644 --- a/test/files/neg/t7984.scala +++ b/test/files/neg/t7984.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class Test { type ListInt = List[Int] diff --git a/test/files/neg/t8015-ffb.scala b/test/files/neg/t8015-ffb.scala index 7fd2d9ea91dd..d94e4d6353f6 100644 --- a/test/files/neg/t8015-ffb.scala +++ b/test/files/neg/t8015-ffb.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Xfatal-warnings +//> using options -Xlint -Xfatal-warnings // trait G { diff --git a/test/files/neg/t8035-removed.check b/test/files/neg/t8035-removed.check index 79aa9ed88a62..cf47a1dfa38b 100644 --- a/test/files/neg/t8035-removed.check +++ b/test/files/neg/t8035-removed.check @@ -2,7 +2,7 @@ t8035-removed.scala:4: error: adaptation of an empty argument list by inserting signature: SetOps.apply(elem: A): Boolean given arguments: after adaptation: SetOps((): Unit) -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=scala.collection.SetOps.apply List(1,2,3).toSet() ^ @@ -13,7 +13,7 @@ t8035-removed.scala:7: error: adaptation of an empty argument list by inserting signature: A(x: T): Foo.A[T] given arguments: after adaptation: new A((): Unit) -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=Foo.A. new A ^ @@ -21,7 +21,7 @@ t8035-removed.scala:11: error: adaptation of an empty argument list by inserting signature: Format.format(x$1: Object): String given arguments: after adaptation: Format.format((): Unit) -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=java.text.Format.format sdf.format() ^ diff --git a/test/files/neg/t8035-removed.scala b/test/files/neg/t8035-removed.scala index d06113bbff4a..88ccfba66c48 100644 --- a/test/files/neg/t8035-removed.scala +++ b/test/files/neg/t8035-removed.scala @@ -1,5 +1,5 @@ -//> using options -Werror -Xlint -Xsource:3-cross -// +//> using options -Werror -Xlint -Xsource:3 + object Foo { List(1,2,3).toSet() diff --git a/test/files/neg/t8044-b.check b/test/files/neg/t8044-b.check index ae3506ee42ed..ef4a1375d2fa 100644 --- a/test/files/neg/t8044-b.check +++ b/test/files/neg/t8044-b.check @@ -1,4 +1,4 @@ t8044-b.scala:3: error: Pattern variables must start with a lower-case letter. (SLS 8.1.1.) def g = 42 match { case `Oops` : Int => } // must be varish - ^ + ^ 1 error diff --git a/test/files/neg/t8178.scala b/test/files/neg/t8178.scala index bc5804577d74..37595cc83062 100644 --- a/test/files/neg/t8178.scala +++ b/test/files/neg/t8178.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings sealed trait Fails case class VarArgs1(a: String*) extends Fails case class FailsChild2(a: Seq[String]) extends Fails diff --git a/test/files/neg/t8182.check b/test/files/neg/t8182.check index 4408e975c6f2..0bb9d6f7bb70 100644 --- a/test/files/neg/t8182.check +++ b/test/files/neg/t8182.check @@ -6,17 +6,17 @@ t8182.scala:7: error: illegal start of simple pattern ^ t8182.scala:6: error: type application is not allowed in pattern val a b[B] // error then continue as for X - ^ + ^ t8182.scala:10: error: illegal start of simple pattern case a b[B] => // bumpy recovery ^ t8182.scala:10: error: type application is not allowed in pattern case a b[B] => // bumpy recovery - ^ + ^ t8182.scala:11: error: '=>' expected but '}' found. } ^ t8182.scala:16: error: type application is not allowed in pattern case a B[T] b => - ^ + ^ 7 errors diff --git a/test/files/neg/t8265.scala b/test/files/neg/t8265.scala index ae4e64b8ba45..d7896cde87da 100644 --- a/test/files/neg/t8265.scala +++ b/test/files/neg/t8265.scala @@ -1,3 +1,3 @@ -// scalac: -language:higherKinds +//> using options -language:higherKinds // class Foo[+CC[X]] { type Coll = CC[_] } diff --git a/test/files/neg/t8266-invalid-interp.check b/test/files/neg/t8266-invalid-interp.check index 3f742d685985..06e0ec82b53f 100644 --- a/test/files/neg/t8266-invalid-interp.check +++ b/test/files/neg/t8266-invalid-interp.check @@ -12,4 +12,7 @@ t8266-invalid-interp.scala:8: error: \v is not supported, but for vertical tab u invalid escape '\v' not one of [\b, \t, \n, \f, \r, \\, \", \', \uxxxx] at index 0 in "\v". Use \\ for literal \. f"\v$x%.4s, Fred", ^ -4 errors +t8266-invalid-interp.scala:11: error: invalid escape '\s' not one of [\b, \t, \n, \f, \r, \\, \", \', \uxxxx] at index 11 in ". And then \s.". Use \\ for literal \. + s"She said, $x. And then \s.", + ^ +5 errors diff --git a/test/files/neg/t8266-invalid-interp.scala b/test/files/neg/t8266-invalid-interp.scala index 7160f67c89ae..2bcf49430493 100644 --- a/test/files/neg/t8266-invalid-interp.scala +++ b/test/files/neg/t8266-invalid-interp.scala @@ -7,4 +7,7 @@ trait X { f"a\vc", f"\v$x%.4s, Fred", ) + def s = Seq( + s"She said, $x. And then \s.", + ) } diff --git a/test/files/neg/t8417.scala b/test/files/neg/t8417.scala index 961514d9eb7f..8f37043ce886 100644 --- a/test/files/neg/t8417.scala +++ b/test/files/neg/t8417.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:adapted-args +//> using options -Xfatal-warnings -Xlint:adapted-args // diff --git a/test/files/neg/t8430.scala b/test/files/neg/t8430.scala index da1b4eefbcce..972aeea3fd99 100644 --- a/test/files/neg/t8430.scala +++ b/test/files/neg/t8430.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Ypatmat-exhaust-depth off +//> using options -Xfatal-warnings -Ypatmat-exhaust-depth off // sealed trait CL3Literal case object IntLit extends CL3Literal diff --git a/test/files/neg/t8450.scala b/test/files/neg/t8450.scala index a1c5de01ce7c..55f60ecd61d7 100644 --- a/test/files/neg/t8450.scala +++ b/test/files/neg/t8450.scala @@ -1,4 +1,4 @@ -// scalac: -Ywarn-numeric-widen -Xfatal-warnings +//> using options -Ywarn-numeric-widen -Xfatal-warnings // trait Foo diff --git a/test/files/neg/t8511.scala b/test/files/neg/t8511.scala index 6d96eda0b0e0..9be381769f18 100644 --- a/test/files/neg/t8511.scala +++ b/test/files/neg/t8511.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed trait Expr final case class Foo(other: Option[String]) extends Expr final case class Bar(someConstant: String) extends Expr diff --git a/test/files/neg/t8525.scala b/test/files/neg/t8525.scala index 606b473983b0..96d5e3a51b45 100644 --- a/test/files/neg/t8525.scala +++ b/test/files/neg/t8525.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:-missing-interpolator -Xlint +//> using options -Xfatal-warnings -Xlint:-missing-interpolator -Xlint // class Named(var name: String) diff --git a/test/files/neg/t8597.scala b/test/files/neg/t8597.scala index b5925c48a1ca..815032539721 100644 --- a/test/files/neg/t8597.scala +++ b/test/files/neg/t8597.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class Unchecked[C] { def nowarn[T] = (null: Any) match { case _: Some[T] => } // warn (did not warn due to scala/bug#8597) diff --git a/test/files/neg/t8597b.scala b/test/files/neg/t8597b.scala index 26b3f97c1500..4a4f38d79d39 100644 --- a/test/files/neg/t8597b.scala +++ b/test/files/neg/t8597b.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Unchecked { (null: Any) match { diff --git a/test/files/neg/t8610-arg.scala b/test/files/neg/t8610-arg.scala index 553a164201ea..380796019999 100644 --- a/test/files/neg/t8610-arg.scala +++ b/test/files/neg/t8610-arg.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint nullary-unit +//> using options -Xfatal-warnings -Xlint nullary-unit // class Named(var name: String) diff --git a/test/files/neg/t8610.scala b/test/files/neg/t8610.scala index 8388d6f4368b..62443d2af273 100644 --- a/test/files/neg/t8610.scala +++ b/test/files/neg/t8610.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint +//> using options -Xfatal-warnings -Xlint // class Named(var name: String) diff --git a/test/files/neg/t8650.scala b/test/files/neg/t8650.scala index b05d3a1d3ba0..98b33b116ab3 100644 --- a/test/files/neg/t8650.scala +++ b/test/files/neg/t8650.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint object Strings { final val greeting = "hello" diff --git a/test/files/neg/t8650b.scala b/test/files/neg/t8650b.scala index c694791320b8..217b0fd1845b 100644 --- a/test/files/neg/t8650b.scala +++ b/test/files/neg/t8650b.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint object Strings { final val greeting = "hello" diff --git a/test/files/neg/t8667.check b/test/files/neg/t8667.check index 142d7508543e..c9852dd91c70 100644 --- a/test/files/neg/t8667.check +++ b/test/files/neg/t8667.check @@ -143,4 +143,70 @@ t8667.scala:91: error: unknown parameter name: k t8667.scala:91: error: too many arguments (found 3, expected 2) for method f2: (i: Int, j: Int): Unit f2(17, 27, k = 42) ^ -48 errors +t8667.scala:98: error: type mismatch; + found : String("not a num 1") + required: Double + def close() = almostTupleAdapted(math.floor("not a num 1"), math.floor("not a num 2")) + ^ +t8667.scala:98: error: type mismatch; + found : String("not a num 2") + required: Double + def close() = almostTupleAdapted(math.floor("not a num 1"), math.floor("not a num 2")) + ^ +t8667.scala:98: error: too many arguments (found 2, expected 2-tuple) for method almostTupleAdapted: (t2: (Int, String)): Unit + def close() = almostTupleAdapted(math.floor("not a num 1"), math.floor("not a num 2")) + ^ +t8667.scala:102: error: type mismatch; + found : String("not a num") + required: Double + def missed() = missingArgs(math.floor("not a num")) + ^ +t8667.scala:102: error: not enough arguments for method missingArgs: (d: Double, s: String): Unit. +Unspecified value parameter s. + def missed() = missingArgs(math.floor("not a num")) + ^ +t8667.scala:106: error: type mismatch; + found : String("not a num") + required: Double + def miscount() = tooManyArgs(math.floor("not a num")) + ^ +t8667.scala:106: error: not enough arguments for method tooManyArgs: (s: String, i: Int): Unit. +Unspecified value parameter i. + def miscount() = tooManyArgs(math.floor("not a num")) + ^ +t8667.scala:108: error: not found: value doesntExist + def nonesuch(): Unit = doesntExist(math.floor("not a num 1"), math.floor("not a num 2")) + ^ +t8667.scala:108: error: type mismatch; + found : String("not a num 1") + required: Double + def nonesuch(): Unit = doesntExist(math.floor("not a num 1"), math.floor("not a num 2")) + ^ +t8667.scala:108: error: type mismatch; + found : String("not a num 2") + required: Double + def nonesuch(): Unit = doesntExist(math.floor("not a num 1"), math.floor("not a num 2")) + ^ +t8667.scala:110: error: not found: value doesntExist + def nonesuchical: Unit = doesntExist(i = math.floor("not a num 1"), j = math.floor("not a num 2")) + ^ +t8667.scala:110: error: type mismatch; + found : String("not a num 1") + required: Double + def nonesuchical: Unit = doesntExist(i = math.floor("not a num 1"), j = math.floor("not a num 2")) + ^ +t8667.scala:110: error: type mismatch; + found : String("not a num 2") + required: Double + def nonesuchical: Unit = doesntExist(i = math.floor("not a num 1"), j = math.floor("not a num 2")) + ^ +t8667.scala:112: error: value munge is not a member of List[Int] + def badApplied: Unit = List(42).munge(x = 27) + ^ +t8667.scala:114: error: value munge is not a member of List[Int] + def badApply: Unit = List(42).munge { x = 27 } + ^ +t8667.scala:114: error: not found: value x + def badApply: Unit = List(42).munge { x = 27 } + ^ +64 errors diff --git a/test/files/neg/t8667.scala b/test/files/neg/t8667.scala index 1640884e04b2..d65dc99589f1 100644 --- a/test/files/neg/t8667.scala +++ b/test/files/neg/t8667.scala @@ -91,3 +91,25 @@ trait Nuance { f2(17, 27, k = 42) } } + +trait FurtherFailures { + def almostTupleAdapted(t2: (Int, String)): Unit = () + + def close() = almostTupleAdapted(math.floor("not a num 1"), math.floor("not a num 2")) + + def missingArgs(d: Double, s: String): Unit = () + + def missed() = missingArgs(math.floor("not a num")) + + def tooManyArgs(s: String, i: Int): Unit = () + + def miscount() = tooManyArgs(math.floor("not a num")) + + def nonesuch(): Unit = doesntExist(math.floor("not a num 1"), math.floor("not a num 2")) + + def nonesuchical: Unit = doesntExist(i = math.floor("not a num 1"), j = math.floor("not a num 2")) + + def badApplied: Unit = List(42).munge(x = 27) + + def badApply: Unit = List(42).munge { x = 27 } +} diff --git a/test/files/neg/t8685.check b/test/files/neg/t8685.check index f47aa94d8d73..db0953d9c243 100644 --- a/test/files/neg/t8685.check +++ b/test/files/neg/t8685.check @@ -4,10 +4,10 @@ t8685.scala:37: warning: class C is deprecated (since now): class C is depr t8685.scala:38: warning: constructor D in class D is deprecated (since now): ctor D is depr def g = D(42) ^ -t8685.scala:39: warning: object E is deprecated (since now): module E is depr +t8685.scala:39: warning: class E is deprecated (since now): class E is depr def h = E(42) ^ -t8685.scala:39: warning: class E is deprecated (since now): class E is depr +t8685.scala:39: warning: object E is deprecated (since now): module E is depr def h = E(42) ^ t8685.scala:40: warning: object F is deprecated (since now): module F is depr diff --git a/test/files/neg/t8685.scala b/test/files/neg/t8685.scala index 0cba602194e6..af9db61ea9c3 100644 --- a/test/files/neg/t8685.scala +++ b/test/files/neg/t8685.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // diff --git a/test/files/neg/t8700a/Bar.scala b/test/files/neg/t8700a/Bar.scala index fce3c061f787..3055c25042e0 100644 --- a/test/files/neg/t8700a/Bar.scala +++ b/test/files/neg/t8700a/Bar.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Bar { def bar1(foo: Foo) = foo match { case Foo.A => 1 diff --git a/test/files/neg/t8700b/Bar_2.scala b/test/files/neg/t8700b/Bar_2.scala index bc61137a5afe..c7f5c4966717 100644 --- a/test/files/neg/t8700b/Bar_2.scala +++ b/test/files/neg/t8700b/Bar_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // object Bar { def bar1(foo: Foo) = foo match { diff --git a/test/files/neg/t8704.scala b/test/files/neg/t8704.scala index aebc7162deaf..37614452f4f0 100644 --- a/test/files/neg/t8704.scala +++ b/test/files/neg/t8704.scala @@ -1,4 +1,4 @@ -// scalac: -Ywarn-extra-implicit +//> using options -Ywarn-extra-implicit // diff --git a/test/files/neg/t8731.scala b/test/files/neg/t8731.scala index fd85fbe42ae6..c1015396a1f0 100644 --- a/test/files/neg/t8731.scala +++ b/test/files/neg/t8731.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class C { // not a compile-time constant due to return type diff --git a/test/files/neg/t8755-regress-a.check b/test/files/neg/t8755-regress-a.check new file mode 100644 index 000000000000..b65df72c101f --- /dev/null +++ b/test/files/neg/t8755-regress-a.check @@ -0,0 +1,28 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + namer 2 resolve names, attach symbols to named trees +packageobjects 3 load package objects + typer 4 the meat and potatoes: type the trees + C8 0 C8 makes C7 reachable +superaccessors 6 add super accessors in traits and nested classes + C7 0 C7 has only a before constraint + extmethods 8 add extension methods for inline classes + pickler 9 serialize symbol tables + refchecks 10 reference/override checking, translate nested objects + patmat 11 translate match expressions + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + cleanup 23 platform-specific cleanups, generate reflective calls + delambdafy 24 remove lambdas + jvm 25 generate JVM bytecode + terminal 26 the last phase during a compilation run diff --git a/test/files/neg/t8755-regress-a/ploogin_1.scala b/test/files/neg/t8755-regress-a/ploogin_1.scala new file mode 100644 index 000000000000..643c09f2fed7 --- /dev/null +++ b/test/files/neg/t8755-regress-a/ploogin_1.scala @@ -0,0 +1,40 @@ + +package t8755 + +import scala.tools.nsc, nsc.{Global, Phase, plugins}, plugins.{Plugin, PluginComponent} + +class P(val global: Global) extends Plugin { + override val name = "Testing phase assembly" + override val description = "C7 is not dropped even though it has no runs[Right]After" + override val components = List[PluginComponent]( + component7, + component8, + ) + + object component7 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C7" + override val description = "C7 has only a before constraint" + override val runsRightAfter = None + override val runsAfter = Nil + override val runsBefore = List("patmat") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component8 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C8" + override val description = "C8 makes C7 reachable" + override val runsRightAfter = None + override val runsAfter = List("typer") + override val runsBefore = List("C7") // component name, not phase name! + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } +} diff --git a/test/files/neg/t8755-regress-a/sample_2.scala b/test/files/neg/t8755-regress-a/sample_2.scala new file mode 100644 index 000000000000..c33cb6e657c4 --- /dev/null +++ b/test/files/neg/t8755-regress-a/sample_2.scala @@ -0,0 +1,6 @@ +//> using options -Xplugin:. -Xplugin-require:"Testing phase assembly" -Vphases -Werror +package sample + +// just a sample that is compiled with the sample plugin enabled +object Sample extends App { +} diff --git a/test/files/neg/t8755-regress-a/scalac-plugin.xml b/test/files/neg/t8755-regress-a/scalac-plugin.xml new file mode 100644 index 000000000000..37440fe54290 --- /dev/null +++ b/test/files/neg/t8755-regress-a/scalac-plugin.xml @@ -0,0 +1,5 @@ + + Testing phase assembly + t8755.P + + diff --git a/test/files/neg/t8755.check b/test/files/neg/t8755.check new file mode 100644 index 000000000000..4322d7154355 --- /dev/null +++ b/test/files/neg/t8755.check @@ -0,0 +1,29 @@ +warning: No phase `refchicks` for ploogin.runsAfter - did you mean refchecks? +warning: No phase `java` for ploogin.runsBefore - did you mean jvm? +warning: Dropping phase ploogin, it is not reachable from parser + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + namer 2 resolve names, attach symbols to named trees +packageobjects 3 load package objects + typer 4 the meat and potatoes: type the trees +superaccessors 5 add super accessors in traits and nested classes + extmethods 6 add extension methods for inline classes + pickler 7 serialize symbol tables + refchecks 8 reference/override checking, translate nested objects + patmat 9 translate match expressions + uncurry 10 uncurry, translate function values to anonymous classes + fields 11 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 12 replace tail calls by jumps + specialize 13 @specialized-driven class and method specialization + explicitouter 14 this refs to outer pointers + erasure 15 erase types, add interfaces for traits + posterasure 16 clean up erased inline classes + lambdalift 17 move nested functions to top level + constructors 18 move field definitions into constructors + flatten 19 eliminate inner classes + mixin 20 mixin composition + cleanup 21 platform-specific cleanups, generate reflective calls + delambdafy 22 remove lambdas + jvm 23 generate JVM bytecode + terminal 24 the last phase during a compilation run diff --git a/test/files/neg/t8755/ploogin_1.scala b/test/files/neg/t8755/ploogin_1.scala new file mode 100644 index 000000000000..33ea7e6c6e56 --- /dev/null +++ b/test/files/neg/t8755/ploogin_1.scala @@ -0,0 +1,31 @@ + +package t8755 + +import scala.tools.nsc.{Global, Phase} +import scala.tools.nsc.plugins.{Plugin, PluginComponent} +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global) extends Plugin { + import global._ + + val name = "ploogin" + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + override val runsBefore = List("java") + val runsAfter = List("refchicks") + val phaseName = Ploogin.this.name + override def description = "A sample phase that doesn't know when to run." + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit): Unit = { + // kewl kode + } + } + } +} diff --git a/test/files/neg/t8755/sample_2.scala b/test/files/neg/t8755/sample_2.scala new file mode 100644 index 000000000000..ef2fba58a09b --- /dev/null +++ b/test/files/neg/t8755/sample_2.scala @@ -0,0 +1,6 @@ +//> using options -Xplugin:. -Xplugin-require:ploogin -Vphases -Werror +package sample + +// just a sample that is compiled with the sample plugin enabled +object Sample extends App { +} diff --git a/test/files/neg/t8755/scalac-plugin.xml b/test/files/neg/t8755/scalac-plugin.xml new file mode 100644 index 000000000000..451480c58d68 --- /dev/null +++ b/test/files/neg/t8755/scalac-plugin.xml @@ -0,0 +1,5 @@ + + ploogin + t8755.Ploogin + + diff --git a/test/files/neg/t8755b.check b/test/files/neg/t8755b.check new file mode 100644 index 000000000000..b4275a932aff --- /dev/null +++ b/test/files/neg/t8755b.check @@ -0,0 +1,27 @@ +warning: Dropping phase ploogin, it is not reachable from parser + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + namer 2 resolve names, attach symbols to named trees +packageobjects 3 load package objects + typer 4 the meat and potatoes: type the trees +superaccessors 5 add super accessors in traits and nested classes + extmethods 6 add extension methods for inline classes + pickler 7 serialize symbol tables + refchecks 8 reference/override checking, translate nested objects + patmat 9 translate match expressions + uncurry 10 uncurry, translate function values to anonymous classes + fields 11 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 12 replace tail calls by jumps + specialize 13 @specialized-driven class and method specialization + explicitouter 14 this refs to outer pointers + erasure 15 erase types, add interfaces for traits + posterasure 16 clean up erased inline classes + lambdalift 17 move nested functions to top level + constructors 18 move field definitions into constructors + flatten 19 eliminate inner classes + mixin 20 mixin composition + cleanup 21 platform-specific cleanups, generate reflective calls + delambdafy 22 remove lambdas + jvm 23 generate JVM bytecode + terminal 24 the last phase during a compilation run diff --git a/test/files/neg/t8755b/ploogin_1.scala b/test/files/neg/t8755b/ploogin_1.scala new file mode 100644 index 000000000000..76ab22f4b257 --- /dev/null +++ b/test/files/neg/t8755b/ploogin_1.scala @@ -0,0 +1,29 @@ + +package t8755 + +import scala.tools.nsc.{Global, Phase} +import scala.tools.nsc.plugins.{Plugin, PluginComponent} +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global) extends Plugin { + import global._ + + val name = "ploogin" + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + override val runsBefore = List("erasure") + val runsAfter = Nil + val phaseName = Ploogin.this.name + override def description = "A phase that another phase must run before." + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit): Unit = () + } + } +} diff --git a/test/files/neg/t8755b/sample_2.scala b/test/files/neg/t8755b/sample_2.scala new file mode 100644 index 000000000000..ef2fba58a09b --- /dev/null +++ b/test/files/neg/t8755b/sample_2.scala @@ -0,0 +1,6 @@ +//> using options -Xplugin:. -Xplugin-require:ploogin -Vphases -Werror +package sample + +// just a sample that is compiled with the sample plugin enabled +object Sample extends App { +} diff --git a/test/files/neg/t8755b/scalac-plugin.xml b/test/files/neg/t8755b/scalac-plugin.xml new file mode 100644 index 000000000000..451480c58d68 --- /dev/null +++ b/test/files/neg/t8755b/scalac-plugin.xml @@ -0,0 +1,5 @@ + + ploogin + t8755.Ploogin + + diff --git a/test/files/neg/t8755c.check b/test/files/neg/t8755c.check new file mode 100644 index 000000000000..606c9132cf41 --- /dev/null +++ b/test/files/neg/t8755c.check @@ -0,0 +1,28 @@ + phase name id description + ---------- -- ----------- + parser 1 parse source into ASTs, perform simple desugaring + namer 2 resolve names, attach symbols to named trees +packageobjects 3 load package objects + typer 4 the meat and potatoes: type the trees + C1 0 C1 tests phase assembly +superaccessors 6 add super accessors in traits and nested classes + extmethods 7 add extension methods for inline classes + pickler 8 serialize symbol tables + refchecks 9 reference/override checking, translate nested objects + patmat 10 translate match expressions + C6 0 C6 tests phase assembly after a phase missing in Scaladoc + uncurry 12 uncurry, translate function values to anonymous classes + fields 13 synthesize accessors and fields, add bitmaps for lazy vals + tailcalls 14 replace tail calls by jumps + specialize 15 @specialized-driven class and method specialization + explicitouter 16 this refs to outer pointers + erasure 17 erase types, add interfaces for traits + posterasure 18 clean up erased inline classes + lambdalift 19 move nested functions to top level + constructors 20 move field definitions into constructors + flatten 21 eliminate inner classes + mixin 22 mixin composition + cleanup 23 platform-specific cleanups, generate reflective calls + delambdafy 24 remove lambdas + jvm 25 generate JVM bytecode + terminal 26 the last phase during a compilation run diff --git a/test/files/neg/t8755c/ploogin_1.scala b/test/files/neg/t8755c/ploogin_1.scala new file mode 100644 index 000000000000..7c09ca9dbf99 --- /dev/null +++ b/test/files/neg/t8755c/ploogin_1.scala @@ -0,0 +1,126 @@ + +package t8755 + +import scala.tools.nsc +import nsc.{Global, Phase, plugins} +import plugins.{Plugin, PluginComponent} + +class P(val global: Global) extends Plugin { + override val name = "Testing" + override val description = "Testing phase assembly" + override val components = List[PluginComponent]( + component1, + //component2, + //component3, + //component4, + //component5, + component6, + //component7, + //component8, + ) + + object component1 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C1" + override val description = "C1 tests phase assembly" + override val runsRightAfter = Option("typer") + override val runsAfter = List("typer") + override val runsBefore = List("terminal") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component2 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C2" + override val description = "C2 tests phase assembly impossible constraint" + override val runsRightAfter = Option("patmat") + override val runsAfter = List("typer") + override val runsBefore = List("typer") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component3 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C3" + override val description = "C3 tests phase assembly missing before, phase is ignored" + override val runsRightAfter = None + override val runsAfter = List("typer") + override val runsBefore = List("germinal") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component4 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C4" + override val description = "C4 tests phase assembly impossible constraint not right after" + override val runsRightAfter = None + override val runsAfter = List("typer") + override val runsBefore = List("typer") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component5 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C5" + override val description = "C5 tests phase assembly before a phase missing in Scaladoc" + override val runsRightAfter = None + override val runsAfter = List("typer") + override val runsBefore = List("erasure") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component6 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C6" + override val description = "C6 tests phase assembly after a phase missing in Scaladoc" + override val runsRightAfter = None + override val runsAfter = List("patmat") + //override val runsBefore = List("terminal") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component7 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C7" + override val description = "C7 tests phase assembly if only a before constraint" + override val runsRightAfter = None + override val runsAfter = Nil + override val runsBefore = List("patmat") + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } + object component8 extends PluginComponent { + override val global = P.this.global + override val phaseName = "C8" + override val description = "C8 is before C7 which specifies no after" + override val runsRightAfter = None + override val runsAfter = List("typer") + override val runsBefore = List("C7") // component name, not phase name! + override def newPhase(prev: Phase) = new phase(prev) + class phase(prev: Phase) extends Phase(prev) { + override val name = s"phase $phaseName" + override def run() = println(name) + } + } +} diff --git a/test/files/neg/t8755c/sample_2.scala b/test/files/neg/t8755c/sample_2.scala new file mode 100644 index 000000000000..6a687ef41075 --- /dev/null +++ b/test/files/neg/t8755c/sample_2.scala @@ -0,0 +1,6 @@ +//> using options -Xplugin:. -Xplugin-require:Testing -Vphases -Werror +package sample + +// just a sample that is compiled with the sample plugin enabled +object Sample extends App { +} diff --git a/test/files/neg/t8755c/scalac-plugin.xml b/test/files/neg/t8755c/scalac-plugin.xml new file mode 100644 index 000000000000..ff68af97a9dd --- /dev/null +++ b/test/files/neg/t8755c/scalac-plugin.xml @@ -0,0 +1,5 @@ + + Testing + t8755.P + + diff --git a/test/files/neg/t8777.scala b/test/files/neg/t8777.scala index bd853d7daec5..8d8ad0fa921d 100644 --- a/test/files/neg/t8777.scala +++ b/test/files/neg/t8777.scala @@ -1,4 +1,4 @@ -// scalac: '-Wconf:msg=shadowing a nested class of a parent is deprecated:s' +//> using options '-Wconf:msg=shadowing a nested class of a parent is deprecated:s' package a { trait Test { diff --git a/test/files/neg/t9093.check b/test/files/neg/t9093.check index 2779900e02d2..22ac91dfdbce 100644 --- a/test/files/neg/t9093.check +++ b/test/files/neg/t9093.check @@ -1,4 +1,4 @@ -t9093.scala:3: error: missing argument list for method apply2 in object Main +t9093.scala:3: error: missing argument list for method apply2 in object Main of type [C](fa: Any)(f: C): Null Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing `apply2 _` or `apply2(_)(_)` instead of `apply2`. val x: Unit = apply2(0)/*(0)*/ diff --git a/test/files/neg/t9127.check b/test/files/neg/t9127.check deleted file mode 100644 index 81c3de3cdd5f..000000000000 --- a/test/files/neg/t9127.check +++ /dev/null @@ -1,12 +0,0 @@ -t9127.scala:6: warning: possible missing interpolator: detected interpolated identifier `$s` - val t = "$s" - ^ -t9127.scala:7: warning: possible missing interpolator: detected an interpolated expression - val u = "a${s}b" - ^ -t9127.scala:8: warning: possible missing interpolator: detected interpolated identifier `$s` - val v = "a$s b" - ^ -error: No warnings can be incurred under -Werror. -3 warnings -1 error diff --git a/test/files/neg/t9127.scala b/test/files/neg/t9127.scala deleted file mode 100644 index 1871e63dfa2d..000000000000 --- a/test/files/neg/t9127.scala +++ /dev/null @@ -1,9 +0,0 @@ -// scalac: -Xlint:missing-interpolator -Xfatal-warnings -// - -trait X { - val s = "hello" - val t = "$s" - val u = "a${s}b" - val v = "a$s b" -} diff --git a/test/files/neg/t9232.scala b/test/files/neg/t9232.scala index 453cc1be8a2b..bdc5977ef90a 100644 --- a/test/files/neg/t9232.scala +++ b/test/files/neg/t9232.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings final class Foo(val value: Int) object Foo { diff --git a/test/files/neg/t9398/match.scala b/test/files/neg/t9398/match.scala index 1329b3894588..95015888d5a3 100644 --- a/test/files/neg/t9398/match.scala +++ b/test/files/neg/t9398/match.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class Test { // Should warn that CC(B2) isn't matched def test(c: CC): Unit = c match { diff --git a/test/files/neg/t9617/Test.scala b/test/files/neg/t9617/Test.scala index efdd94f8a15d..2d365a0ebf8f 100644 --- a/test/files/neg/t9617/Test.scala +++ b/test/files/neg/t9617/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // Joint-compilation copy of test/files/neg/t10752/Test_2.scala object Test extends p1.DeprecatedClass { diff --git a/test/files/neg/t9636.scala b/test/files/neg/t9636.scala index 2c0b483e83bd..4c3293d20384 100644 --- a/test/files/neg/t9636.scala +++ b/test/files/neg/t9636.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // import java.io._ diff --git a/test/files/neg/t9675.scala b/test/files/neg/t9675.scala index d4fcdbf4de55..66319c2886b6 100644 --- a/test/files/neg/t9675.scala +++ b/test/files/neg/t9675.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { case class A(x: String) diff --git a/test/files/neg/t9834.scala b/test/files/neg/t9834.scala index a0d5e15dbdba..43a605591655 100644 --- a/test/files/neg/t9834.scala +++ b/test/files/neg/t9834.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object x { def apply() = 42 ; def update(i: Int) = () } diff --git a/test/files/neg/t9847.check b/test/files/neg/t9847.check index 66898657f212..d10c0e852288 100644 --- a/test/files/neg/t9847.check +++ b/test/files/neg/t9847.check @@ -1,6 +1,12 @@ t9847.scala:6: warning: discarded non-Unit value of type Int(42) def f(): Unit = 42 ^ +t9847.scala:9: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 + ^ +t9847.scala:13: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses + 1 + ^ t9847.scala:14: warning: discarded non-Unit value of type Int(1) + 1 ^ @@ -10,22 +16,7 @@ t9847.scala:18: warning: discarded non-Unit value of type Int t9847.scala:21: warning: discarded non-Unit value of type Int def j(): Unit = x + 1 ^ -t9847.scala:6: warning: a pure expression does nothing in statement position - def f(): Unit = 42 - ^ -t9847.scala:9: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 1 - ^ -t9847.scala:13: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses - 1 - ^ -t9847.scala:14: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - + 1 - ^ -t9847.scala:14: warning: a pure expression does nothing in statement position - + 1 - ^ -t9847.scala:23: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +t9847.scala:23: warning: a pure expression does nothing in statement position class C { 42 } ^ t9847.scala:24: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses @@ -35,5 +26,5 @@ t9847.scala:24: warning: a pure expression does nothing in statement position; m class D { 42 ; 17 } ^ error: No warnings can be incurred under -Werror. -12 warnings +9 warnings 1 error diff --git a/test/files/neg/t9847.scala b/test/files/neg/t9847.scala index fba4739f169c..9e6abbffb167 100644 --- a/test/files/neg/t9847.scala +++ b/test/files/neg/t9847.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation -Ywarn-value-discard +//> using options -Werror -Xlint:deprecation -Ywarn-value-discard // trait T { diff --git a/test/files/neg/t9953.scala b/test/files/neg/t9953.scala index 957fc8f04e4b..a106a03920c7 100644 --- a/test/files/neg/t9953.scala +++ b/test/files/neg/t9953.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class X(val v: Int) extends AnyVal diff --git a/test/files/neg/text-blocks/Invalid1.java b/test/files/neg/text-blocks/Invalid1.java index 54c7e98d9219..f49a4d1fd416 100644 --- a/test/files/neg/text-blocks/Invalid1.java +++ b/test/files/neg/text-blocks/Invalid1.java @@ -1,4 +1,4 @@ -// javaVersion: 15+ +//> using jvm 15+ class Invalid1 { public static final String badOpeningDelimiter = """non-whitespace diff --git a/test/files/neg/text-blocks/Invalid2.java b/test/files/neg/text-blocks/Invalid2.java index 08b0a57548aa..3aafd9dcaadb 100644 --- a/test/files/neg/text-blocks/Invalid2.java +++ b/test/files/neg/text-blocks/Invalid2.java @@ -1,4 +1,4 @@ -// javaVersion: 15+ +//> using jvm 15+ class Invalid2 { // Closing delimiter is first three eligible `"""`, not last diff --git a/test/files/neg/too-large.check b/test/files/neg/too-large.check new file mode 100644 index 000000000000..abcefd8bde22 --- /dev/null +++ b/test/files/neg/too-large.check @@ -0,0 +1,4 @@ +error: Error while emitting C +UTF8 string too large +error: Method crash in class C has a bad signature of length 124243 +2 errors diff --git a/test/files/neg/too-large.scala b/test/files/neg/too-large.scala new file mode 100644 index 000000000000..037ca2400933 --- /dev/null +++ b/test/files/neg/too-large.scala @@ -0,0 +1,12 @@ +//> abusing options -Vdebug -Xverify +class C { + type Level1 = Tuple4[Unit, Unit, Unit, Unit] + type Level2 = Tuple4[Level1, Level1, Level1, Level1] + type Level3 = Tuple4[Level2, Level2, Level2, Level2] + type Level4 = Tuple4[Level3, Level3, Level3, Level3] + type Level5 = Tuple4[Level4, Level4, Level4, Level4] + type Level6 = Tuple4[Level5, Level5, Level5, Level5] + type Level7 = Tuple4[Level6, Level6, Level6, Level6] + + def crash(x: Level6): Unit = ??? +} diff --git a/test/files/neg/tostring-interpolated.check b/test/files/neg/tostring-interpolated.check new file mode 100644 index 000000000000..13d0527e6745 --- /dev/null +++ b/test/files/neg/tostring-interpolated.check @@ -0,0 +1,41 @@ +tostring-interpolated.scala:7: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.f + def f = f"$c" // warn + ^ +tostring-interpolated.scala:8: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.s + def s = s"$c" // warn + ^ +tostring-interpolated.scala:9: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.r + def r = raw"$c" // warn + ^ +tostring-interpolated.scala:11: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.format + def format = f"${c.x}%d in $c or $c%s" // warn using c.toString // warn + ^ +tostring-interpolated.scala:11: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.format + def format = f"${c.x}%d in $c or $c%s" // warn using c.toString // warn + ^ +tostring-interpolated.scala:13: warning: Boolean format is null test for non-Boolean + def bool = f"$c%b" // warn just a null check + ^ +tostring-interpolated.scala:15: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.oops + def oops = s"${null} slipped thru my fingers" // warn + ^ +tostring-interpolated.scala:20: error: interpolation uses toString +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=T.greeting + def greeting = s"$sb, world" // warn + ^ +tostring-interpolated.scala:31: error: interpolated Unit value +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=Mitigations.unitized + def unitized = s"unfortunately $shown" // warn accidental unit value + ^ +tostring-interpolated.scala:32: error: interpolated Unit value +Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=w-flag-tostring-interpolated, site=Mitigations.funitized + def funitized = f"unfortunately $shown" // warn accidental unit value + ^ +1 warning +9 errors diff --git a/test/files/neg/tostring-interpolated.scala b/test/files/neg/tostring-interpolated.scala new file mode 100644 index 000000000000..959720e4aacb --- /dev/null +++ b/test/files/neg/tostring-interpolated.scala @@ -0,0 +1,36 @@ +//> using options -Wconf:cat=w-flag-tostring-interpolated:e -Wtostring-interpolated + +case class C(x: Int) + +trait T { + def c = C(42) + def f = f"$c" // warn + def s = s"$c" // warn + def r = raw"$c" // warn + + def format = f"${c.x}%d in $c or $c%s" // warn using c.toString // warn + + def bool = f"$c%b" // warn just a null check + + def oops = s"${null} slipped thru my fingers" // warn + + def ok = s"${c.toString}" + + def sb = new StringBuilder().append("hello") + def greeting = s"$sb, world" // warn +} + +class Mitigations { + + val s = "hello, world" + val i = 42 + def shown() = println("shown") + + def ok = s"$s is ok" + def jersey = s"number $i" + def unitized = s"unfortunately $shown" // warn accidental unit value + def funitized = f"unfortunately $shown" // warn accidental unit value + + def nopct = f"$s is ok" + def nofmt = f"number $i" +} diff --git a/test/files/neg/trait_fields_deprecated_overriding.scala b/test/files/neg/trait_fields_deprecated_overriding.scala index aafc1088159c..73711e59b685 100644 --- a/test/files/neg/trait_fields_deprecated_overriding.scala +++ b/test/files/neg/trait_fields_deprecated_overriding.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // package scala diff --git a/test/files/neg/unchecked-abstract.scala b/test/files/neg/unchecked-abstract.scala index fc9e33a26c60..808128a310ec 100644 --- a/test/files/neg/unchecked-abstract.scala +++ b/test/files/neg/unchecked-abstract.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait Contravariant[-X] trait Invariant[X] diff --git a/test/files/neg/unchecked-impossible.scala b/test/files/neg/unchecked-impossible.scala index c2b78aff963a..8d84fb938921 100644 --- a/test/files/neg/unchecked-impossible.scala +++ b/test/files/neg/unchecked-impossible.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // final case class T2[+A, +B](a: A, b: B) diff --git a/test/files/neg/unchecked-knowable.scala b/test/files/neg/unchecked-knowable.scala index 10882cd3482a..39c967468890 100644 --- a/test/files/neg/unchecked-knowable.scala +++ b/test/files/neg/unchecked-knowable.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // /** Knowable - only final leaves */ sealed abstract class A1 diff --git a/test/files/neg/unchecked-refinement.scala b/test/files/neg/unchecked-refinement.scala index 2d3b27eda23a..491fcfaf33a0 100644 --- a/test/files/neg/unchecked-refinement.scala +++ b/test/files/neg/unchecked-refinement.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // a.scala // Thu Sep 27 09:42:16 PDT 2012 diff --git a/test/files/neg/unchecked-suppress.scala b/test/files/neg/unchecked-suppress.scala index de9ce147cbea..9302ef9e9e16 100644 --- a/test/files/neg/unchecked-suppress.scala +++ b/test/files/neg/unchecked-suppress.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A { def f(x: Any) = x match { diff --git a/test/files/neg/unchecked.scala b/test/files/neg/unchecked.scala index 56526347001e..eee51c67bce3 100644 --- a/test/files/neg/unchecked.scala +++ b/test/files/neg/unchecked.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import language.existentials diff --git a/test/files/neg/unchecked2.scala b/test/files/neg/unchecked2.scala index 35148453869f..007b0b6a8d6e 100644 --- a/test/files/neg/unchecked2.scala +++ b/test/files/neg/unchecked2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { // These warn because it can be statically shown they won't match. diff --git a/test/files/neg/unchecked3.scala b/test/files/neg/unchecked3.scala index c8b636233957..d077a59b8849 100644 --- a/test/files/neg/unchecked3.scala +++ b/test/files/neg/unchecked3.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait A2[T1] final class B2[T1, T2] extends A2[T1] diff --git a/test/files/neg/unicode-arrows-deprecation.scala b/test/files/neg/unicode-arrows-deprecation.scala index e77a7f0a5bec..7a9f05a24d68 100644 --- a/test/files/neg/unicode-arrows-deprecation.scala +++ b/test/files/neg/unicode-arrows-deprecation.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object Test { val a: Int ⇒ Int = x ⇒ x diff --git a/test/files/neg/unit-returns-value.scala b/test/files/neg/unit-returns-value.scala index 6c4295e67864..89ce8d827b9f 100644 --- a/test/files/neg/unit-returns-value.scala +++ b/test/files/neg/unit-returns-value.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def f: Unit = { diff --git a/test/files/neg/universal-lint.scala b/test/files/neg/universal-lint.scala index 86adb81c08c0..c01a573cf939 100644 --- a/test/files/neg/universal-lint.scala +++ b/test/files/neg/universal-lint.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror trait Test { def f = List("").map(_.isInstanceOf) diff --git a/test/files/neg/unreachablechar.scala b/test/files/neg/unreachablechar.scala index ae8d6c32f62c..b17fe0505efc 100644 --- a/test/files/neg/unreachablechar.scala +++ b/test/files/neg/unreachablechar.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Foo extends App{ 'f' match { diff --git a/test/files/neg/unsafe.scala b/test/files/neg/unsafe.scala index f026db2598e2..372280dc868b 100644 --- a/test/files/neg/unsafe.scala +++ b/test/files/neg/unsafe.scala @@ -1,6 +1,6 @@ -// scalac: --release:8 -Yrelease:java.lang -// javaVersion: 19+ +//> using options --release:8 -Yrelease:java.lang +//> using jvm 19+ // -Yrelease opens packages but does not override class definitions // because ct.sym comes first diff --git a/test/files/neg/unused.check b/test/files/neg/unused.check index e85abeec351b..256ea024f817 100644 --- a/test/files/neg/unused.check +++ b/test/files/neg/unused.check @@ -1,21 +1,9 @@ -unused.scala:7: warning: pattern var a in value patvars is never used: use a wildcard `_` or suppress this warning with `a@_` - case C(a, _, _, _) => 1 +unused.scala:7: warning: pattern var x in value patvars is never used + case C(x, 2, _, _) => 1 ^ -unused.scala:8: warning: pattern var b in value patvars is never used: use a wildcard `_` or suppress this warning with `b@_` - case C(_, b, c@_, _) => 2 - ^ -unused.scala:9: warning: pattern var a in value patvars is never used: use a wildcard `_` or suppress this warning with `a@_` - case C(a, b@_, c, d@_) => 3 - ^ -unused.scala:9: warning: pattern var c in value patvars is never used: use a wildcard `_` or suppress this warning with `c@_` - case C(a, b@_, c, d@_) => 3 - ^ -unused.scala:10: warning: pattern var e in value patvars is never used: use a wildcard `_` or suppress this warning with `e@_` +unused.scala:10: warning: pattern var e in value patvars is never used case e => 4 ^ -unused.scala:8: warning: unreachable code - case C(_, b, c@_, _) => 2 - ^ error: No warnings can be incurred under -Werror. -6 warnings +2 warnings 1 error diff --git a/test/files/neg/unused.scala b/test/files/neg/unused.scala index ba0bb7ab7693..397cb4243520 100644 --- a/test/files/neg/unused.scala +++ b/test/files/neg/unused.scala @@ -1,12 +1,12 @@ -// scalac: -Wunused:patvars -Werror +//> using options -Werror -Wunused:patvars case class C(a: Int, b: Int, c: Int, d: Int) object Test { val patvars = C(1, 2, 3, 4) match { - case C(a, _, _, _) => 1 - case C(_, b, c@_, _) => 2 + case C(x, 2, _, _) => 1 + case C(2, b, y@_, _) => 2 case C(a, b@_, c, d@_) => 3 case e => 4 } -} \ No newline at end of file +} diff --git a/test/files/neg/using-source3.check b/test/files/neg/using-source3.check index 5940a51cdc62..24519344e517 100644 --- a/test/files/neg/using-source3.check +++ b/test/files/neg/using-source3.check @@ -3,7 +3,7 @@ it is both defined in the enclosing class D and inherited in the enclosing class In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.f`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D.E.g def g = f ^ diff --git a/test/files/neg/using-source3.scala b/test/files/neg/using-source3.scala index 8cff07076640..9f7c9c2f92f6 100644 --- a/test/files/neg/using-source3.scala +++ b/test/files/neg/using-source3.scala @@ -1,8 +1,8 @@ // skalac: -Werror -Xsource:3 -//> using option -Werror -//> using option -Xsource:3 +//> using options -Werror +//> using options -Xsource:3 class C { def f = 42 diff --git a/test/files/neg/using-source3b.check b/test/files/neg/using-source3b.check index 115116ca9dbc..5bba8f78b9d0 100644 --- a/test/files/neg/using-source3b.check +++ b/test/files/neg/using-source3b.check @@ -3,7 +3,7 @@ it is both defined in the enclosing class D and inherited in the enclosing class In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.f`. Or use `-Wconf:msg=legacy-binding:s` to silence this warning. [quickfixable] -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration, site=D.E.g def g = f ^ diff --git a/test/files/neg/value-discard.scala b/test/files/neg/value-discard.scala index a6bde54878b3..2d6c866c2370 100644 --- a/test/files/neg/value-discard.scala +++ b/test/files/neg/value-discard.scala @@ -1,4 +1,4 @@ -// scalac: -Wvalue-discard -Werror +//> using options -Wvalue-discard -Werror final class UnusedTest { import scala.collection.mutable @@ -25,3 +25,38 @@ final class UnusedTest { def u: Unit = f: Unit // nowarn } + +class UnitAscription { + import scala.concurrent._, ExecutionContext.Implicits._ + + case class C(c: Int) { + def f(i: Int, j: Int = c) = i + j + } + + def f(i: Int, j: Int = 27) = i + j + + def g[A]: List[A] = Nil + + def i: Int = 42 + + def `default arg is inline`: Unit = + f(i = 42): Unit // nowarn + + def `default arg requires block`: Unit = + C(27).f(i = 42): Unit // nowarn + + def `application requires implicit arg`: Unit = + Future(42): Unit // nowarn + + def `application requires inferred type arg`: Unit = + g: Unit // nowarn + + def `implicit selection from this`: Unit = + i: Unit // nowarn +} + +object UnitAscription { + def g[A]: List[A] = Nil + def `application requires inferred type arg`: Unit = + g: Unit // nowarn UnitAscription.g +} diff --git a/test/files/neg/varargs2.scala b/test/files/neg/varargs2.scala index 82ccf97cb03a..26c8da1e43a8 100644 --- a/test/files/neg/varargs2.scala +++ b/test/files/neg/varargs2.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import annotation.* diff --git a/test/files/neg/variant-placeholders-future.scala b/test/files/neg/variant-placeholders-future.scala index 75296ff945b4..62ec844d76f1 100644 --- a/test/files/neg/variant-placeholders-future.scala +++ b/test/files/neg/variant-placeholders-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // object Test { type -_ = Int // error -_ not allowed as a type def name without backticks diff --git a/test/files/neg/view-bounds-deprecation.scala b/test/files/neg/view-bounds-deprecation.scala index 28928c009ddd..4d4e56f3bc7f 100644 --- a/test/files/neg/view-bounds-deprecation.scala +++ b/test/files/neg/view-bounds-deprecation.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object Test { def f[A <% Int](a: A) = null diff --git a/test/files/neg/view-bounds-removal.check b/test/files/neg/view-bounds-removal.check index b13101e96166..3bebd5120cef 100644 --- a/test/files/neg/view-bounds-removal.check +++ b/test/files/neg/view-bounds-removal.check @@ -1,12 +1,12 @@ view-bounds-removal.scala:4: error: view bounds are unsupported; use an implicit parameter instead. example: instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)` -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def f[A <% Int](a: A) = null ^ view-bounds-removal.scala:5: error: view bounds are unsupported; use an implicit parameter instead. example: instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)` -Scala 3 migration messages are errors under -Xsource:3. Use -Wconf / @nowarn to filter them or add -Xmigration to demote them to warnings. +Scala 3 migration messages are issued as errors under -Xsource:3. Use -Wconf or @nowarn to demote them to warnings or suppress. Applicable -Wconf / @nowarn filters for this fatal warning: msg=, cat=scala3-migration def g[C, B <: C, A <% B : Numeric](a: A) = null ^ diff --git a/test/files/neg/view-bounds-removal.scala b/test/files/neg/view-bounds-removal.scala index 4559e7175135..7c1d741d5cdb 100644 --- a/test/files/neg/view-bounds-removal.scala +++ b/test/files/neg/view-bounds-removal.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // object Test { def f[A <% Int](a: A) = null diff --git a/test/files/neg/virtpatmat_exhaust_big.scala b/test/files/neg/virtpatmat_exhaust_big.scala index ee0649c2b4e2..6f53cd24f28a 100644 --- a/test/files/neg/virtpatmat_exhaust_big.scala +++ b/test/files/neg/virtpatmat_exhaust_big.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class Z object Z { diff --git a/test/files/neg/virtpatmat_exhaust_compound.scala b/test/files/neg/virtpatmat_exhaust_compound.scala index 461656968a5c..4860d94558e6 100644 --- a/test/files/neg/virtpatmat_exhaust_compound.scala +++ b/test/files/neg/virtpatmat_exhaust_compound.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait Base case object O1 extends Base diff --git a/test/files/neg/virtpatmat_reach_null.scala b/test/files/neg/virtpatmat_reach_null.scala index 0a98530095ad..f6c8db0ca687 100644 --- a/test/files/neg/virtpatmat_reach_null.scala +++ b/test/files/neg/virtpatmat_reach_null.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class Const { final def excludes(other: Const) = diff --git a/test/files/neg/virtpatmat_reach_sealed_unsealed.scala b/test/files/neg/virtpatmat_reach_sealed_unsealed.scala index 300a0ab85cae..f0a8905f6d72 100644 --- a/test/files/neg/virtpatmat_reach_sealed_unsealed.scala +++ b/test/files/neg/virtpatmat_reach_sealed_unsealed.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class X sealed case class A(x: Int) extends X diff --git a/test/files/neg/virtpatmat_unreach_select.scala b/test/files/neg/virtpatmat_unreach_select.scala index db6caf85b1a3..dc49fe2dabd4 100644 --- a/test/files/neg/virtpatmat_unreach_select.scala +++ b/test/files/neg/virtpatmat_unreach_select.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // class Test { object severity extends Enumeration diff --git a/test/files/neg/warn-inferred-any.scala b/test/files/neg/warn-inferred-any.scala index a717a84ece00..069ddbafa42d 100644 --- a/test/files/neg/warn-inferred-any.scala +++ b/test/files/neg/warn-inferred-any.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:infer-any +//> using options -Xfatal-warnings -Xlint:infer-any // trait Foo[-A <: AnyRef, +B <: AnyRef] { def run[U](x: A)(action: B => U): Boolean = ??? diff --git a/test/files/neg/warn-unused-explicits.scala b/test/files/neg/warn-unused-explicits.scala index eca406ccf5a4..b90ac269fd51 100644 --- a/test/files/neg/warn-unused-explicits.scala +++ b/test/files/neg/warn-unused-explicits.scala @@ -1,4 +1,4 @@ -// scalac: -Wunused:explicits -Werror +//> using options -Wunused:explicits -Werror // trait Context[A] trait ExplicitsOnly { diff --git a/test/files/neg/warn-unused-implicits.check b/test/files/neg/warn-unused-implicits.check index b5c08f8d311e..62482bf568de 100644 --- a/test/files/neg/warn-unused-implicits.check +++ b/test/files/neg/warn-unused-implicits.check @@ -4,6 +4,12 @@ warn-unused-implicits.scala:13: warning: parameter s in method f is never used warn-unused-implicits.scala:33: warning: parameter s in method i is never used def i(implicit s: String, t: Int) = t // yes, warn ^ +warn-unused-implicits.scala:52: warning: parameter ev in method ==> is never used + def ==>[B](b: B)(implicit ev: BadCanEqual[A, B]): Boolean = a == b // warn, ev.run + ^ +warn-unused-implicits.scala:60: warning: parameter m in method f is never used + def f[A](implicit m: MembersOnly[A]) = toString.nonEmpty // warn implicit trait with private member + ^ error: No warnings can be incurred under -Werror. -2 warnings +4 warnings 1 error diff --git a/test/files/neg/warn-unused-implicits.scala b/test/files/neg/warn-unused-implicits.scala index daa2d3b26e4f..2fd2b374f7cd 100644 --- a/test/files/neg/warn-unused-implicits.scala +++ b/test/files/neg/warn-unused-implicits.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:implicits +//> using options -Werror -Wunused:implicits // trait InterFace { @@ -40,3 +40,22 @@ trait U { _: T => override def f()(implicit i: Int): Int = g() // no warn, required by baseclass, scala/bug#12876 def g(): Int } + +trait CanEqual[A, B] +trait BadCanEqual[A, B] extends Runnable + +class EqTest { + implicit class ArrowAssert[A](a: A) { + def ==>[B](b: B)(implicit ev: CanEqual[A, B]): Boolean = a == b // no warn, no non-trivial members + } + implicit class BadArrowAssert[A](a: A) { + def ==>[B](b: B)(implicit ev: BadCanEqual[A, B]): Boolean = a == b // warn, ev.run + } +} + +trait MembersOnly[A] { + private def member() = 42 // don't care whether member is accessible; maybe they must pass it elsewhere +} +class Privately { + def f[A](implicit m: MembersOnly[A]) = toString.nonEmpty // warn implicit trait with private member +} diff --git a/test/files/neg/warn-unused-imports-b/warn-unused-imports_2.scala b/test/files/neg/warn-unused-imports-b/warn-unused-imports_2.scala index 47451b3e7743..d09377524abc 100644 --- a/test/files/neg/warn-unused-imports-b/warn-unused-imports_2.scala +++ b/test/files/neg/warn-unused-imports-b/warn-unused-imports_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports -Ymacro-annotations +//> using options -Werror -Wunused:imports -Ymacro-annotations // class Bippo { def length: Int = 123 diff --git a/test/files/neg/warn-unused-imports/sample_1.scala b/test/files/neg/warn-unused-imports/sample_1.scala index 04765849ee0e..80dcc59cfa10 100644 --- a/test/files/neg/warn-unused-imports/sample_1.scala +++ b/test/files/neg/warn-unused-imports/sample_1.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports +//> using options -Werror -Wunused:imports import language._ diff --git a/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala b/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala index 48f760d12753..d9fc9c69072f 100644 --- a/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala +++ b/test/files/neg/warn-unused-imports/warn-unused-imports_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports +//> using options -Werror -Wunused:imports // class Bippo { def length: Int = 123 diff --git a/test/files/neg/warn-unused-locals.check b/test/files/neg/warn-unused-locals.check index 139b33eb2b09..c3ddc76575dd 100644 --- a/test/files/neg/warn-unused-locals.check +++ b/test/files/neg/warn-unused-locals.check @@ -4,6 +4,9 @@ warn-unused-locals.scala:9: warning: local var x in method f0 is never used warn-unused-locals.scala:16: warning: local val b in method f1 is never used val b = new Outer // warn ^ +warn-unused-locals.scala:20: warning: local var x in method f2 is never updated: consider using immutable val + var x = 100 // warn about it being a var + ^ warn-unused-locals.scala:27: warning: local object HiObject in method l1 is never used object HiObject { def f = this } // warn ^ @@ -16,9 +19,6 @@ warn-unused-locals.scala:32: warning: local class DingDongDoobie is never used warn-unused-locals.scala:35: warning: local type OtherThing is never used type OtherThing = String // warn ^ -warn-unused-locals.scala:20: warning: local var x in method f2 is never updated: consider using immutable val - var x = 100 // warn about it being a var - ^ error: No warnings can be incurred under -Werror. 7 warnings 1 error diff --git a/test/files/neg/warn-unused-locals.scala b/test/files/neg/warn-unused-locals.scala index f8a2ea249a62..ef9068d4845e 100644 --- a/test/files/neg/warn-unused-locals.scala +++ b/test/files/neg/warn-unused-locals.scala @@ -1,4 +1,4 @@ -// scalac: -Wunused:locals -Werror +//> using options -Wunused:locals -Werror class Outer { class Inner @@ -36,3 +36,8 @@ object Types { (new Bippy): Something } } + +// breakage: local val x$1 in method skolemize is never used +case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) { + def skolemize: SymbolKind = copy(accurate = s"$accurate skolem", abbreviation = s"$abbreviation#SKO") +} diff --git a/test/files/neg/warn-unused-params.check b/test/files/neg/warn-unused-params.check index 402f88d99e36..3f02ca64cd49 100644 --- a/test/files/neg/warn-unused-params.check +++ b/test/files/neg/warn-unused-params.check @@ -25,9 +25,6 @@ warn-unused-params.scala:87: warning: parameter ev in method g2 is never used warn-unused-params.scala:91: warning: parameter i in anonymous function is never used def f = (i: Int) => answer // warn ^ -warn-unused-params.scala:97: warning: parameter i in anonymous function is never used - def g = for (i <- List(1)) yield answer // warn map.(i => 42) - ^ warn-unused-params.scala:101: warning: parameter ctx in method f is never used def f[A](implicit ctx: Context[A]) = answer ^ @@ -43,6 +40,9 @@ warn-unused-params.scala:111: warning: parameter b in method f is never used warn-unused-params.scala:134: warning: parameter s in method i is never used def i(implicit s: String) = answer // yes, warn ^ +warn-unused-params.scala:142: warning: parameter s in method f is never used + def f(s: Serializable) = toString.nonEmpty // warn explicit param of marker trait + ^ error: No warnings can be incurred under -Werror. 15 warnings 1 error diff --git a/test/files/neg/warn-unused-params.scala b/test/files/neg/warn-unused-params.scala index b046287304d2..4a03355e533e 100644 --- a/test/files/neg/warn-unused-params.scala +++ b/test/files/neg/warn-unused-params.scala @@ -1,4 +1,4 @@ -// scalac: -Wunused:params -Werror +//> using options -Wunused:params -Werror // import Answers._ @@ -94,9 +94,9 @@ trait Anonymous { def f2: Int => Int = _ + 1 // no warn placeholder syntax (a fresh name and synthetic parameter) - def g = for (i <- List(1)) yield answer // warn map.(i => 42) + def g = for (i <- List(1)) yield answer // no warn patvar elaborated as map.(i => 42) } -trait Context[A] +trait Context[A] { def m(a: A): A = a } trait Implicits { def f[A](implicit ctx: Context[A]) = answer def g[A: Context] = answer @@ -137,3 +137,23 @@ trait BadMix { _: InterFace => class Unequal { override def equals(other: Any) = toString.nonEmpty // no warn non-trivial RHS, required by universal method } + +class Seriously { + def f(s: Serializable) = toString.nonEmpty // warn explicit param of marker trait +} + +class TryStart(start: String) { + def FINALLY(end: END.type) = start +} + +object END + +class Nested { + @annotation.unused private def actuallyNotUsed(fresh: Int, stale: Int) = fresh +} + +class Annie(value: String) extends annotation.StaticAnnotation // no warn for annotation + +class Selfie { + def f(i: Int, j: Int) = this // no warn this is trivial +} diff --git a/test/files/neg/warn-unused-patvars.check b/test/files/neg/warn-unused-patvars.check index 058753bbdfbd..d473a2bc45bd 100644 --- a/test/files/neg/warn-unused-patvars.check +++ b/test/files/neg/warn-unused-patvars.check @@ -1,5 +1,5 @@ -warn-unused-patvars.scala:11: warning: private val x in trait Boundings is never used - private val x = 42 // warn, sanity check +warn-unused-patvars.scala:10: warning: private val x in trait Boundings is never used + private val x = 42 // warn, to ensure that warnings are enabled ^ error: No warnings can be incurred under -Werror. 1 warning diff --git a/test/files/neg/warn-unused-patvars.scala b/test/files/neg/warn-unused-patvars.scala index 2f4930d5ac60..2a015e72dc23 100644 --- a/test/files/neg/warn-unused-patvars.scala +++ b/test/files/neg/warn-unused-patvars.scala @@ -1,14 +1,13 @@ -// scalac: -Ywarn-unused:-patvars,_ -Xfatal-warnings -// +//> using options -Wunused:-patvars,_ -Werror -// verify no warning when -Ywarn-unused:-patvars +// verify NO warning when -Wunused:-patvars case class C(a: Int, b: String, c: Option[String]) case class D(a: Int) trait Boundings { - private val x = 42 // warn, sanity check + private val x = 42 // warn, to ensure that warnings are enabled def c = C(42, "hello", Some("world")) def d = D(42) diff --git a/test/files/neg/warn-unused-privates.check b/test/files/neg/warn-unused-privates.check index 17185ed2937c..4c49b4c09e65 100644 --- a/test/files/neg/warn-unused-privates.check +++ b/test/files/neg/warn-unused-privates.check @@ -4,9 +4,15 @@ class Boppy extends { warn-unused-privates.scala:5: warning: private constructor in class Bippy is never used private def this(c: Int) = this(c, c) // warn ^ +warn-unused-privates.scala:6: warning: private method bippy in class Bippy is never used + private def bippy(x: Int): Int = bippy(x) // warn + ^ warn-unused-privates.scala:7: warning: private method boop in class Bippy is never used private def boop(x: Int) = x+a+b // warn ^ +warn-unused-privates.scala:8: warning: private val MILLIS1 in class Bippy is never used + final private val MILLIS1 = 2000 // now warn, might have been inlined + ^ warn-unused-privates.scala:9: warning: private val MILLIS2 in class Bippy is never used final private val MILLIS2: Int = 1000 // warn ^ @@ -19,6 +25,9 @@ warn-unused-privates.scala:17: warning: private val BOOL in object Bippy is neve warn-unused-privates.scala:41: warning: private val hummer in class Boppy is never used private val hummer = "def" // warn ^ +warn-unused-privates.scala:43: warning: private val bum in class Boppy is never used + private final val bum = "ghi" // now warn, might have been (was) inlined + ^ warn-unused-privates.scala:48: warning: private var v1 in trait Accessors is never used private var v1: Int = 0 // warn ^ @@ -43,15 +52,27 @@ warn-unused-privates.scala:68: warning: private var s2 in class StableAccessors warn-unused-privates.scala:69: warning: private var s3 in class StableAccessors is never used private var s3: Int = 0 // warn, never got ^ +warn-unused-privates.scala:72: warning: local var s5 in class StableAccessors is never updated: consider using immutable val + private[this] var s5 = 0 // warn, never set + ^ warn-unused-privates.scala:87: warning: private default argument in trait DefaultArgs is never used private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3 ^ warn-unused-privates.scala:87: warning: private default argument in trait DefaultArgs is never used private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3 ^ +warn-unused-privates.scala:114: warning: local var x in method f2 is never updated: consider using immutable val + var x = 100 // warn about it being a var + ^ warn-unused-privates.scala:120: warning: private object Dongo in object Types is never used private object Dongo { def f = this } // warn ^ +warn-unused-privates.scala:121: warning: private class Bar1 in object Types is never used + private class Bar1 // warn + ^ +warn-unused-privates.scala:123: warning: private type Alias1 in object Types is never used + private type Alias1 = String // warn + ^ warn-unused-privates.scala:153: warning: private method x_= in class OtherNames is never used private def x_=(i: Int): Unit = () ^ @@ -61,24 +82,24 @@ warn-unused-privates.scala:154: warning: private method x in class OtherNames is warn-unused-privates.scala:155: warning: private method y_= in class OtherNames is never used private def y_=(i: Int): Unit = () ^ -warn-unused-privates.scala:121: warning: private class Bar1 in object Types is never used - private class Bar1 // warn - ^ -warn-unused-privates.scala:123: warning: private type Alias1 in object Types is never used - private type Alias1 = String // warn - ^ warn-unused-privates.scala:233: warning: private class for your eyes only in object not even using companion privates is never used private implicit class `for your eyes only`(i: Int) { // warn ^ warn-unused-privates.scala:249: warning: private class D in class nonprivate alias is enclosing is never used private class D extends C2 // warn ^ -warn-unused-privates.scala:72: warning: local var s5 in class StableAccessors is never updated: consider using immutable val - private[this] var s5 = 0 // warn, never set +warn-unused-privates.scala:269: warning: private val n in class t12992 enclosing def is unused is never used + private val n = 42 + ^ +warn-unused-privates.scala:274: warning: private method f in class recursive reference is not a usage is never used + private def f(i: Int): Int = // warn + ^ +warn-unused-privates.scala:277: warning: private class P in class recursive reference is not a usage is never used + private class P { + ^ +warn-unused-privates.scala:284: warning: private val There in class Constantly is never used + private final val There = "there" // warn ^ -warn-unused-privates.scala:114: warning: local var x in method f2 is never updated: consider using immutable val - var x = 100 // warn about it being a var - ^ error: No warnings can be incurred under -Werror. -27 warnings +34 warnings 1 error diff --git a/test/files/neg/warn-unused-privates.scala b/test/files/neg/warn-unused-privates.scala index 30fad175955e..91b5752fa44d 100644 --- a/test/files/neg/warn-unused-privates.scala +++ b/test/files/neg/warn-unused-privates.scala @@ -1,11 +1,11 @@ // -// scalac: -deprecation -Wunused:privates -Xfatal-warnings +//> using options -deprecation -Werror -Wunused:privates // class Bippy(a: Int, b: Int) { private def this(c: Int) = this(c, c) // warn - private def bippy(x: Int): Int = bippy(x) // TODO: could warn + private def bippy(x: Int): Int = bippy(x) // warn private def boop(x: Int) = x+a+b // warn - final private val MILLIS1 = 2000 // no warn, might have been inlined + final private val MILLIS1 = 2000 // now warn, might have been inlined final private val MILLIS2: Int = 1000 // warn final private val HI_COMPANION: Int = 500 // no warn, accessed from companion def hi() = Bippy.HI_INSTANCE @@ -40,7 +40,7 @@ class Boppy extends { val dinger = hom private val hummer = "def" // warn - private final val bum = "ghi" // no warn, might have been (was) inlined + private final val bum = "ghi" // now warn, might have been (was) inlined final val bum2 = "ghi" // no warn, same } @@ -264,3 +264,47 @@ trait `short comings` { class `issue 12600 ignore abstract types` { type Abs } + +class `t12992 enclosing def is unused` { + private val n = 42 + @annotation.unused def f() = n + 2 // unused code uses n +} + +class `recursive reference is not a usage` { + private def f(i: Int): Int = // warn + if (i <= 0) i + else f(i-1) + private class P { + def f() = new P() + } +} + +class Constantly { + private final val Here = "here" + private final val There = "there" // warn + def bromide = Here + " today, gone tomorrow." +} + +class Annots { + import annotation._ + + trait T { + def value: Int + } + + class C { + private final val Here = "here" + private final val There = "msg=there" + def f(implicit @implicitNotFound(Here) t: T) = t.value + def x: String @nowarn(There) = "" + } + + // cf HashMap#mergeInto which looped on type of new unchecked + // case bm: BitmapIndexedMapNode[K, V] @unchecked => + class Weird[K, V] { + def f(other: Weird[K, V]) = + other match { + case weird: Weird[K, V] @unchecked => + } + } +} diff --git a/test/files/neg/warn-useless-svuid.scala b/test/files/neg/warn-useless-svuid.scala index 25882dc1bcd6..3253cb8ec8e0 100644 --- a/test/files/neg/warn-useless-svuid.scala +++ b/test/files/neg/warn-useless-svuid.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:serial -Xfatal-warnings +//> using options -Xlint:serial -Xfatal-warnings // @SerialVersionUID(1L) class X diff --git a/test/files/neg/wconfSource1.scala b/test/files/neg/wconfSource1.scala index 19e191de5a19..0e7e8805170d 100644 --- a/test/files/neg/wconfSource1.scala +++ b/test/files/neg/wconfSource1.scala @@ -1,4 +1,4 @@ -// scalac: -Wconf:src=.*Source.*&cat=deprecation:e,src=Source1.scala&msg=statement:e,src=wconfSource1&msg=statement:e,src=wconfSource1.scala&msg=statement:i +//> using options -Wconf:src=.*Source.*&cat=deprecation:e,src=Source1.scala&msg=statement:e,src=wconfSource1&msg=statement:e,src=wconfSource1.scala&msg=statement:i // src=Source1.scala doesn't match: the pattern needs to start at a path segment (after `/`) // src=wconfSource1 doesn't match: the pattern needs to match to the end of the path (.scala) diff --git a/test/files/neg/wconfSource2.scala b/test/files/neg/wconfSource2.scala index 022356993884..549476972c76 100644 --- a/test/files/neg/wconfSource2.scala +++ b/test/files/neg/wconfSource2.scala @@ -1,4 +1,4 @@ -// scalac: -Wconf:src=test/files/neg/wconfSource2.scala&cat=deprecation:e,src=test/.*&msg=statement:i,src=/neg/.*&cat=feature-reflective-calls:i +//> using options -Wconf:src=test/files/neg/wconfSource2.scala&cat=deprecation:e,src=test/.*&msg=statement:i,src=/neg/.*&cat=feature-reflective-calls:i class C { @deprecated("", "") def dep = 0 diff --git a/test/files/neg/wildcards-future.scala b/test/files/neg/wildcards-future.scala index 54b7675813e7..f69e0b02f79d 100644 --- a/test/files/neg/wildcards-future.scala +++ b/test/files/neg/wildcards-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // object Test { val underscores: Map[_ <: AnyRef, _ >: Null] = Map() diff --git a/test/files/neg/xlint-captured.scala b/test/files/neg/xlint-captured.scala index e4acdf7bcc59..ded04c983428 100644 --- a/test/files/neg/xlint-captured.scala +++ b/test/files/neg/xlint-captured.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wperformance +//> using options -Werror -Wperformance object Test { var a, b = 0 // ok def mkStrangeCounter(): Int => Int = { diff --git a/test/files/neg/xml-parens.scala b/test/files/neg/xml-parens.scala index 490b23952804..b97bf73442b4 100644 --- a/test/files/neg/xml-parens.scala +++ b/test/files/neg/xml-parens.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:typer +//> using options -Ystop-after:typer // object Test { () diff --git a/test/files/neg/yimports-custom-b/C_2.scala b/test/files/neg/yimports-custom-b/C_2.scala index 09940d0a6d42..37901f6cbeba 100644 --- a/test/files/neg/yimports-custom-b/C_2.scala +++ b/test/files/neg/yimports-custom-b/C_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:hello.world.minidef +//> using options -Yimports:hello.world.minidef import hello.{world => hw} import hw.minidef.{Magic => Answer} diff --git a/test/files/neg/yimports-custom-b/minidef_1.scala b/test/files/neg/yimports-custom-b/minidef_1.scala index befc137b6ab6..78d2f3c03bfc 100644 --- a/test/files/neg/yimports-custom-b/minidef_1.scala +++ b/test/files/neg/yimports-custom-b/minidef_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala +//> using options -Yimports:scala package hello.world diff --git a/test/files/neg/yimports-custom/C_2.scala b/test/files/neg/yimports-custom/C_2.scala index 660a580d6fee..5a5482c51058 100644 --- a/test/files/neg/yimports-custom/C_2.scala +++ b/test/files/neg/yimports-custom/C_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:hello.world.minidef +//> using options -Yimports:hello.world.minidef class C { val v: Numb = Magic diff --git a/test/files/neg/yimports-masked/C_2.scala b/test/files/neg/yimports-masked/C_2.scala index e3eade457876..88d6e61a3e4b 100644 --- a/test/files/neg/yimports-masked/C_2.scala +++ b/test/files/neg/yimports-masked/C_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala,hello.world.minidef +//> using options -Yimports:scala,hello.world.minidef // import at top level or top of package disables implicit import. // the import can appear at any statement position, here, end of package. diff --git a/test/files/neg/yimports-nojava.scala b/test/files/neg/yimports-nojava.scala index 955685d16f7a..d7ef3646cdf4 100644 --- a/test/files/neg/yimports-nojava.scala +++ b/test/files/neg/yimports-nojava.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala,scala.Predef +//> using options -Yimports:scala,scala.Predef trait T { def f() = println("hello, world!") diff --git a/test/files/neg/yimports-nosuch.scala b/test/files/neg/yimports-nosuch.scala index c868edfa3d6c..617f0b84ba12 100644 --- a/test/files/neg/yimports-nosuch.scala +++ b/test/files/neg/yimports-nosuch.scala @@ -1,3 +1,3 @@ -// scalac: -Yimports:skala,scala.Predeff +//> using options -Yimports:skala,scala.Predeff // class C diff --git a/test/files/neg/yimports-predef.scala b/test/files/neg/yimports-predef.scala index 6165c566ac82..d6b2b7be4197 100644 --- a/test/files/neg/yimports-predef.scala +++ b/test/files/neg/yimports-predef.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala,scala.Predef +//> using options -Yimports:scala,scala.Predef // import Predef.{any2stringadd => _, _} diff --git a/test/files/neg/yimports-stable/C_2.scala b/test/files/neg/yimports-stable/C_2.scala index dfadaef12186..6c57e369be71 100644 --- a/test/files/neg/yimports-stable/C_2.scala +++ b/test/files/neg/yimports-stable/C_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala,scala.Predef,hello.world.potions +//> using options -Yimports:scala,scala.Predef,hello.world.potions // class C { val v: Numb = magic diff --git a/test/files/pos/and-future.scala b/test/files/pos/and-future.scala index f7e15e822ecc..27ace4bc8d54 100644 --- a/test/files/pos/and-future.scala +++ b/test/files/pos/and-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // trait X diff --git a/test/files/pos/annotated-outer.scala b/test/files/pos/annotated-outer.scala index 86f6fe675ace..51a26f2aa0b4 100644 --- a/test/files/pos/annotated-outer.scala +++ b/test/files/pos/annotated-outer.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { trait MySet[A] trait MyMap[K, +V] { diff --git a/test/files/pos/auto-application.scala b/test/files/pos/auto-application.scala index 1e9ec1b1c209..293136c39b0d 100644 --- a/test/files/pos/auto-application.scala +++ b/test/files/pos/auto-application.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -deprecation -Xsource:3 +//> using options -Werror -deprecation -Xsource:3 // class Test { def a1(xs: List[String]): Int = xs.hashCode diff --git a/test/files/pos/byname-implicits-31/Main_2.scala b/test/files/pos/byname-implicits-31/Main_2.scala index 7f7962f38ef6..7d279d8b9cae 100644 --- a/test/files/pos/byname-implicits-31/Main_2.scala +++ b/test/files/pos/byname-implicits-31/Main_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ycheck:_ +//> using options -Ycheck:_ object Test { util.lazily[Ping] } diff --git a/test/files/pos/byname-implicits-32/Main_2.scala b/test/files/pos/byname-implicits-32/Main_2.scala index 7f7962f38ef6..7d279d8b9cae 100644 --- a/test/files/pos/byname-implicits-32/Main_2.scala +++ b/test/files/pos/byname-implicits-32/Main_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ycheck:_ +//> using options -Ycheck:_ object Test { util.lazily[Ping] } diff --git a/test/files/pos/byname-implicits-33/Main_2.scala b/test/files/pos/byname-implicits-33/Main_2.scala index d3a14994ca12..e1e0214b50c3 100644 --- a/test/files/pos/byname-implicits-33/Main_2.scala +++ b/test/files/pos/byname-implicits-33/Main_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ycheck:_ +//> using options -Ycheck:_ object Test { util.lazily[Functor[Rec]] } diff --git a/test/files/pos/byname-implicits-34/Main_2.scala b/test/files/pos/byname-implicits-34/Main_2.scala index d2bcbe4645d9..249d845e0340 100644 --- a/test/files/pos/byname-implicits-34/Main_2.scala +++ b/test/files/pos/byname-implicits-34/Main_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ycheck:_ +//> using options -Ycheck:_ object Test { util.lazily[Rec] } diff --git a/test/files/pos/case-object-add-serializable.scala b/test/files/pos/case-object-add-serializable.scala index 7728649414a7..b773f08a7e7c 100644 --- a/test/files/pos/case-object-add-serializable.scala +++ b/test/files/pos/case-object-add-serializable.scala @@ -1,4 +1,4 @@ -// scalac: -Xdev -Werror +//> using options -Xdev -Werror // Was: "warning: !!! base trait Serializable not found in basetypes of object Person. This might indicate incorrect caching of TypeRef#parents." // under -Xdev class Test { diff --git a/test/files/pos/caseclass_private_constructor.scala b/test/files/pos/caseclass_private_constructor.scala index acdde94ef232..c401ef41437b 100644 --- a/test/files/pos/caseclass_private_constructor.scala +++ b/test/files/pos/caseclass_private_constructor.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 -Xmigration +//> using options -Wconf:cat=scala3-migration:ws -Xsource:3 case class A private (i: Int) object A { diff --git a/test/files/pos/classtag-pos.scala b/test/files/pos/classtag-pos.scala index f30c3c3c1685..83c607f4b85c 100644 --- a/test/files/pos/classtag-pos.scala +++ b/test/files/pos/classtag-pos.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// import scala.reflect.runtime.universe._ class A { diff --git a/test/files/pos/cycle/X_2.scala b/test/files/pos/cycle/X_2.scala index 68c22b86446f..3effc687d68f 100644 --- a/test/files/pos/cycle/X_2.scala +++ b/test/files/pos/cycle/X_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ybreak-cycles +//> using options -Ybreak-cycles import bar.J_1._ //<--- illegal cyclic reference involving class X diff --git a/test/files/pos/debug-reset-local-attrs.scala b/test/files/pos/debug-reset-local-attrs.scala index 94d68ff9c0f7..cbc86a2c901f 100644 --- a/test/files/pos/debug-reset-local-attrs.scala +++ b/test/files/pos/debug-reset-local-attrs.scala @@ -1,2 +1,2 @@ -// scalac: -Ydebug +//> using options -Ydebug case class FT(f : Float) diff --git a/test/files/pos/delambdafy_t6260_method.scala b/test/files/pos/delambdafy_t6260_method.scala index 644e2681dc19..7c073c0d3066 100644 --- a/test/files/pos/delambdafy_t6260_method.scala +++ b/test/files/pos/delambdafy_t6260_method.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method +//> using options -Ydelambdafy:method class Box[X](val x: X) extends AnyVal { def map[Y](f: X => Y): Box[Y] = ((bx: Box[X]) => new Box(f(bx.x)))(this) diff --git a/test/files/pos/dotless-targs-ranged.scala b/test/files/pos/dotless-targs-ranged.scala index 67d4f8d80dcb..935e1dd8f8a9 100644 --- a/test/files/pos/dotless-targs-ranged.scala +++ b/test/files/pos/dotless-targs-ranged.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:true +// class A { def fn1 = List apply 1 def fn2 = List apply[Int] 2 diff --git a/test/files/pos/dotless-targs.scala b/test/files/pos/dotless-targs.scala index e88f7206dc6f..7e208d5198c5 100644 --- a/test/files/pos/dotless-targs.scala +++ b/test/files/pos/dotless-targs.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false class A { def fn1 = List apply 1 def fn2 = List apply[Int] 2 diff --git a/test/files/pos/exhaust_alternatives.scala b/test/files/pos/exhaust_alternatives.scala index 07bd1e01775e..dfa3e0919f23 100644 --- a/test/files/pos/exhaust_alternatives.scala +++ b/test/files/pos/exhaust_alternatives.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings sealed abstract class X sealed case class A(x: Boolean) extends X case object B extends X diff --git a/test/files/pos/existential-slow-compile1.scala b/test/files/pos/existential-slow-compile1.scala index 8d7007354624..9ebfcc0e46ee 100644 --- a/test/files/pos/existential-slow-compile1.scala +++ b/test/files/pos/existential-slow-compile1.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:refchecks -Yrangepos +//> using options -Ystop-after:refchecks class C { type L[+A] = scala.collection.immutable.List[A] def test = { diff --git a/test/files/pos/existential-slow-compile2.scala b/test/files/pos/existential-slow-compile2.scala index 901c06880d41..3c779b477e73 100644 --- a/test/files/pos/existential-slow-compile2.scala +++ b/test/files/pos/existential-slow-compile2.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:refchecks -Yrangepos +//> using options -Ystop-after:refchecks class C { class L[+A] def test = { diff --git a/test/files/pos/forcomp-treepos.scala b/test/files/pos/forcomp-treepos.scala new file mode 100644 index 000000000000..8e48a749c59f --- /dev/null +++ b/test/files/pos/forcomp-treepos.scala @@ -0,0 +1,5 @@ +//> using options -Yvalidate-pos:typer +object A { + def foo(list: List[String]) = for (string <- list if string.length > 5) + println(string) +} diff --git a/test/files/pos/generic-sigs.scala b/test/files/pos/generic-sigs.scala index f1293f8da12f..841849e70c21 100644 --- a/test/files/pos/generic-sigs.scala +++ b/test/files/pos/generic-sigs.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings import language.existentials object A { diff --git a/test/files/pos/higherKinds.scala b/test/files/pos/higherKinds.scala index 083c3463f811..27f43ed0d061 100644 --- a/test/files/pos/higherKinds.scala +++ b/test/files/pos/higherKinds.scala @@ -1,4 +1,4 @@ -// scalac: -feature -Werror +//> using options -feature -Werror object Test { type F[A] <: List[A] def foo[G[X] <: List[X]](x: F[Int]): F[Int] = x diff --git a/test/files/pos/hk-existential-subtype.scala b/test/files/pos/hk-existential-subtype.scala index cc61b7deaa5d..9528c404545e 100644 --- a/test/files/pos/hk-existential-subtype.scala +++ b/test/files/pos/hk-existential-subtype.scala @@ -1,4 +1,4 @@ -// scalac: -language:higherKinds,existentials -Xfatal-warnings +//> using options -language:higherKinds,existentials -Xfatal-warnings class Functor[F[_]] object Functor { val someF: Functor[F] forSome { type F[_] } = new Functor[Option] diff --git a/test/files/pos/hkarray.scala b/test/files/pos/hkarray.scala index 11e7b50f53ca..93457452dbbb 100644 --- a/test/files/pos/hkarray.scala +++ b/test/files/pos/hkarray.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -language:higherKinds +//> using options -Xfatal-warnings -language:higherKinds trait Foo[CC[_]] { } class Bip { diff --git a/test/files/pos/i11371.scala b/test/files/pos/i11371.scala index 74156b777c9f..c895d83e6d20 100644 --- a/test/files/pos/i11371.scala +++ b/test/files/pos/i11371.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // object HelloWorld { def whileLoop: Int = { diff --git a/test/files/pos/i20006-java/J.java b/test/files/pos/i20006-java/J.java new file mode 100644 index 000000000000..65705b33d256 --- /dev/null +++ b/test/files/pos/i20006-java/J.java @@ -0,0 +1,4 @@ +public class J { + private String mo; + public String mo() { return this.mo; } +} diff --git a/test/files/pos/i20006-java/T.scala b/test/files/pos/i20006-java/T.scala new file mode 100644 index 000000000000..4b3aaa7c92f2 --- /dev/null +++ b/test/files/pos/i20006-java/T.scala @@ -0,0 +1,5 @@ +//> using options -Ypickle-java + +class T { + new J().mo(); +} diff --git a/test/files/pos/i20026/Empty.java b/test/files/pos/i20026/Empty.java new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/files/pos/i20026/JFun.java b/test/files/pos/i20026/JFun.java new file mode 100644 index 000000000000..d2109909c3e0 --- /dev/null +++ b/test/files/pos/i20026/JFun.java @@ -0,0 +1,4 @@ +@FunctionalInterface +public interface JFun { + String f(String s); +} diff --git a/test/files/pos/i20026/JTest.java b/test/files/pos/i20026/JTest.java new file mode 100644 index 000000000000..c91f533383b5 --- /dev/null +++ b/test/files/pos/i20026/JTest.java @@ -0,0 +1,4 @@ + +@api.TestInstance(api.TestInstance.Lifecycle.PER_CLASS) +public class JTest { +} diff --git a/test/files/pos/i20026/KTest.java b/test/files/pos/i20026/KTest.java new file mode 100644 index 000000000000..9b32932e780c --- /dev/null +++ b/test/files/pos/i20026/KTest.java @@ -0,0 +1,6 @@ + +import api.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class KTest { +} diff --git a/test/files/pos/i20026/TestInstance.java b/test/files/pos/i20026/TestInstance.java new file mode 100644 index 000000000000..11cca9698664 --- /dev/null +++ b/test/files/pos/i20026/TestInstance.java @@ -0,0 +1,20 @@ + +package api; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +public @interface TestInstance { + enum Lifecycle { + PER_CLASS; + } + Lifecycle value(); +} diff --git a/test/files/pos/i20026/test.scala b/test/files/pos/i20026/test.scala new file mode 100644 index 000000000000..838788d85923 --- /dev/null +++ b/test/files/pos/i20026/test.scala @@ -0,0 +1,6 @@ + +object Test extends App { + println { + (new JTest, new KTest, ((s: String) => s): JFun) + } +} diff --git a/test/files/pos/i21319/Foo.java b/test/files/pos/i21319/Foo.java new file mode 100644 index 000000000000..1240d014b7e7 --- /dev/null +++ b/test/files/pos/i21319/Foo.java @@ -0,0 +1,8 @@ +package app; + +import java.util.Optional; +import lib.*; + +public class Foo { + private java.util.@lib.Valid Optional userId; +} diff --git a/test/files/pos/i21319/Test.scala b/test/files/pos/i21319/Test.scala new file mode 100644 index 000000000000..a85c8f461aab --- /dev/null +++ b/test/files/pos/i21319/Test.scala @@ -0,0 +1,3 @@ +package app + +class Test diff --git a/test/files/pos/i21319/Valid.java b/test/files/pos/i21319/Valid.java new file mode 100644 index 000000000000..17e0e1173726 --- /dev/null +++ b/test/files/pos/i21319/Valid.java @@ -0,0 +1,17 @@ +package lib; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE }) +@Retention(RUNTIME) +@Documented +public @interface Valid {} diff --git a/test/files/pos/ifunc.scala b/test/files/pos/ifunc.scala index 3d604ec3fe15..45b221fcdb4e 100644 --- a/test/files/pos/ifunc.scala +++ b/test/files/pos/ifunc.scala @@ -8,3 +8,23 @@ trait T { val g = (b: () => Boolean) => while (b()) println() // less weird } + +import language.implicitConversions + +class Setting { + def tap(f: this.type => Unit): this.type = { f(this); this } +} +class BooleanSetting extends Setting { + def tap2(f: BooleanSetting => Unit): BooleanSetting = { f(this); this } +} +object BooleanSetting { + implicit def cv(s: BooleanSetting): Boolean = true +} + +object Test extends App { + val setting = new Setting().tap(println) + val boolean = new BooleanSetting().tap(if (_) println("yes")) + val bool1 = new BooleanSetting().tap(s => if (s) println("yes")) + val bool2a = new BooleanSetting().tap2(s => if (s) println("yes")) + val bool2b = new BooleanSetting().tap2(if (_) println("yes")) +} diff --git a/test/files/pos/ignore-wperf.scala b/test/files/pos/ignore-wperf.scala index 24c4e6a5c4ba..b63323bd07fb 100644 --- a/test/files/pos/ignore-wperf.scala +++ b/test/files/pos/ignore-wperf.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wperformance -Wconf:cat=lint-performance:s +//> using options -Werror -Wperformance -Wconf:cat=lint-performance:s class C { var x = 0 diff --git a/test/files/pos/import-future.scala b/test/files/pos/import-future.scala index 30e499ca0bb1..0ffe056ee49d 100644 --- a/test/files/pos/import-future.scala +++ b/test/files/pos/import-future.scala @@ -1,5 +1,4 @@ -// scalac: -Xsource:3 -// +//> using options -Xsource:3 import java.io as jio import scala.{collection as c} @@ -31,3 +30,31 @@ object starring { val f = Future(42) val r = Await.result(f, D.Inf) } + +trait T[A] { + def t: A +} +object T { + implicit def tInt: T[Int] = new T[Int] { + def t: Int = 42 + } + def f[A](implicit t: T[A]): A = t.t +} +object X { + import T.given + def g = T.f[Int] // was given is not a member +} + +class status_quo { + import scala.util.chaining._ + import scala.concurrent.duration._ + def f = 42.tap(println) + def g = 42.seconds +} + +class givenly { + import scala.util.chaining.given + import scala.concurrent.duration.given + def f = 42.tap(println) + def g = 42.seconds +} diff --git a/test/files/pos/infixed.scala b/test/files/pos/infixed.scala index 5004b90f4ac9..ac03760491e6 100644 --- a/test/files/pos/infixed.scala +++ b/test/files/pos/infixed.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:leading-infix class K { def x(y: Int) = 0 } diff --git a/test/files/pos/inline-access-levels/A_1.scala b/test/files/pos/inline-access-levels/A_1.scala index ff2620161c65..b8fa46ba6a71 100644 --- a/test/files/pos/inline-access-levels/A_1.scala +++ b/test/files/pos/inline-access-levels/A_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt -Werror +//> using options -opt:inline:** -Wopt -Werror package test object A { diff --git a/test/files/pos/inline-access-levels/Test_2.scala b/test/files/pos/inline-access-levels/Test_2.scala index a9aedd61e0b8..97937c80b43d 100644 --- a/test/files/pos/inline-access-levels/Test_2.scala +++ b/test/files/pos/inline-access-levels/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt -Werror +//> using options -opt:inline:** -Wopt -Werror package test object Test { diff --git a/test/files/pos/java-import-static-from-subclass/Test.scala b/test/files/pos/java-import-static-from-subclass/Test.scala index 7d2326b519e1..4b7e4a5d159e 100644 --- a/test/files/pos/java-import-static-from-subclass/Test.scala +++ b/test/files/pos/java-import-static-from-subclass/Test.scala @@ -1,2 +1,2 @@ -// scalac: -Ypickle-java +//> using options -Ypickle-java class Test diff --git a/test/files/pos/lazyref-autoapply.scala b/test/files/pos/lazyref-autoapply.scala index d255b95bfdc5..37642091d579 100644 --- a/test/files/pos/lazyref-autoapply.scala +++ b/test/files/pos/lazyref-autoapply.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xsource:3 -Xlint +//> using options -Werror -Xsource:3 -Xlint object Test { def doti(i: Int): Product = { diff --git a/test/files/pos/leading-infix-op.scala b/test/files/pos/leading-infix-op.scala index d812f4460f4e..2aead2c55541 100644 --- a/test/files/pos/leading-infix-op.scala +++ b/test/files/pos/leading-infix-op.scala @@ -1,5 +1,4 @@ - -// scalac: -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:leading-infix trait T { def f(x: Int): Boolean = diff --git a/test/files/pos/macro-annot-unused-param-b/Macros_1.scala b/test/files/pos/macro-annot-unused-param-b/Macros_1.scala new file mode 100644 index 000000000000..3ab8d0bc820c --- /dev/null +++ b/test/files/pos/macro-annot-unused-param-b/Macros_1.scala @@ -0,0 +1,22 @@ +//> using options -Ymacro-annotations +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context +import scala.annotation.StaticAnnotation + +object Macros { + def annotImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { + import c.universe._ + val classTree = annottees.head.tree + val objectTree = q""" + object X { + def f: Int => String = { x => "hello" } + } + """ + + c.Expr[Any](Block(List(classTree, objectTree), Literal(Constant(())))) + } +} + +class mymacro extends StaticAnnotation { + def macroTransform(annottees: Any*): Any = macro Macros.annotImpl +} diff --git a/test/files/pos/macro-annot-unused-param-b/Test_2.scala b/test/files/pos/macro-annot-unused-param-b/Test_2.scala new file mode 100644 index 000000000000..c2e959094c22 --- /dev/null +++ b/test/files/pos/macro-annot-unused-param-b/Test_2.scala @@ -0,0 +1,7 @@ +//> using options -Ymacro-annotations -Werror -Wmacros:before -Wunused:params +@mymacro +class X + +object Test { + println(X.f(123)) +} diff --git a/test/files/pos/macro-annot-unused-param/Macros_1.scala b/test/files/pos/macro-annot-unused-param/Macros_1.scala index 17d602216c23..3ab8d0bc820c 100644 --- a/test/files/pos/macro-annot-unused-param/Macros_1.scala +++ b/test/files/pos/macro-annot-unused-param/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations +//> using options -Ymacro-annotations import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context import scala.annotation.StaticAnnotation diff --git a/test/files/pos/macro-annot-unused-param/Test_2.scala b/test/files/pos/macro-annot-unused-param/Test_2.scala index 9f101f7491da..b6fe87874ef7 100644 --- a/test/files/pos/macro-annot-unused-param/Test_2.scala +++ b/test/files/pos/macro-annot-unused-param/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations -Wunused:params -Werror +//> using options -Ymacro-annotations -Werror -Wmacros:default -Wunused:params @mymacro class X diff --git a/test/files/pos/macro-annot/t12366.scala b/test/files/pos/macro-annot/t12366.scala index 9b75bb3c6d1f..885919ec411d 100644 --- a/test/files/pos/macro-annot/t12366.scala +++ b/test/files/pos/macro-annot/t12366.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations +//> using options -Ymacro-annotations object Test extends App { @deprecated diff --git a/test/files/pos/macro-bounds-check/MacroImpl_1.scala b/test/files/pos/macro-bounds-check/MacroImpl_1.scala index fc76a03ddf4c..b419dc9e01e3 100644 --- a/test/files/pos/macro-bounds-check/MacroImpl_1.scala +++ b/test/files/pos/macro-bounds-check/MacroImpl_1.scala @@ -28,6 +28,7 @@ class DerivationMacros(val c: whitebox.Context) { q""" { def e(a: $R): Object = a + println("encode hlist") Predef.??? } """ @@ -39,7 +40,7 @@ class DerivationMacros(val c: whitebox.Context) { q""" { def e(a: $R): Object = a - + println("encode coproduct") Predef.??? } """ diff --git a/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala index 204a41ca94b0..a32fc61e7311 100644 --- a/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala +++ b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings object Test1 { val `macro` = ??? } diff --git a/test/files/pos/multiLineOps.scala b/test/files/pos/multiLineOps.scala index f5717ebc3fb7..8b9da5484317 100644 --- a/test/files/pos/multiLineOps.scala +++ b/test/files/pos/multiLineOps.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xsource:3-cross +//> using options -Werror -Xsource:3 -Xsource-features:leading-infix class Channel { def ! (msg: String): Channel = this diff --git a/test/files/pos/native-warning.scala b/test/files/pos/native-warning.scala index 7f47e94604a9..73a22ceaecc7 100644 --- a/test/files/pos/native-warning.scala +++ b/test/files/pos/native-warning.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation class A { @native def setup(): Unit diff --git a/test/files/pos/nonlocal-unchecked.scala b/test/files/pos/nonlocal-unchecked.scala index 818517aea8d5..62487c47f419 100644 --- a/test/files/pos/nonlocal-unchecked.scala +++ b/test/files/pos/nonlocal-unchecked.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings class A { def f: Boolean = { val xs = Nil map (_ => return false) diff --git a/test/files/pos/nullary-override-3.scala b/test/files/pos/nullary-override-3.scala index 171ed5be8edc..2ab5e5ce86c1 100644 --- a/test/files/pos/nullary-override-3.scala +++ b/test/files/pos/nullary-override-3.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:nowarn -Xsource:3 +//> using options -Werror -Wunused:nowarn -Xsource:3 // class C extends java.lang.CharSequence { def charAt(x$1: Int): Char = ??? diff --git a/test/files/pos/open-infix-future.scala b/test/files/pos/open-infix-future.scala index 8fee778d40cb..7b09cb54cf83 100644 --- a/test/files/pos/open-infix-future.scala +++ b/test/files/pos/open-infix-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // open class A diff --git a/test/files/pos/package-ob-case/A_1.scala b/test/files/pos/package-ob-case/A_1.scala index 39f68eef9dbb..7101da2092ed 100644 --- a/test/files/pos/package-ob-case/A_1.scala +++ b/test/files/pos/package-ob-case/A_1.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings package foo { package object foo { case class X(z: Int) { } diff --git a/test/files/pos/package-ob-case/B_2.scala b/test/files/pos/package-ob-case/B_2.scala index 39f68eef9dbb..7101da2092ed 100644 --- a/test/files/pos/package-ob-case/B_2.scala +++ b/test/files/pos/package-ob-case/B_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings package foo { package object foo { case class X(z: Int) { } diff --git a/test/files/pos/package-object-deferred-load-bug/A_1.scala b/test/files/pos/package-object-deferred-load-bug/A_1.scala new file mode 100644 index 000000000000..2597aff42d23 --- /dev/null +++ b/test/files/pos/package-object-deferred-load-bug/A_1.scala @@ -0,0 +1,7 @@ +package p1 { + package x_01 { object zappo {}} + + package x_64 { + object zappo {} + } +} diff --git a/test/files/pos/package-object-deferred-load-bug/A_2.scala b/test/files/pos/package-object-deferred-load-bug/A_2.scala new file mode 100644 index 000000000000..f40038de1a6a --- /dev/null +++ b/test/files/pos/package-object-deferred-load-bug/A_2.scala @@ -0,0 +1,10 @@ +package p1 { + import x_64._ + package x_01 { + object blerg extends AnyRef {} + } + + package x_64 { + object blerg {} + } +} \ No newline at end of file diff --git a/test/files/pos/package-object-deferred-load-bug/B_2.scala b/test/files/pos/package-object-deferred-load-bug/B_2.scala new file mode 100644 index 000000000000..b39bbae9da72 --- /dev/null +++ b/test/files/pos/package-object-deferred-load-bug/B_2.scala @@ -0,0 +1,10 @@ +package p1 { + import x_64._ + package x_01 { + object `package` extends AnyRef { def m = "m "} + } + + package x_64 { + object `package` { def m = "m" } + } +} diff --git a/test/files/pos/parens-for-params-silent.scala b/test/files/pos/parens-for-params-silent.scala index 6eb07a5c3c8a..b0ee04fd6bd9 100644 --- a/test/files/pos/parens-for-params-silent.scala +++ b/test/files/pos/parens-for-params-silent.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wconf:msg=lambda-parens:s -Xsource:3 +//> using options -Werror -Wconf:msg=lambda-parens:s -Xsource:3 class C { def f = { diff --git a/test/files/pos/patmat-hk.scala b/test/files/pos/patmat-hk.scala index 95f08e018d25..5e150da4695f 100644 --- a/test/files/pos/patmat-hk.scala +++ b/test/files/pos/patmat-hk.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 case class Foo[F[_]]() case class APair[F[_], G[_], A](f: F[A], g: G[A]) diff --git a/test/files/pos/patmat-suppress.scala b/test/files/pos/patmat-suppress.scala index 1e408db0a423..e144193b1316 100644 --- a/test/files/pos/patmat-suppress.scala +++ b/test/files/pos/patmat-suppress.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xno-patmat-analysis +//> using options -Xfatal-warnings -Xno-patmat-analysis // // test that none of these warn due to -Xno-patmat-analysis // tests taken from test/files/neg/patmatexhaust.scala, test/files/neg/pat_unreachable.scala diff --git a/test/files/pos/patmat_list_rewrite.scala b/test/files/pos/patmat_list_rewrite.scala index abd20fb910ab..693cf0a30b77 100644 --- a/test/files/pos/patmat_list_rewrite.scala +++ b/test/files/pos/patmat_list_rewrite.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // class C { def m(xs: List[String]) = xs match { diff --git a/test/files/pos/polymorphic-case-class.scala b/test/files/pos/polymorphic-case-class.scala index a7e8eb8bb0fd..f133ae8a1bf5 100644 --- a/test/files/pos/polymorphic-case-class.scala +++ b/test/files/pos/polymorphic-case-class.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // no unchecked warnings case class Bippy[T, -U, +V](x: T, z: V) { } diff --git a/test/files/pos/rangepos-anonapply.scala b/test/files/pos/rangepos-anonapply.scala index 49e0e1f2ff9c..14dfe5ceae24 100644 --- a/test/files/pos/rangepos-anonapply.scala +++ b/test/files/pos/rangepos-anonapply.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// class Test { trait PropTraverser { def apply(x: Int): Unit = {} diff --git a/test/files/pos/rangepos-patmat.scala b/test/files/pos/rangepos-patmat.scala index 0c40266dab4e..64bbce5b344f 100644 --- a/test/files/pos/rangepos-patmat.scala +++ b/test/files/pos/rangepos-patmat.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// class Foo { def test: PartialFunction[Any, String] = { case _ => "ok" } } diff --git a/test/files/pos/rangepos.scala b/test/files/pos/rangepos.scala index fc511a2f205a..80c0d6d80eba 100644 --- a/test/files/pos/rangepos.scala +++ b/test/files/pos/rangepos.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// class Foo(val x: Double) extends AnyVal { } object Pretty { diff --git a/test/files/pos/setter-not-implicit.scala b/test/files/pos/setter-not-implicit.scala index 4836cf6304c8..4cb6b5cd88bd 100644 --- a/test/files/pos/setter-not-implicit.scala +++ b/test/files/pos/setter-not-implicit.scala @@ -1,5 +1,5 @@ -// scalac: -feature -Xfatal-warnings +//> using options -feature -Xfatal-warnings object O { implicit var x: Int = 0 } diff --git a/test/files/pos/skunky-expansion.scala b/test/files/pos/skunky-expansion.scala index d3f26c83a210..15f84bb9234b 100644 --- a/test/files/pos/skunky-expansion.scala +++ b/test/files/pos/skunky-expansion.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wnonunit-statement +//> using options -Werror -Wnonunit-statement // import scala.reflect.macros._ import scala.reflect.api.TypeCreator diff --git a/test/files/pos/skunky.scala b/test/files/pos/skunky.scala index 1c5f5730a0ab..98a8604b2f43 100644 --- a/test/files/pos/skunky.scala +++ b/test/files/pos/skunky.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wnonunit-statement +//> using options -Werror -Wnonunit-statement import scala.reflect.macros._ diff --git a/test/files/pos/t10093.scala b/test/files/pos/t10093.scala index 82e7f860cf39..1f5da004680b 100644 --- a/test/files/pos/t10093.scala +++ b/test/files/pos/t10093.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings class A[@specialized(Int) T](val value: T) { trait B def useValue(x:T): Unit = () diff --git a/test/files/pos/t10185.scala b/test/files/pos/t10185.scala index 36338d7576a0..5334a1c0177e 100644 --- a/test/files/pos/t10185.scala +++ b/test/files/pos/t10185.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // sealed trait Foo[A, F[_ <: A]] case class Bar[A, F[_ <: A]]() extends Foo[A, F] diff --git a/test/files/pos/t10195.scala b/test/files/pos/t10195.scala index 86fe175bdcc1..58e23de346c0 100644 --- a/test/files/pos/t10195.scala +++ b/test/files/pos/t10195.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // sealed trait Foo[F[_]] case class Bar[F[_]]() extends Foo[F] diff --git a/test/files/pos/t10195b.scala b/test/files/pos/t10195b.scala index 78272e523222..0bf710f97e49 100644 --- a/test/files/pos/t10195b.scala +++ b/test/files/pos/t10195b.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // sealed trait Foo[F[_]] case class Bar[F[_]]() extends Foo[F] diff --git a/test/files/pos/t10197.scala b/test/files/pos/t10197.scala index 8ccb8dc73529..6c69aa0d2405 100644 --- a/test/files/pos/t10197.scala +++ b/test/files/pos/t10197.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 import scala.language.higherKinds final case class Getter[S, A](get: S => A) diff --git a/test/files/pos/t10213.scala b/test/files/pos/t10213.scala index f5d76d1e6aad..44b1cf521049 100644 --- a/test/files/pos/t10213.scala +++ b/test/files/pos/t10213.scala @@ -1,6 +1,6 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 import scala.language.higherKinds final case class Coproduct[F[_], G[_], A](run: Either[F[A], G[A]]) diff --git a/test/files/pos/t10238.scala b/test/files/pos/t10238.scala index 6ae974052f58..bfb6f23044ad 100644 --- a/test/files/pos/t10238.scala +++ b/test/files/pos/t10238.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 object Test { diff --git a/test/files/pos/t10270/Main_2.scala b/test/files/pos/t10270/Main_2.scala index 58d21e8e0c00..a0b7c5aff01a 100644 --- a/test/files/pos/t10270/Main_2.scala +++ b/test/files/pos/t10270/Main_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Ywarn-unused:imports +//> using options -Xfatal-warnings -Ywarn-unused:imports object Main extends App { diff --git a/test/files/pos/t10288.scala b/test/files/pos/t10288.scala index 59d8d96cf092..4b2b32bbb281 100644 --- a/test/files/pos/t10288.scala +++ b/test/files/pos/t10288.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 trait Target trait Unrelated diff --git a/test/files/pos/t10296-before/Unused_2.scala b/test/files/pos/t10296-before/Unused_2.scala index cdde22bb0d1f..5d00b5ba284e 100644 --- a/test/files/pos/t10296-before/Unused_2.scala +++ b/test/files/pos/t10296-before/Unused_2.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings -Xlint:unused -Ywarn-macros:before +//> using options -Xfatal-warnings -Xlint:unused -Ywarn-macros:before // import scala.language.experimental.macros diff --git a/test/files/pos/t10296/Unused_2.scala b/test/files/pos/t10296/Unused_2.scala index 7f1e2ec869a2..adca67fbf0bf 100644 --- a/test/files/pos/t10296/Unused_2.scala +++ b/test/files/pos/t10296/Unused_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:unused +//> using options -Xfatal-warnings -Xlint:unused import scala.language.experimental.macros diff --git a/test/files/pos/t10372.scala b/test/files/pos/t10372.scala index 79003178775b..1a22e89c8d76 100644 --- a/test/files/pos/t10372.scala +++ b/test/files/pos/t10372.scala @@ -1,5 +1,5 @@ // -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // import scala.language.higherKinds import scala.language.implicitConversions diff --git a/test/files/pos/t10373.scala b/test/files/pos/t10373.scala index f1c62ec0726b..f913cfe64fb7 100644 --- a/test/files/pos/t10373.scala +++ b/test/files/pos/t10373.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed abstract class Foo { def bar(): Unit = this match { case Foo_1() => //do something diff --git a/test/files/pos/t10394.scala b/test/files/pos/t10394.scala index 3698595a681f..51ce1062b8bf 100644 --- a/test/files/pos/t10394.scala +++ b/test/files/pos/t10394.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings -Ywarn-unused:patvars +//> using options -Xfatal-warnings -Ywarn-unused:patvars trait T { def f = for (i: Int <- List(42)) yield i } diff --git a/test/files/pos/t10502.scala b/test/files/pos/t10502.scala index 38cd733e646a..0222e731211f 100644 --- a/test/files/pos/t10502.scala +++ b/test/files/pos/t10502.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings final class Box[A](val unwrap: A) diff --git a/test/files/pos/t10532/C.java b/test/files/pos/t10532/C.java new file mode 100644 index 000000000000..515d8bae362c --- /dev/null +++ b/test/files/pos/t10532/C.java @@ -0,0 +1,11 @@ + +public class C { + public long f(long x, Long y) { return x + y; } + public long f(Long x, Long y) { return x + y; } + + public long g(long x, String y) { return x + Long.parseLong(y); } + public long g(Long x, String y) { return x + Long.parseLong(y); } + + public long h(long x) { return x + 1; } + public long h(Long x) { return x + 1; } +} diff --git a/test/files/pos/t10532/D.scala b/test/files/pos/t10532/D.scala new file mode 100644 index 000000000000..6d2157f0b44a --- /dev/null +++ b/test/files/pos/t10532/D.scala @@ -0,0 +1,7 @@ + +import java.lang.{Long => JLong} + +class D { + def f(x: Long, y: JLong): Long = x + y + def f(x: JLong, y: JLong): Long = x + y +} diff --git a/test/files/pos/t10532/test.scala b/test/files/pos/t10532/test.scala new file mode 100644 index 000000000000..bb6602eabca5 --- /dev/null +++ b/test/files/pos/t10532/test.scala @@ -0,0 +1,17 @@ + +object Test extends App { + val c = new C + val d = new D + + println(c.f(42, 42)) + println(c.f(42L, 42L)) + + println(c.g(42, "42")) + println(c.g(42L, "42")) + + println(c.h(42)) + println(c.h(42L)) + + println(d.f(42, 42)) + println(d.f(42L, 42L)) +} diff --git a/test/files/pos/t10561.scala b/test/files/pos/t10561.scala new file mode 100644 index 000000000000..a159d24b54c7 --- /dev/null +++ b/test/files/pos/t10561.scala @@ -0,0 +1,12 @@ + +class Parent { + private val field: Int = 3 +} + +class Child(n: Int) extends { + private val field = n +} with Parent { + class Inner { + def f = field + } +} diff --git a/test/files/pos/t10589-case-implicit-param/cc_2.scala b/test/files/pos/t10589-case-implicit-param/cc_2.scala index 17a1dce15ca9..48281f051bac 100644 --- a/test/files/pos/t10589-case-implicit-param/cc_2.scala +++ b/test/files/pos/t10589-case-implicit-param/cc_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations +//> using options -Ymacro-annotations trait T[A] @macid diff --git a/test/files/pos/t10589-case-implicit-param/macros_1.scala b/test/files/pos/t10589-case-implicit-param/macros_1.scala index 700c925d879c..d3eeb8bf05ce 100644 --- a/test/files/pos/t10589-case-implicit-param/macros_1.scala +++ b/test/files/pos/t10589-case-implicit-param/macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-annotations +//> using options -Ymacro-annotations import scala.annotation.StaticAnnotation import scala.language.experimental.macros diff --git a/test/files/pos/t10623.scala b/test/files/pos/t10623.scala index d48273914f76..93cc77a4abd9 100644 --- a/test/files/pos/t10623.scala +++ b/test/files/pos/t10623.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings -Xlint:unused +//> using options -Xfatal-warnings -Xlint:unused // object `package` { diff --git a/test/files/pos/t10643.scala b/test/files/pos/t10643.scala index 99c4cf4c9302..4636f064cb31 100644 --- a/test/files/pos/t10643.scala +++ b/test/files/pos/t10643.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// trait AA trait BB diff --git a/test/files/pos/t10644/Objs_1.scala b/test/files/pos/t10644/Objs_1.scala index 804cfa435c18..7f8649e5599f 100644 --- a/test/files/pos/t10644/Objs_1.scala +++ b/test/files/pos/t10644/Objs_1.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings case object A ; case object B object C { // inferred refinement type `Product with Serializable` of val `objs` has owner `C` diff --git a/test/files/pos/t10644/Test_2.scala b/test/files/pos/t10644/Test_2.scala index 029cee6ad301..0e5ba627e2ea 100644 --- a/test/files/pos/t10644/Test_2.scala +++ b/test/files/pos/t10644/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings object Test { // Should not result in the spurious warning: // comparing non-null values of types Product with Serializable diff --git a/test/files/pos/t10680.scala b/test/files/pos/t10680.scala index 7a2c64bfb0e1..d1ee3b3a5459 100644 --- a/test/files/pos/t10680.scala +++ b/test/files/pos/t10680.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings object MyEnum extends Enumeration { val e1 = Value("e1") val e2 = Value("e2") diff --git a/test/files/pos/t10763.scala b/test/files/pos/t10763.scala index a18f9cd8ccfc..f4c0bbbf3c25 100644 --- a/test/files/pos/t10763.scala +++ b/test/files/pos/t10763.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Wunused +//> using options -Werror -Wunused class Test { def xsUnused = { diff --git a/test/files/pos/t11303.scala b/test/files/pos/t11303.scala index d094bf900048..2998610eaab8 100644 --- a/test/files/pos/t11303.scala +++ b/test/files/pos/t11303.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { sealed trait Gadt[F[_], O, R] diff --git a/test/files/pos/t11525.scala b/test/files/pos/t11525.scala index cc8727281810..94f63b23e1e5 100644 --- a/test/files/pos/t11525.scala +++ b/test/files/pos/t11525.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:refchecks -Ydebug -uniqid +//> using options -Ystop-after:refchecks -Ydebug -uniqid package java.lang /* This is a pretty random test that very indirectly tests `unique`ing of `ObjectTpeJavaRef` diff --git a/test/files/pos/t11534.scala b/test/files/pos/t11534.scala index bab4bd956d87..dd3808195b75 100644 --- a/test/files/pos/t11534.scala +++ b/test/files/pos/t11534.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test1 { val g: scala.tools.nsc.Global = ??? import g._ diff --git a/test/files/pos/t11538.scala b/test/files/pos/t11538.scala index 13101365d02d..0c02d81241b7 100644 --- a/test/files/pos/t11538.scala +++ b/test/files/pos/t11538.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -deprecation -stop:refchecks +//> using options -Werror -deprecation -stop:refchecks package t11538 @deprecated("not for you", since = "just now") diff --git a/test/files/pos/t11558.scala b/test/files/pos/t11558.scala index 9a734206cb69..5882952ab2c6 100644 --- a/test/files/pos/t11558.scala +++ b/test/files/pos/t11558.scala @@ -3,3 +3,11 @@ class Test { trait S[T] { def map[R](f: F1[_ >: T, _ <: R]): S[R] } (??? : S[Int]).map(_.toString) // check that map's type param is inferred (should be String) } + +object Test_9244 { + trait F1[T1, R] { def apply(a1: T1): R } + + def cycle[T](function: F1[? >: T, ? <: T]): Unit = ??? + + def t9244 = cycle((_: String) => "") +} diff --git a/test/files/pos/t11603.scala b/test/files/pos/t11603.scala index 01a59a532bac..8d943b1ae6fc 100644 --- a/test/files/pos/t11603.scala +++ b/test/files/pos/t11603.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class C { def m(x: true) = x match { case true => println("the one true path") diff --git a/test/files/pos/t11663/B_2.scala b/test/files/pos/t11663/B_2.scala index 6426225f7a85..5c2513618f28 100644 --- a/test/files/pos/t11663/B_2.scala +++ b/test/files/pos/t11663/B_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt:_ +//> using options -opt:inline:** -Wopt:_ class B { def bar(c: A) = c.m } diff --git a/test/files/pos/t11681.scala b/test/files/pos/t11681.scala index 0976e86fd7b1..68638b12e4ad 100644 --- a/test/files/pos/t11681.scala +++ b/test/files/pos/t11681.scala @@ -1,5 +1,5 @@ // -// scalac: -Wunused:privates -Werror +//> using options -Wunused:privates -Werror // package com diff --git a/test/files/pos/t11788/Bar.scala b/test/files/pos/t11788/Bar.scala new file mode 100644 index 000000000000..01c1838abe21 --- /dev/null +++ b/test/files/pos/t11788/Bar.scala @@ -0,0 +1,3 @@ +object Bar extends App { + println(new Foo().test()) +} diff --git a/test/files/pos/t11788/Foo.java b/test/files/pos/t11788/Foo.java new file mode 100644 index 000000000000..802929d7fc92 --- /dev/null +++ b/test/files/pos/t11788/Foo.java @@ -0,0 +1,7 @@ +public class Foo { + private String java; + + public java.lang.Integer test() { + return Integer.valueOf(42); + } +} diff --git a/test/files/pos/t11813.scala b/test/files/pos/t11813.scala index 0e827625c690..accc6b4e2377 100644 --- a/test/files/pos/t11813.scala +++ b/test/files/pos/t11813.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:implicit-recursion +//> using options -Werror -Xlint:implicit-recursion // package warner diff --git a/test/files/pos/t11856.scala b/test/files/pos/t11856.scala index 6c8b500c7245..69831172dc1d 100644 --- a/test/files/pos/t11856.scala +++ b/test/files/pos/t11856.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:params +//> using options -Werror -Wunused:params class C { def answer: 42 = 42 diff --git a/test/files/pos/t11895.scala b/test/files/pos/t11895.scala index 98230bc5797b..3f58faf1b246 100644 --- a/test/files/pos/t11895.scala +++ b/test/files/pos/t11895.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -deprecation +//> using options -Werror -deprecation // trait Bar { trait Foo diff --git a/test/files/pos/t11908/C.scala b/test/files/pos/t11908/C.scala index 615277efc50b..b443d18fe3fb 100644 --- a/test/files/pos/t11908/C.scala +++ b/test/files/pos/t11908/C.scala @@ -1,6 +1,10 @@ -// javaVersion: 16+ +//> using jvm 16+ object C { + def useR0: Unit = { + val r0 = new R0 + } + def useR1 = { // constructor signature val r1 = new R1(123, "hello") @@ -8,6 +12,7 @@ object C { // accessors signature val i: Int = r1.i val s: String = r1.s + val j: Int = r1.i() // method val s2: String = r1.someMethod() @@ -46,10 +51,21 @@ object C { val l: Long = r3.l val s: String = r3.s + locally { + val i: Int = r3.i() + val l: Long = r3.l() + val s: String = r3.s() + } + // method val l2: Long = r3.l(43L, 44L) // supertype val isRecord: java.lang.Record = r3 } + + def useR4: Unit = { + val r4 = new R4(42) + val n: Int = r4.t + } } diff --git a/test/files/pos/t11908/IntLike.scala b/test/files/pos/t11908/IntLike.scala index 9e45fd43bc98..e1172f12d964 100644 --- a/test/files/pos/t11908/IntLike.scala +++ b/test/files/pos/t11908/IntLike.scala @@ -1,4 +1,4 @@ -// javaVersion: 16+ +//> using jvm 16+ trait IntLike { def getInt: Int } diff --git a/test/files/pos/t11908/R1.java b/test/files/pos/t11908/R1.java index 350ac64b987e..8880f0bc1cff 100644 --- a/test/files/pos/t11908/R1.java +++ b/test/files/pos/t11908/R1.java @@ -5,3 +5,7 @@ public String someMethod() { return s + "!"; } } + +record R0() {} + +record R4(T t) {} diff --git a/test/files/pos/t11908b/C_2.scala b/test/files/pos/t11908b/C_2.scala new file mode 100644 index 000000000000..b443d18fe3fb --- /dev/null +++ b/test/files/pos/t11908b/C_2.scala @@ -0,0 +1,71 @@ +//> using jvm 16+ +object C { + + def useR0: Unit = { + val r0 = new R0 + } + + def useR1 = { + // constructor signature + val r1 = new R1(123, "hello") + + // accessors signature + val i: Int = r1.i + val s: String = r1.s + val j: Int = r1.i() + + // method + val s2: String = r1.someMethod() + + // supertype + val isRecord: java.lang.Record = r1 + + () + } + + def useR2 = { + // constructor signature + val r2 = new R2.R(123, "hello") + + // accessors signature + val i: Int = r2.i + val s: String = r2.s + + // method + val i2: Int = r2.getInt + + // supertype + val isIntLike: IntLike = r2 + val isRecord: java.lang.Record = r2 + + () + } + + def useR3 = { + // constructor signature + val r3 = new R3(123, 42L, "hi") + new R3("hi", 123) + + // accessors signature + val i: Int = r3.i + val l: Long = r3.l + val s: String = r3.s + + locally { + val i: Int = r3.i() + val l: Long = r3.l() + val s: String = r3.s() + } + + // method + val l2: Long = r3.l(43L, 44L) + + // supertype + val isRecord: java.lang.Record = r3 + } + + def useR4: Unit = { + val r4 = new R4(42) + val n: Int = r4.t + } +} diff --git a/test/files/pos/t11908b/IntLike.scala b/test/files/pos/t11908b/IntLike.scala new file mode 100644 index 000000000000..e1172f12d964 --- /dev/null +++ b/test/files/pos/t11908b/IntLike.scala @@ -0,0 +1,4 @@ +//> using jvm 16+ +trait IntLike { + def getInt: Int +} diff --git a/test/files/pos/t11908b/R1.java b/test/files/pos/t11908b/R1.java new file mode 100644 index 000000000000..8880f0bc1cff --- /dev/null +++ b/test/files/pos/t11908b/R1.java @@ -0,0 +1,11 @@ +// javaVersion: 16+ +record R1(int i, String s) { + + public String someMethod() { + return s + "!"; + } +} + +record R0() {} + +record R4(T t) {} diff --git a/test/files/pos/t11908b/R2.java b/test/files/pos/t11908b/R2.java new file mode 100644 index 000000000000..62bf5ff6c22c --- /dev/null +++ b/test/files/pos/t11908b/R2.java @@ -0,0 +1,14 @@ +// javaVersion: 16+ +public class R2 { + final record R(int i, String s) implements IntLike { + public int getInt() { + return i; + } + + // Canonical constructor + public R(int i, java.lang.String s) { + this.i = i; + this.s = s.intern(); + } + } +} diff --git a/test/files/pos/t11908b/R3.java b/test/files/pos/t11908b/R3.java new file mode 100644 index 000000000000..03a06dfc6f37 --- /dev/null +++ b/test/files/pos/t11908b/R3.java @@ -0,0 +1,23 @@ +// javaVersion: 16+ +public record R3(int i, long l, String s) { + + // User-specified accessor + public int i() { + return i + 1; // evil >:) + } + + // Not an accessor - too many parameters + public long l(long a1, long a2) { + return a1 + a2; + } + + // Secondary constructor + public R3(String s, int i) { + this(i, 42L, s); + } + + // Compact constructor + public R3 { + s = s.intern(); + } +} diff --git a/test/files/pos/t11917/Z.scala b/test/files/pos/t11917/Z.scala index c2ca34faf005..13b19b20ec8e 100644 --- a/test/files/pos/t11917/Z.scala +++ b/test/files/pos/t11917/Z.scala @@ -1,4 +1,4 @@ -// scalac: -Ypickle-java +//> using options -Ypickle-java package bar diff --git a/test/files/pos/t11921b.scala b/test/files/pos/t11921b.scala index 38870f0cb53b..420b4c4d2f14 100644 --- a/test/files/pos/t11921b.scala +++ b/test/files/pos/t11921b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wconf:msg=legacy-binding:s -Xsource:3 +//> using options -Werror -Wconf:msg=legacy-binding:s -Xsource:3 object test1 { @@ -18,7 +18,7 @@ object test1 { } object test2 { - def c(y: Float) = { + def c(y: Float): AnyRef { val y: Int } = { class D { val y = 2 } diff --git a/test/files/pos/t11921c.scala b/test/files/pos/t11921c.scala index d78439424f4e..d10aa603669a 100644 --- a/test/files/pos/t11921c.scala +++ b/test/files/pos/t11921c.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // test/scaladoc/resources/t5784.scala diff --git a/test/files/pos/t11952.scala b/test/files/pos/t11952.scala index 6b93cfb6f1e8..5da46f3e6c2b 100644 --- a/test/files/pos/t11952.scala +++ b/test/files/pos/t11952.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint -nowarn +//> using options -Werror -Xlint -nowarn // // nowarn should mean no warnings are emitted, // irrespective of other flags, and also no diff --git a/test/files/pos/t11964.scala b/test/files/pos/t11964.scala index 4f0bd8f73726..86b51f6ae33a 100644 --- a/test/files/pos/t11964.scala +++ b/test/files/pos/t11964.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint object Hmm { def zxc(b: Int*)(implicit x: Int = 3) = "" + b + x diff --git a/test/files/pos/t11966.scala b/test/files/pos/t11966.scala index b662e71322da..4802c8c602cf 100644 --- a/test/files/pos/t11966.scala +++ b/test/files/pos/t11966.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -deprecation +//> using options -Werror -deprecation // object Test { val original = """\/ \/ /\""" diff --git a/test/files/pos/t12006.scala b/test/files/pos/t12006.scala index a4abecfaf62f..013ba24a3e2f 100644 --- a/test/files/pos/t12006.scala +++ b/test/files/pos/t12006.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // see https://github.com/scala/bug/issues/12006 // java.io.InputStream looks like a SAM (read method), diff --git a/test/files/pos/t12127.scala b/test/files/pos/t12127.scala new file mode 100644 index 000000000000..c600d254ad5c --- /dev/null +++ b/test/files/pos/t12127.scala @@ -0,0 +1,10 @@ + +//> using options -Werror -Wunused + +class C { + def f(x: Any): "hi" = x match { case s @ "hi" => s } // was: Error while emitting (in backend) + def g(x: Any): String = x match { case s @ "hi" => s } + def h(x: Any): String = x match { case s: String => s } + + def check(x: Any): "bi" = x match { case s @ "hi" => "bi" } +} diff --git a/test/files/pos/t12159/s.scala b/test/files/pos/t12159/s.scala index 29eb9518ea6c..1cfc877e074b 100644 --- a/test/files/pos/t12159/s.scala +++ b/test/files/pos/t12159/s.scala @@ -1,4 +1,4 @@ -// javaVersion: 17+ +//> using jvm 17+ package p diff --git a/test/files/pos/t12159b/s_2.scala b/test/files/pos/t12159b/s_2.scala index 881204f4d830..07a865b66c93 100644 --- a/test/files/pos/t12159b/s_2.scala +++ b/test/files/pos/t12159b/s_2.scala @@ -1,5 +1,5 @@ -// javaVersion: 17+ -// scalac: -Werror +//> using jvm 17+ +//> using options -Werror package p class C { diff --git a/test/files/pos/t12186.scala b/test/files/pos/t12186.scala index b8a72238510f..a1ca8e05dc68 100644 --- a/test/files/pos/t12186.scala +++ b/test/files/pos/t12186.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // this is remodeling of the scala package object and scala.collection.immutable.{ List, ::, Nil } // in order to: diff --git a/test/files/pos/t12225.scala b/test/files/pos/t12225.scala index baae67d36bf8..76a8b9a2ffb4 100644 --- a/test/files/pos/t12225.scala +++ b/test/files/pos/t12225.scala @@ -1,4 +1,4 @@ -// scalac: -Ydebug +//> using options -Ydebug object Test { def foo(arr: Array[Int]): Unit = { val Array(x, y) = arr diff --git a/test/files/pos/t12240.scala b/test/files/pos/t12240.scala index a04ef0e734cf..7f34ab67408d 100644 --- a/test/files/pos/t12240.scala +++ b/test/files/pos/t12240.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +//> using options -Xfatal-warnings -Xlint:strict-unsealed-patmat // object Test { diff --git a/test/files/pos/t12249/A.scala b/test/files/pos/t12249/A.scala new file mode 100644 index 000000000000..dd3901812050 --- /dev/null +++ b/test/files/pos/t12249/A.scala @@ -0,0 +1,4 @@ +package mixintest.a +abstract class A { + protected val x: Int +} \ No newline at end of file diff --git a/test/files/pos/t12249/B.scala b/test/files/pos/t12249/B.scala new file mode 100644 index 000000000000..554d2c88cd9f --- /dev/null +++ b/test/files/pos/t12249/B.scala @@ -0,0 +1,5 @@ +package mixintest.b +import mixintest.a.A +trait B extends A { + println(x) +} \ No newline at end of file diff --git a/test/files/pos/t12249/C.scala b/test/files/pos/t12249/C.scala new file mode 100644 index 000000000000..2ebc19bec65a --- /dev/null +++ b/test/files/pos/t12249/C.scala @@ -0,0 +1,4 @@ +package mixintest.c +import mixintest.a.A +import mixintest.b.B +case class C(override protected val x: Int) extends A with B \ No newline at end of file diff --git a/test/files/pos/t12250.scala b/test/files/pos/t12250.scala index ec5be8411860..38add8ba16d6 100644 --- a/test/files/pos/t12250.scala +++ b/test/files/pos/t12250.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror final case class Foo(value: String) object Foo { diff --git a/test/files/pos/t12250b.scala b/test/files/pos/t12250b.scala index b47977512fd7..cf84e9bea5a6 100644 --- a/test/files/pos/t12250b.scala +++ b/test/files/pos/t12250b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed case class Sub1(str: String) final case class Sup1(str: String) extends Sup0 diff --git a/test/files/pos/t12254.scala b/test/files/pos/t12254.scala index a44393063d60..e9d5c084164c 100644 --- a/test/files/pos/t12254.scala +++ b/test/files/pos/t12254.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint:strict-unsealed-patmat +//> using options -Xfatal-warnings -Xlint:strict-unsealed-patmat // object Test { diff --git a/test/files/pos/t12277.scala b/test/files/pos/t12277.scala index 6ec5050c9a1d..8737de45ad7e 100644 --- a/test/files/pos/t12277.scala +++ b/test/files/pos/t12277.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:strict-unsealed-patmat -Werror +//> using options -Xlint:strict-unsealed-patmat -Werror sealed trait A final case class B() extends A final case class C() extends A diff --git a/test/files/pos/t12304.scala b/test/files/pos/t12304.scala index 3b84224dd3ab..28160f2e7501 100644 --- a/test/files/pos/t12304.scala +++ b/test/files/pos/t12304.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class Foo class Test { diff --git a/test/files/pos/t12326.scala b/test/files/pos/t12326.scala index 7a8eac907c32..464a63590de0 100644 --- a/test/files/pos/t12326.scala +++ b/test/files/pos/t12326.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports -Wconf:origin=scala.collection.mutable._:s,origin=scala.concurrent.ExecutionContext.Implicits._:s +//> using options -Werror -Wunused:imports -Wconf:origin=scala.collection.mutable._:s,origin=scala.concurrent.ExecutionContext.Implicits._:s import scala.collection.mutable._ diff --git a/test/files/pos/t12326b.scala b/test/files/pos/t12326b.scala index 93dfec40fdf3..1b6049edad3b 100644 --- a/test/files/pos/t12326b.scala +++ b/test/files/pos/t12326b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:imports +//> using options -Werror -Wunused:imports import annotation._ diff --git a/test/files/pos/t12392.scala b/test/files/pos/t12392.scala index 056fd1ae2d17..339c8898c0ea 100644 --- a/test/files/pos/t12392.scala +++ b/test/files/pos/t12392.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import scala.reflect.api.Universe object Test { diff --git a/test/files/pos/t12393/R1.java b/test/files/pos/t12393/R1.java index 08c764ceb4ba..a4fd067f2bbe 100644 --- a/test/files/pos/t12393/R1.java +++ b/test/files/pos/t12393/R1.java @@ -1,4 +1,4 @@ -// javaVersion: 9+ +//> using jvm 9+ public interface R1 { private void foo() { diff --git a/test/files/pos/t12396/B_2.scala b/test/files/pos/t12396/B_2.scala index b61d88c9f292..7ef4203e8787 100644 --- a/test/files/pos/t12396/B_2.scala +++ b/test/files/pos/t12396/B_2.scala @@ -1,4 +1,4 @@ -// javaVersion: 21+ +//> using jvm 21+ class B { def bar = (new A_1).f(null) diff --git a/test/files/pos/t12398.scala b/test/files/pos/t12398.scala index ebd6bda4cf8e..2d2708d46cd7 100644 --- a/test/files/pos/t12398.scala +++ b/test/files/pos/t12398.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import scala.reflect.api.Universe object Test { diff --git a/test/files/pos/t12398b.scala b/test/files/pos/t12398b.scala index 9337a6e8e0fd..546992be6d82 100644 --- a/test/files/pos/t12398b.scala +++ b/test/files/pos/t12398b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import scala.reflect.api.Universe object Test { diff --git a/test/files/pos/t12474/s.scala b/test/files/pos/t12474/s.scala index 2f4e4ed3a9ad..53da15f42147 100644 --- a/test/files/pos/t12474/s.scala +++ b/test/files/pos/t12474/s.scala @@ -1,4 +1,4 @@ -// javaVersion: 17+ +//> using jvm 17+ class S { def j: Nat = new Nat.Zero diff --git a/test/files/pos/t12538.scala b/test/files/pos/t12538.scala index 58a4a30597d5..18a4c6a5164d 100644 --- a/test/files/pos/t12538.scala +++ b/test/files/pos/t12538.scala @@ -1,5 +1,5 @@ -// javaVersion: 17+ +//> using jvm 17+ class C { @java.lang.Deprecated(since = s"test") var i = 4 diff --git a/test/files/pos/t12554.scala b/test/files/pos/t12554.scala index ea5880d6779d..c18b46f6261d 100644 --- a/test/files/pos/t12554.scala +++ b/test/files/pos/t12554.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:java.lang,scala,scala.Predef,scala.util.chaining +//> using options -Yimports:java.lang,scala,scala.Predef,scala.util.chaining class C { def f = 42.tap(println) diff --git a/test/files/pos/t12554b/s_2.scala b/test/files/pos/t12554b/s_2.scala index c4338906d2e4..653d0442ccd8 100644 --- a/test/files/pos/t12554b/s_2.scala +++ b/test/files/pos/t12554b/s_2.scala @@ -1,5 +1,5 @@ -// scalac: -Yimports:java.lang,scala,scala.Predef,p,q,r.Z +//> using options -Yimports:java.lang,scala,scala.Predef,p,q,r.Z object Test extends App { println(X) diff --git a/test/files/pos/t12600.scala b/test/files/pos/t12600.scala index fc86c2a9fc28..41e9b33e8620 100644 --- a/test/files/pos/t12600.scala +++ b/test/files/pos/t12600.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused:_ +//> using options -Werror -Wunused:_ class Private { private type Curry[A] = { type T[B] = Either[A, B] } def m2[T[A]]: Unit = () diff --git a/test/files/pos/t12645/Macro_1.scala b/test/files/pos/t12645/Macro_1.scala index 827ba992fe77..870c84ef1549 100644 --- a/test/files/pos/t12645/Macro_1.scala +++ b/test/files/pos/t12645/Macro_1.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import language.experimental.macros import scala.reflect.macros.whitebox.Context diff --git a/test/files/pos/t12645/Test_2.scala b/test/files/pos/t12645/Test_2.scala index 520bd7de7dd6..ab71fab4b2b6 100644 --- a/test/files/pos/t12645/Test_2.scala +++ b/test/files/pos/t12645/Test_2.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 object Test extends App { def f(s: String) = println(s) diff --git a/test/files/pos/t12645b/Test_2.scala b/test/files/pos/t12645b/Test_2.scala index eb9942baf848..8b5fa24c10c4 100644 --- a/test/files/pos/t12645b/Test_2.scala +++ b/test/files/pos/t12645b/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 object Test extends App { Foo.ctx.quote(42).ast.id diff --git a/test/files/pos/t12645b/macro_1.scala b/test/files/pos/t12645b/macro_1.scala index 732ae1fd7d20..888390bf8831 100644 --- a/test/files/pos/t12645b/macro_1.scala +++ b/test/files/pos/t12645b/macro_1.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import scala.language.experimental.macros import scala.reflect.macros.whitebox.Context diff --git a/test/files/pos/t12646.scala b/test/files/pos/t12646.scala index 72118974d5fb..b0e3f66f5b9a 100644 --- a/test/files/pos/t12646.scala +++ b/test/files/pos/t12646.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Wunused:params +//> using options -Werror -Wunused:params trait T { private var x: String = _ diff --git a/test/files/pos/t12647/Macro_1.scala b/test/files/pos/t12647/Macro_1.scala index a808e46089a3..cbec50a79d11 100644 --- a/test/files/pos/t12647/Macro_1.scala +++ b/test/files/pos/t12647/Macro_1.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import scala.reflect.macros.whitebox.Context diff --git a/test/files/pos/t12647/Resolve_2.scala b/test/files/pos/t12647/Resolve_2.scala index dab65c6a310b..c9f54c1040c2 100644 --- a/test/files/pos/t12647/Resolve_2.scala +++ b/test/files/pos/t12647/Resolve_2.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import language.experimental.macros @@ -8,6 +8,6 @@ trait Resolver { } class ValueResolver extends Resolver { - override def resolve = valueResult + override def resolve: Result { def value: String } = valueResult def valueResult: Result = macro Macros.impl } diff --git a/test/files/pos/t12647/Test_3.scala b/test/files/pos/t12647/Test_3.scala index 152e5ddc4aa4..e2fc19f46853 100644 --- a/test/files/pos/t12647/Test_3.scala +++ b/test/files/pos/t12647/Test_3.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 object Test extends App { val resolver = new ValueResolver diff --git a/test/files/pos/t12664.scala b/test/files/pos/t12664.scala new file mode 100644 index 000000000000..aadbae96156e --- /dev/null +++ b/test/files/pos/t12664.scala @@ -0,0 +1,38 @@ +//> using options -nowarn -Wconf:cat=lint-missing-interpolator:ws -Werror -Xlint -Xsource:3 + +/* +-nowarn and -Xlint are in contradiction. Which wins? +-nowarn is recognized by per-run reporting and by sink reporter (e.g., ConsoleReporter). +For per-run reporting, -nowarn means default wconf for deprecation must not be ws (summary, which would warn). +Instead, it is w or s depending on whether -deprecation is requested. +So from the perspective of per-run reporting, -deprecation means issue a diagnostic even if -nowarn. + +For the sink reporter, too, -nowarn means "don't summarize with warning count". +In addition, -nowarn means -maxwarns:0, so any warning is filtered by FilteringReporter. +(Normally, displayed warnings is capped by -maxwarns and then summarized as a count when done.) +So from the perspective of the sink reporter, -nowarn means filter out warnings and don't print count of warnings. +It doesn't consider -deprecation at all. +In addition, -nowarn subverts -Werror. + +In the test example, there are 2 lints, a non-lint, and a migration warning. +The wconf boosts a lint to ws summary, but -nowarn tells the sink not to print either a warning or a count. +Migration is boosted to e by default, but -nowarn says don't boost migration warnings. +A user-supplied wconf could boost migration despite -nowarn. +Other warnings are silenced by any:s installed by -nowarn. +*/ +trait T { + def g[A]: Option[A] +} + +class C extends T { + def f: Unit = 42 // suppressed other warning for expr, lint for parens + + override def g[A] = None // suppressed migration warning, not boosted to error under --no-warnings + + def oops = "$f" // summarized lint + + @deprecated("old stuff", since="1.0") + def old = 17 + + def stale = old +} diff --git a/test/files/pos/t12671.scala b/test/files/pos/t12671.scala index 9db7ec760751..65dfa3dcc7ec 100644 --- a/test/files/pos/t12671.scala +++ b/test/files/pos/t12671.scala @@ -1,5 +1,5 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 import scala.collection.{mutable, IterableOnce} import scala.collection.immutable.{AbstractSet, Set, SetOps} diff --git a/test/files/pos/t12712.scala b/test/files/pos/t12712.scala index 195743b46770..59d8f4504819 100644 --- a/test/files/pos/t12712.scala +++ b/test/files/pos/t12712.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object T { private sealed trait T private object O extends T diff --git a/test/files/pos/t12787.scala b/test/files/pos/t12787.scala index e32f880264c4..3d1f1be6fea4 100644 --- a/test/files/pos/t12787.scala +++ b/test/files/pos/t12787.scala @@ -1,5 +1,5 @@ -// scalac: -opt:inline: -Wopt -Werror +//> using options -opt:inline: -Wopt -Werror // skalac: -opt:inline: -Vopt:C -Wopt -Werror // > using scala 2.13.nightly diff --git a/test/files/pos/t12792.scala b/test/files/pos/t12792.scala index 120c68623635..6a6855325700 100644 --- a/test/files/pos/t12792.scala +++ b/test/files/pos/t12792.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint import annotation._ diff --git a/test/files/pos/t12800/matcher_1.scala b/test/files/pos/t12800/matcher_1.scala index e305f9717a6f..52912d2a97fa 100644 --- a/test/files/pos/t12800/matcher_1.scala +++ b/test/files/pos/t12800/matcher_1.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xsource:3 +//> using options -Werror -Xsource:3 import JetBrains.* diff --git a/test/files/pos/t12812.scala b/test/files/pos/t12812.scala index 79c35540b26e..e4b84fe79fbd 100644 --- a/test/files/pos/t12812.scala +++ b/test/files/pos/t12812.scala @@ -1,5 +1,5 @@ -// scalac: -Werror -Xsource:3 -language:postfixOps -Xlint +//> using options -Werror -Xsource:3 -language:postfixOps -Xlint class C { def foo(max: Int) = (1 to max).map(1 to).foreach(r => println(r.mkString(","))) diff --git a/test/files/pos/t12830.scala b/test/files/pos/t12830.scala index 2bce19c6d96d..90e1a8a7f237 100644 --- a/test/files/pos/t12830.scala +++ b/test/files/pos/t12830.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 class C { def i: Int = 42 diff --git a/test/files/pos/t12851/C_2.scala b/test/files/pos/t12851/C_2.scala index 4e5334029e13..859df816094c 100644 --- a/test/files/pos/t12851/C_2.scala +++ b/test/files/pos/t12851/C_2.scala @@ -1,2 +1,2 @@ -// scalac: -Werror +//> using options -Werror class C extends T2 diff --git a/test/files/pos/t12851c/ScalaNumber.java b/test/files/pos/t12851c/ScalaNumber.java index 5a6a8a7c65f5..5ed76ec3fb22 100644 --- a/test/files/pos/t12851c/ScalaNumber.java +++ b/test/files/pos/t12851c/ScalaNumber.java @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/test/files/pos/t12858/B.scala b/test/files/pos/t12858/B.scala index 36275173ecb6..3611602cbf1b 100644 --- a/test/files/pos/t12858/B.scala +++ b/test/files/pos/t12858/B.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror trait B1 extends A { def f: Int } trait C1 { def f = 2 } diff --git a/test/files/pos/t12953-expandee/Client_2.scala b/test/files/pos/t12953-expandee/Client_2.scala new file mode 100644 index 000000000000..82fd527122b1 --- /dev/null +++ b/test/files/pos/t12953-expandee/Client_2.scala @@ -0,0 +1,12 @@ + +//> using options -Werror -Wunused:locals -Xlint:missing-interpolator -Wmacros:default + +import Macro.id + +object Test extends App { + println { + id { + println("hello, world of $unusedVariable") + } + } +} diff --git a/test/files/pos/t12953-expandee/Macro_1.scala b/test/files/pos/t12953-expandee/Macro_1.scala new file mode 100644 index 000000000000..921cca9ae4cb --- /dev/null +++ b/test/files/pos/t12953-expandee/Macro_1.scala @@ -0,0 +1,12 @@ + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macro { + def id[A](body: A): A = macro impl[A] + + def impl[A: c.WeakTypeTag](c: Context)(body: c.Expr[A]) = { + import c.universe._ + q"""val unusedVariable = "42".toInt; $body""" + } +} diff --git a/test/files/pos/t12953.scala b/test/files/pos/t12953.scala new file mode 100644 index 000000000000..a0b44003a9fb --- /dev/null +++ b/test/files/pos/t12953.scala @@ -0,0 +1,24 @@ + +//> using options -Werror -Wunused:privates + +package example + +import scala.reflect.macros.blackbox + +/*case*/ class A(x: Int) + +class MyMacro(val c: blackbox.Context) { + import c.universe._ + + def impl(tree: c.Tree): Tree = { + tree match { + case q"${a: A}" => + //reify(a).tree // uses $m in expansion + reify(()).tree + case _ => + c.abort(c.enclosingPosition, "err") + } + } + + private implicit def instance: Unliftable[A] = ??? +} diff --git a/test/files/pos/t12976.scala b/test/files/pos/t12976.scala new file mode 100644 index 000000000000..05d36de90a81 --- /dev/null +++ b/test/files/pos/t12976.scala @@ -0,0 +1,6 @@ + +//> using options -Xsource:3-cross + +trait T { + def f(c: Char) = raw"\u%04X".format(c.toInt) +} diff --git a/test/files/pos/t12985.scala b/test/files/pos/t12985.scala new file mode 100644 index 000000000000..e95bbdf503f3 --- /dev/null +++ b/test/files/pos/t12985.scala @@ -0,0 +1,8 @@ + +//> using options -Wconf:any:s -Werror -Xlint:cloneable + +class Base extends Cloneable + +object X extends Base + +class Y extends Base diff --git a/test/files/pos/t12987.scala b/test/files/pos/t12987.scala new file mode 100644 index 000000000000..e9a866f4abc9 --- /dev/null +++ b/test/files/pos/t12987.scala @@ -0,0 +1,30 @@ +object typeMember { + class Foo { + type FT + class I + def m(b: FT, o: Option[I]): Int = 0 + } + + object Test { + def f[T]: Foo { type FT = T } = ??? + def t = { + val b: Any = ??? + f.m(b, None) + } + } +} + +object typeParam { + class Foo[FT] { + class I + def m(b: FT, o: Option[I]): Int = 0 + } + + object Test { + def f[T]: Foo[T] = ??? + def t = { + val b: Any = ??? + f.m(b, None) + } + } +} diff --git a/test/files/pos/t12988.scala b/test/files/pos/t12988.scala new file mode 100644 index 000000000000..45234ed3a19b --- /dev/null +++ b/test/files/pos/t12988.scala @@ -0,0 +1,12 @@ +object example { + final case class Toto[@specialized(Int) A] (private val actualToString: String, a: A) { + @inline def description: String = actualToString + } + def toto[A](a: A): Toto[A] = Toto("", a) +} + +object Test extends App { + import example._ + + println(s"Hello World! ${toto(1)}") +} diff --git a/test/files/pos/t13013.scala b/test/files/pos/t13013.scala new file mode 100644 index 000000000000..3a123b2ef8aa --- /dev/null +++ b/test/files/pos/t13013.scala @@ -0,0 +1,9 @@ +object Node { + trait Root { self: Node => + val root = this + } +} +trait Node { + def root: Node +} +final class RootNode extends Node with Node.Root diff --git a/test/files/pos/t13017/A.java b/test/files/pos/t13017/A.java new file mode 100644 index 000000000000..da6911a86790 --- /dev/null +++ b/test/files/pos/t13017/A.java @@ -0,0 +1,12 @@ +enum En { + @Deprecated Um +} + +@interface Ann { + En value(); +} + +public class A { + @Ann(En.Um) + public static void te() { return; } +} diff --git a/test/files/pos/t13017/Test.scala b/test/files/pos/t13017/Test.scala new file mode 100644 index 000000000000..8f939a5c4eb3 --- /dev/null +++ b/test/files/pos/t13017/Test.scala @@ -0,0 +1,5 @@ +//> using options -Werror -Ypickle-java -deprecation + +object Test { + def t = A.te() +} diff --git a/test/files/pos/t13025.scala b/test/files/pos/t13025.scala new file mode 100644 index 000000000000..6589629cad25 --- /dev/null +++ b/test/files/pos/t13025.scala @@ -0,0 +1,11 @@ +package p1 { + case class Foo[X] private (a: Int) + object Foo { + def apply[X](a: String): Foo[Any] = ??? + } +} +package p2 { + class C { + def x = p1.Foo[Any](0) + } +} diff --git a/test/files/pos/t13041.scala b/test/files/pos/t13041.scala new file mode 100644 index 000000000000..c1bcce529368 --- /dev/null +++ b/test/files/pos/t13041.scala @@ -0,0 +1,26 @@ + +//> using options -Werror -Wunused:patvars -Yvalidate-pos:typer + +class C { + val m = Map( + "first" -> Map((true, 1), (false, 2), (true, 3)), + "second" -> Map((true, 1), (false, 2), (true, 3)) + ) + def f = + m.map { case (a, m1) => + for { + (status, lag) <- m1 if status + } yield (a, status, lag) + } + def g = + for { + (a, m1) <- m + (status, lag) <- m1 if status + } yield (a, status, lag) + def leading = + for { + _ <- List("42") + i = 1 + _ <- List("0", "27")(i) + } yield () +} diff --git a/test/files/pos/t13055.scala b/test/files/pos/t13055.scala new file mode 100644 index 000000000000..e759da628092 --- /dev/null +++ b/test/files/pos/t13055.scala @@ -0,0 +1,28 @@ +//> using options -Xsource:3 -Xsource-features:eta-expand-always + +//import org.scalacheck._, Prop._ + +object Main extends App { + class Prop + class Gen[A] + object Gen { + implicit def const[T](x: T): Gen[T] = ??? + } + + def forAll[T1, P](g: Gen[T1])(f: T1 => P)(implicit p: P => Prop): Prop = ??? + def forAll[A1, P](f: A1 => P)(implicit p: P => Prop): Prop = ??? + + def what() = forAll { + (a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, + a8: Int, + a9: Int, + ) => false + } + +} + +/* + def what(): (((Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean) => Nothing) => Main.Prop = { + val eta$0$1: Main.Gen[(Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean] = Main.this.Gen.const[(Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean](((a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int, a9: Int) => false)); + ((f: ((Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean) => Nothing) => Main.this.forAll[(Int, Int, Int, Int, Int, Int, Int, Int, Int) => Boolean, Nothing](eta$0$1)(f)(scala.Predef.$conforms[Nothing])) +*/ diff --git a/test/files/pos/t13060.scala b/test/files/pos/t13060.scala new file mode 100644 index 000000000000..0af5ba710166 --- /dev/null +++ b/test/files/pos/t13060.scala @@ -0,0 +1,26 @@ +class C { + def id[A](r: A): A = r + def bug(x: Int, e: Boolean): Unit = { + x match { + case 1 => id(()) + case 2 if e => + } + println() + } +} + +class D { + def foo(): Unit = () + def b: Boolean = false + + def bug(x: Int): Unit = { + (x: @annotation.switch) match { + case 2 if b => + foo() + case _ if b => + foo() + case _ => + foo() + } + } +} diff --git a/test/files/pos/t13066.scala b/test/files/pos/t13066.scala new file mode 100644 index 000000000000..43a1a8a01159 --- /dev/null +++ b/test/files/pos/t13066.scala @@ -0,0 +1,17 @@ + +//> using options -Werror + +package testsamepackageimport { + package p { + class C + } + + package p { + package q { + import p._ // no warn + class U { + def f = new C + } + } + } +} diff --git a/test/files/pos/t13089.scala b/test/files/pos/t13089.scala new file mode 100644 index 000000000000..b54db5d43f72 --- /dev/null +++ b/test/files/pos/t13089.scala @@ -0,0 +1,17 @@ +//> using options -Werror + +trait F + +class T { + def t1 = "" == Some("").getOrElse(None) // used to warn incorrectly, because a RefinementClassSymbol is unrelated to String + + def a: T with Serializable = null + def b: Serializable with T = null + def t2 = "" == a // no warn, the implementation bails on intersection types + def t3 = "" == b // no warn + + def t1(a: F, b: Product with F) = a == b // no warn + def t2(a: F, b: F with Product) = a == b // no warn + def t3(a: F with Product, b: F) = a == b // no warn + def t4(a: Product with F, b: F) = a == b // no warn +} diff --git a/test/files/pos/t1439.scala b/test/files/pos/t1439.scala index baef9d60d031..df8fed01656a 100644 --- a/test/files/pos/t1439.scala +++ b/test/files/pos/t1439.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror // no unchecked warnings class View[C[A]] { } diff --git a/test/files/pos/t2030.scala b/test/files/pos/t2030.scala index 4a70cf662821..60260e5ae539 100644 --- a/test/files/pos/t2030.scala +++ b/test/files/pos/t2030.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3.0 +//> using options -Xsource:3.0 import scala.collection.immutable._ object Test extends App { diff --git a/test/files/pos/t2509-5.scala b/test/files/pos/t2509-5.scala index edda1cd4ca38..ea067fc896be 100644 --- a/test/files/pos/t2509-5.scala +++ b/test/files/pos/t2509-5.scala @@ -1,5 +1,5 @@ -// See https://github.com/lampepfl/dotty/issues/2974 -// scalac: -Yscala3-implicit-resolution +// See https://github.com/scala/scala3/issues/2974 +//> using options -Xsource:3 -Xsource-features:implicit-resolution trait Foo[-T] diff --git a/test/files/pos/t2509-6.scala b/test/files/pos/t2509-6.scala index d604b32750dc..5d21d986becf 100644 --- a/test/files/pos/t2509-6.scala +++ b/test/files/pos/t2509-6.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution class A class B extends A diff --git a/test/files/pos/t2509-7a.scala b/test/files/pos/t2509-7a.scala index b2ab27c90de2..5927e67bddfc 100644 --- a/test/files/pos/t2509-7a.scala +++ b/test/files/pos/t2509-7a.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution class Both[-A, +B] diff --git a/test/files/pos/t2799.scala b/test/files/pos/t2799.scala index fb951471494f..9cefaefc38b2 100644 --- a/test/files/pos/t2799.scala +++ b/test/files/pos/t2799.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror @deprecated("hi mom", "") case class Bob () diff --git a/test/files/pos/t3234.scala b/test/files/pos/t3234.scala index bd2746ca941e..1b1769aadff3 100644 --- a/test/files/pos/t3234.scala +++ b/test/files/pos/t3234.scala @@ -1,5 +1,5 @@ -// scalac: -opt:inline:** -Wopt -Werror +//> using options -opt:inline:** -Wopt -Werror // trait Trait1 { @inline final def foo2(n: Int) = n*n diff --git a/test/files/pos/t3368.scala b/test/files/pos/t3368.scala index 4984f5b23990..ba9bf05117d9 100644 --- a/test/files/pos/t3368.scala +++ b/test/files/pos/t3368.scala @@ -1,5 +1,5 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // trait X { // error: in XML literal: name expected, but char '!' cannot start a name diff --git a/test/files/pos/t3420.scala b/test/files/pos/t3420.scala index 0d0bc9a0ab77..962a0ab437ff 100644 --- a/test/files/pos/t3420.scala +++ b/test/files/pos/t3420.scala @@ -1,5 +1,5 @@ -// scalac: -opt:inline:** -Wopt -Werror +//> using options -opt:inline:** -Wopt -Werror // class C { val cv = Map[Int, Int](1 -> 2) diff --git a/test/files/pos/t3420b.scala b/test/files/pos/t3420b.scala index 6b5f61019633..84471c995d08 100644 --- a/test/files/pos/t3420b.scala +++ b/test/files/pos/t3420b.scala @@ -1,5 +1,5 @@ -// scalac: --release 8 -opt:inline:** -Wopt -Werror +//> using options --release 8 -opt:inline:** -Wopt -Werror // class C { val cv = Map[Int, Int](1 -> 2) diff --git a/test/files/pos/t3495.scala b/test/files/pos/t3495.scala index bcbc3ebfdc98..5dfd28328ce6 100644 --- a/test/files/pos/t3495.scala +++ b/test/files/pos/t3495.scala @@ -1,5 +1,5 @@ -// scalac: -Dsoot.class.path=bin:. +//> using options -Dsoot.class.path=bin:. // // option parsing broke on colon // diff --git a/test/files/pos/t3664.scala b/test/files/pos/t3664.scala index 57cb67794beb..0c0ea6fa17a5 100644 --- a/test/files/pos/t3664.scala +++ b/test/files/pos/t3664.scala @@ -1,5 +1,4 @@ - -//> using options -Werror -Xlint -Xsource:3-cross +//> using options -Werror -Xlint -Xsource:3 import language.implicitConversions diff --git a/test/files/pos/t3960.scala b/test/files/pos/t3960.scala index ed3fd8d87651..6452a645ceee 100644 --- a/test/files/pos/t3960.scala +++ b/test/files/pos/t3960.scala @@ -1,5 +1,5 @@ -// scalac: -Ycheck:typer +//> using options -Ycheck:typer // class A { class C[x] diff --git a/test/files/pos/t3995.scala b/test/files/pos/t3995.scala index 8babe50baf33..57b53738d44f 100644 --- a/test/files/pos/t3995.scala +++ b/test/files/pos/t3995.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// // class Lift { def apply(f: F0): Unit = {} diff --git a/test/files/pos/t4020.scala b/test/files/pos/t4020.scala index daba560bed8a..fb620e98c897 100644 --- a/test/files/pos/t4020.scala +++ b/test/files/pos/t4020.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A { sealed trait Foo diff --git a/test/files/pos/t4225.scala b/test/files/pos/t4225.scala index 03bb01f9ad67..2ea3222ca36b 100644 --- a/test/files/pos/t4225.scala +++ b/test/files/pos/t4225.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// // object Test { class Foo { diff --git a/test/files/pos/t4225b.scala b/test/files/pos/t4225b.scala index 2c3133c33fcb..a2786759a6ce 100644 --- a/test/files/pos/t4225b.scala +++ b/test/files/pos/t4225b.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// // class Foo { class Bar diff --git a/test/files/pos/t4225c.scala b/test/files/pos/t4225c.scala index a5d3b9ae06a5..e21b2251ead8 100644 --- a/test/files/pos/t4225c.scala +++ b/test/files/pos/t4225c.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// // trait A trait B diff --git a/test/files/pos/t4494.scala b/test/files/pos/t4494.scala index 0e78f83a2b86..5e08e35d87bc 100644 --- a/test/files/pos/t4494.scala +++ b/test/files/pos/t4494.scala @@ -1,5 +1,5 @@ -// scalac: -Yrangepos +// // object A { List(1) diff --git a/test/files/pos/t4649.scala b/test/files/pos/t4649.scala index 4cfa8ac995ce..a00121f2eedf 100644 --- a/test/files/pos/t4649.scala +++ b/test/files/pos/t4649.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { // @annotation.tailrec diff --git a/test/files/pos/t4744/Bar.scala b/test/files/pos/t4744/Bar.scala index 01182d0a9a9f..4d20c49eb561 100644 --- a/test/files/pos/t4744/Bar.scala +++ b/test/files/pos/t4744/Bar.scala @@ -1,2 +1,2 @@ -// scalac: -Ybreak-cycles +//> using options -Ybreak-cycles class Bar { val quux = new Foo[java.lang.Integer]() } diff --git a/test/files/pos/t4840.scala b/test/files/pos/t4840.scala index b31d37b1ab30..921da5e8ca68 100644 --- a/test/files/pos/t4840.scala +++ b/test/files/pos/t4840.scala @@ -1,5 +1,5 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt // class Crashy { def g(): Option[Any] = None diff --git a/test/files/pos/t4911.scala b/test/files/pos/t4911.scala index ba2daa367dd9..efae95df97d0 100644 --- a/test/files/pos/t4911.scala +++ b/test/files/pos/t4911.scala @@ -1,5 +1,5 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import language._ diff --git a/test/files/pos/t4940.scala b/test/files/pos/t4940.scala new file mode 100644 index 000000000000..b6a59a5bdd08 --- /dev/null +++ b/test/files/pos/t4940.scala @@ -0,0 +1,39 @@ +//> using options -Werror -Xlint +class C { + val f: PartialFunction[String, Int] = (x: String) => x match { case "x" => 3 } + val f2: PartialFunction[String, Int] = (x: String) => x match { case "x" => x.toString.toInt } + + val g: PartialFunction[X, Int] = (x: X) => x match { case X(i) => i } + val g2: PartialFunction[X, Int] = (x: Y) => x match { case X(i) => i } + //val g3: PartialFunction[Y, Int] = (x: X) => x match { case X(i) => i } + + val m: PartialFunction[Double, Int] = (x: Double) => x match { case 3.14 => 3 } +} + +class D { + val f: PartialFunction[String, Int] = _ match { case "x" => 3 } + + val g: PartialFunction[X, Int] = _ match { case X(i) => i } + + val m: PartialFunction[Double, Int] = _ match { case 3.14 => 3 } +} + +class E { + val f: PartialFunction[String, Int] = x => x.toInt + + val g: PartialFunction[X, Int] = x => x.x + + val m: PartialFunction[Double, Long] = d => d.round +} + +trait Y +case class X(x: Int) extends Y + +class ActuallyOK { + val map = Map(42 -> "foo") + def k = List(27).collect { + map.get(_) match { + case Some(i) => i + } + } +} diff --git a/test/files/pos/t5029.scala b/test/files/pos/t5029.scala index c8af164c1d16..d423d1ba1244 100644 --- a/test/files/pos/t5029.scala +++ b/test/files/pos/t5029.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { (Vector(): Seq[_]) match { case List() => true; case Nil => false; case x => throw new MatchError(x) } diff --git a/test/files/pos/t5165b/TestObject_3.scala b/test/files/pos/t5165b/TestObject_3.scala index fba846c0be65..68f85d53a47e 100644 --- a/test/files/pos/t5165b/TestObject_3.scala +++ b/test/files/pos/t5165b/TestObject_3.scala @@ -1,3 +1,3 @@ -// scalac: -Werror +//> using options -Werror object TestObject extends TestTrait diff --git a/test/files/pos/t5165b/TestTrait_2.scala b/test/files/pos/t5165b/TestTrait_2.scala index 1c1a560378c8..94a7e4b92624 100644 --- a/test/files/pos/t5165b/TestTrait_2.scala +++ b/test/files/pos/t5165b/TestTrait_2.scala @@ -1,3 +1,3 @@ -// scalac: -Werror +//> using options -Werror @TestAnnotation_1(one=TestAnnotation_1.TestEnumOne.A, two=TestAnnotation_1.TestEnumTwo.C, strVal="something") trait TestTrait diff --git a/test/files/pos/t5175.scala b/test/files/pos/t5175.scala index 37501ca52918..b3da323650d9 100644 --- a/test/files/pos/t5175.scala +++ b/test/files/pos/t5175.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def ==(p: Phase): Int = 0 diff --git a/test/files/pos/t5265a.scala b/test/files/pos/t5265a.scala index 95db6ec743ed..b8c465d85e13 100644 --- a/test/files/pos/t5265a.scala +++ b/test/files/pos/t5265a.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wconf:cat=other-implicit-type:s +//> using options -Werror -Wconf:cat=other-implicit-type:s trait T[A] class C[A: T] diff --git a/test/files/pos/t5365-nonStrict.scala b/test/files/pos/t5365-nonStrict.scala index 3934ea7b7f6a..c71ff102b058 100644 --- a/test/files/pos/t5365-nonStrict.scala +++ b/test/files/pos/t5365-nonStrict.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xnon-strict-patmat-analysis +//> using options -Werror -Xnon-strict-patmat-analysis // // copy of neg/t5365.scala, which under -Xnon-strict-patmat-analysis gives no warnings class C { diff --git a/test/files/pos/t5542.scala b/test/files/pos/t5542.scala index 3f79d7e3f422..816d371dcf33 100644 --- a/test/files/pos/t5542.scala +++ b/test/files/pos/t5542.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class Test { Option(3) match { case Some(n) => n; case None => 0 } diff --git a/test/files/pos/t5809.scala b/test/files/pos/t5809.scala index ab8fa12969f7..ef41fd0db6e8 100644 --- a/test/files/pos/t5809.scala +++ b/test/files/pos/t5809.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Xfatal-warnings +//> using options -Xlint -Xfatal-warnings // package object foo { implicit class EnrichedInt(foo: Int) { diff --git a/test/files/pos/t5818.scala b/test/files/pos/t5818.scala index 6948c0d08f7d..cdea6899b8e7 100644 --- a/test/files/pos/t5818.scala +++ b/test/files/pos/t5818.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // abstract class Abstract { type TypeMember diff --git a/test/files/pos/t5897.scala b/test/files/pos/t5897.scala index 64b7ce139ead..61599eff22e9 100644 --- a/test/files/pos/t5897.scala +++ b/test/files/pos/t5897.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // no warning here // (strangely, if there's an unreachable code warning *anywhere in this compilation unit*, diff --git a/test/files/pos/t5899.scala b/test/files/pos/t5899.scala index f3e9dd002b16..b94f845605a6 100644 --- a/test/files/pos/t5899.scala +++ b/test/files/pos/t5899.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import scala.tools.nsc._ diff --git a/test/files/pos/t5930.scala b/test/files/pos/t5930.scala index bdcb43ecd624..0abbcaf97091 100644 --- a/test/files/pos/t5930.scala +++ b/test/files/pos/t5930.scala @@ -1,4 +1,4 @@ -// scalac: -Ywarn-dead-code -Xfatal-warnings +//> using options -Ywarn-dead-code -Xfatal-warnings // // should not warn about dead code (`matchEnd(throw new MatchError)`) class Test { diff --git a/test/files/pos/t5932.scala b/test/files/pos/t5932.scala index 5c9630cd6c14..904ef3708c76 100644 --- a/test/files/pos/t5932.scala +++ b/test/files/pos/t5932.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A diff --git a/test/files/pos/t5946.scala b/test/files/pos/t5946.scala index a06805468621..b8019d4c94dc 100644 --- a/test/files/pos/t5946.scala +++ b/test/files/pos/t5946.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object TestDep { class Ops(val g: scala.reflect.api.JavaUniverse) { diff --git a/test/files/pos/t5954c/A_1.scala b/test/files/pos/t5954c/A_1.scala index 2affe3b7cb17..f61fb978a569 100644 --- a/test/files/pos/t5954c/A_1.scala +++ b/test/files/pos/t5954c/A_1.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package object A { // these used to should be prevented by the implementation restriction // but are now allowed diff --git a/test/files/pos/t5954c/B_2.scala b/test/files/pos/t5954c/B_2.scala index 2affe3b7cb17..f61fb978a569 100644 --- a/test/files/pos/t5954c/B_2.scala +++ b/test/files/pos/t5954c/B_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package object A { // these used to should be prevented by the implementation restriction // but are now allowed diff --git a/test/files/pos/t5954d/A_1.scala b/test/files/pos/t5954d/A_1.scala index 57039b9767bf..cfd32660649a 100644 --- a/test/files/pos/t5954d/A_1.scala +++ b/test/files/pos/t5954d/A_1.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xdev +//> using options -Werror -Xdev package p { package object base { class B diff --git a/test/files/pos/t5954d/B_2.scala b/test/files/pos/t5954d/B_2.scala index e83f1fda2a9d..d89c7ceef104 100644 --- a/test/files/pos/t5954d/B_2.scala +++ b/test/files/pos/t5954d/B_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xdev +//> using options -Werror -Xdev package p { trait T { class B diff --git a/test/files/pos/t5968.scala b/test/files/pos/t5968.scala index 4b99bf476daf..ac59997ee294 100644 --- a/test/files/pos/t5968.scala +++ b/test/files/pos/t5968.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object X { def f(e: Either[Int, X.type]) = e match { diff --git a/test/files/pos/t6008.scala b/test/files/pos/t6008.scala index 3a815cb933c4..447d0a0ce714 100644 --- a/test/files/pos/t6008.scala +++ b/test/files/pos/t6008.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // none of these should complain about exhaustivity class Test { diff --git a/test/files/pos/t6022.scala b/test/files/pos/t6022.scala index 8a1a8581af6f..a28bb7dabdab 100644 --- a/test/files/pos/t6022.scala +++ b/test/files/pos/t6022.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class Test { (null: Any) match { diff --git a/test/files/pos/t6091.scala b/test/files/pos/t6091.scala index 82d9a9c5b6f9..8ce694e643c1 100644 --- a/test/files/pos/t6091.scala +++ b/test/files/pos/t6091.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Xlint +//> using options -Xfatal-warnings -Xlint // object Foo { def eq(x: Int) = x } diff --git a/test/files/pos/t6123-explaintypes-implicits.scala b/test/files/pos/t6123-explaintypes-implicits.scala index 3d5c0e4ee2e8..38ba0cae3328 100644 --- a/test/files/pos/t6123-explaintypes-implicits.scala +++ b/test/files/pos/t6123-explaintypes-implicits.scala @@ -1,4 +1,4 @@ -// scalac: -explaintypes +//> using options -explaintypes // object ImplicitBugReport { trait Exp[+T] diff --git a/test/files/pos/t6146.scala b/test/files/pos/t6146.scala index adb8f760f831..9c7d37b5fef2 100644 --- a/test/files/pos/t6146.scala +++ b/test/files/pos/t6146.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // No unreachable or exhaustiveness warnings, please. diff --git a/test/files/pos/t6159.scala b/test/files/pos/t6159.scala index 0863350323e1..af68e1ca3c52 100644 --- a/test/files/pos/t6159.scala +++ b/test/files/pos/t6159.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror trait A { sealed abstract class X private class X1 extends X with X2 { } diff --git a/test/files/pos/t6162-inheritance.scala b/test/files/pos/t6162-inheritance.scala index b83b3d16e12a..e0662833836f 100644 --- a/test/files/pos/t6162-inheritance.scala +++ b/test/files/pos/t6162-inheritance.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // package scala.t6126 diff --git a/test/files/pos/t6210.scala b/test/files/pos/t6210.scala index 3cbd7707f126..44ae23511dcb 100644 --- a/test/files/pos/t6210.scala +++ b/test/files/pos/t6210.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // abstract sealed trait AST abstract sealed trait AExpr extends AST diff --git a/test/files/pos/t6217.scala b/test/files/pos/t6217.scala index 45b19c6138c9..8695bf90b2ea 100644 --- a/test/files/pos/t6217.scala +++ b/test/files/pos/t6217.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings package p { package _root_ { package scala { diff --git a/test/files/pos/t6260.scala b/test/files/pos/t6260.scala index 80a70ec412e2..b09668f825ea 100644 --- a/test/files/pos/t6260.scala +++ b/test/files/pos/t6260.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline // class Box[X](val x: X) extends AnyVal { def map[Y](f: X => Y): Box[Y] = diff --git a/test/files/pos/t6275.scala b/test/files/pos/t6275.scala index 00033b7fd935..1ba9fac14880 100644 --- a/test/files/pos/t6275.scala +++ b/test/files/pos/t6275.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait A[T] diff --git a/test/files/pos/t6450.scala b/test/files/pos/t6450.scala index 7dc6b36e491e..39aa6307f9f4 100644 --- a/test/files/pos/t6450.scala +++ b/test/files/pos/t6450.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object ExhaustivityWarnBugReportMinimal { //sealed is needed for the warning sealed trait FoundNode[T]/*presence of parameters is irrelevant*/ diff --git a/test/files/pos/t6537.scala b/test/files/pos/t6537.scala index 0320508b320a..0d5712b54526 100644 --- a/test/files/pos/t6537.scala +++ b/test/files/pos/t6537.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // package tester diff --git a/test/files/pos/t6675.scala b/test/files/pos/t6675.scala index ed16807b61d6..bd9624ff004c 100644 --- a/test/files/pos/t6675.scala +++ b/test/files/pos/t6675.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // object LeftOrRight { def unapply[A](value: Either[A, A]): Option[A] = value match { diff --git a/test/files/pos/t6771.scala b/test/files/pos/t6771.scala index d6781f640678..5e34b4baff40 100644 --- a/test/files/pos/t6771.scala +++ b/test/files/pos/t6771.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { type Id[X] = X diff --git a/test/files/pos/t6891.scala b/test/files/pos/t6891.scala index 696eb81a7eec..9884bf3bda1d 100644 --- a/test/files/pos/t6891.scala +++ b/test/files/pos/t6891.scala @@ -1,4 +1,4 @@ -// scalac: -Ycheck:extmethods -Xfatal-warnings +//> using options -Ycheck:extmethods -Xfatal-warnings // object O { implicit class Foo[A](val value: String) extends AnyVal { diff --git a/test/files/pos/t6896.scala b/test/files/pos/t6896.scala index 022bff5c2f34..404d343e0c78 100644 --- a/test/files/pos/t6896.scala +++ b/test/files/pos/t6896.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object TooManyMains { def main(args: Array[String]): Unit = { diff --git a/test/files/pos/t6942/t6942.scala b/test/files/pos/t6942/t6942.scala index 15874c90f1a7..9a7440e455dc 100644 --- a/test/files/pos/t6942/t6942.scala +++ b/test/files/pos/t6942/t6942.scala @@ -1,4 +1,4 @@ -// scalac: -nowarn +//> using options -nowarn // // not a peep out of the pattern matcher's unreachability analysis // its budget should suffice for these simple matches (they do have a large search space) diff --git a/test/files/pos/t6963c.scala b/test/files/pos/t6963c.scala index 80e8f11d9de5..7e71581a75fd 100644 --- a/test/files/pos/t6963c.scala +++ b/test/files/pos/t6963c.scala @@ -1,4 +1,4 @@ -// scalac: -Xmigration:2.9 -Xfatal-warnings +//> using options -Werror -Xmigration:2.9 // import collection.Seq object Test { diff --git a/test/files/pos/t6978/S.scala b/test/files/pos/t6978/S.scala index f5694c81d525..dad2d950a9a8 100644 --- a/test/files/pos/t6978/S.scala +++ b/test/files/pos/t6978/S.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Xfatal-warnings +//> using options -Xlint -Xfatal-warnings trait X { def f: Int } object Test extends J with X with App { diff --git a/test/files/pos/t6994.scala b/test/files/pos/t6994.scala index 34c65858fccd..143c75d329df 100644 --- a/test/files/pos/t6994.scala +++ b/test/files/pos/t6994.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { object NF { diff --git a/test/files/pos/t7011.scala b/test/files/pos/t7011.scala index c508bfd9e6b0..ff2b15e1bb2b 100644 --- a/test/files/pos/t7011.scala +++ b/test/files/pos/t7011.scala @@ -1,4 +1,4 @@ -// scalac: -Ydebug -Xfatal-warnings +//> using options -Ydebug -Xfatal-warnings // object bar { def foo: Unit = { diff --git a/test/files/pos/t7183.scala b/test/files/pos/t7183.scala index 38476f5c9ed9..488924f7d4cc 100644 --- a/test/files/pos/t7183.scala +++ b/test/files/pos/t7183.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A object A { diff --git a/test/files/pos/t7212.scala b/test/files/pos/t7212.scala index 29285c53d87e..ea68ac90eab9 100644 --- a/test/files/pos/t7212.scala +++ b/test/files/pos/t7212.scala @@ -1,5 +1,4 @@ - -// scalac: -Xsource:3-cross -Xmigration +//> using options -Xsource:3 -Xsource-features:infer-override class A { def f: Option[String] = Some("hello, world") diff --git a/test/files/pos/t7212b/ScalaThing.scala b/test/files/pos/t7212b/ScalaThing.scala index b0facb72771e..35df80065f48 100644 --- a/test/files/pos/t7212b/ScalaThing.scala +++ b/test/files/pos/t7212b/ScalaThing.scala @@ -1,5 +1,4 @@ - -// scalac: -Xsource:3-cross -Xmigration +//> using options -Xsource:3 -Xsource-features:infer-override class ScalaThing extends JavaThing { override def remove() = ??? diff --git a/test/files/pos/t7232/Test.scala b/test/files/pos/t7232/Test.scala index 990989bffc69..798bb11235e3 100644 --- a/test/files/pos/t7232/Test.scala +++ b/test/files/pos/t7232/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { import pack._ Foo.okay().size() diff --git a/test/files/pos/t7232b/Test.scala b/test/files/pos/t7232b/Test.scala index 3832ca98fb48..6675688722cc 100644 --- a/test/files/pos/t7232b/Test.scala +++ b/test/files/pos/t7232b/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { import pack._ diff --git a/test/files/pos/t7232c/Test.scala b/test/files/pos/t7232c/Test.scala index 799701b85b3c..48ce66340185 100644 --- a/test/files/pos/t7232c/Test.scala +++ b/test/files/pos/t7232c/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { import pack._ Foo.innerList().isInnerList() diff --git a/test/files/pos/t7232d/Test.scala b/test/files/pos/t7232d/Test.scala index 88631c4bea0b..af3b5f05ded4 100644 --- a/test/files/pos/t7232d/Test.scala +++ b/test/files/pos/t7232d/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { import pack._ Foo.mapEntry().getKey() diff --git a/test/files/pos/t7232e/Test.scala b/test/files/pos/t7232e/Test.scala index 09edcabcbe07..aad5788927c3 100644 --- a/test/files/pos/t7232e/Test.scala +++ b/test/files/pos/t7232e/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { import pack._ diff --git a/test/files/pos/t7232g/Test.scala b/test/files/pos/t7232g/Test.scala index b8dde38e01d7..1f73d9edff61 100644 --- a/test/files/pos/t7232g/Test.scala +++ b/test/files/pos/t7232g/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { import pack._ diff --git a/test/files/pos/t7285a.scala b/test/files/pos/t7285a.scala index a17fe075a0c8..1f1c1e1c652a 100644 --- a/test/files/pos/t7285a.scala +++ b/test/files/pos/t7285a.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class Base diff --git a/test/files/pos/t7315.scala b/test/files/pos/t7315.scala index a593957fcd3a..bb59cf5b14a3 100644 --- a/test/files/pos/t7315.scala +++ b/test/files/pos/t7315.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation -Xfatal-warnings +//> using options -deprecation -Xfatal-warnings // package scala.pack diff --git a/test/files/pos/t7369.scala b/test/files/pos/t7369.scala index 55e138220619..8234eeb9d2e8 100644 --- a/test/files/pos/t7369.scala +++ b/test/files/pos/t7369.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { val X, Y = true diff --git a/test/files/pos/t7427.scala b/test/files/pos/t7427.scala index 15d5baba0595..2050702e4adc 100644 --- a/test/files/pos/t7427.scala +++ b/test/files/pos/t7427.scala @@ -1,4 +1,4 @@ -// scalac: -Ydebug +//> using options -Ydebug // // Compiles with no options // Compiles with -Ydebug -Ydisable-unreachable-prevention diff --git a/test/files/pos/t7433.scala b/test/files/pos/t7433.scala index 07b4dd2b7781..16015b178a41 100644 --- a/test/files/pos/t7433.scala +++ b/test/files/pos/t7433.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { def foo(): Unit = { diff --git a/test/files/pos/t7481.scala b/test/files/pos/t7481.scala index 0f9b012042a3..c419d1f20eba 100644 --- a/test/files/pos/t7481.scala +++ b/test/files/pos/t7481.scala @@ -1,5 +1,5 @@ -// scalac: -no-specialization +//> using options -no-specialization object Test { // val fixesCompile = Array(1, 2, 3) diff --git a/test/files/pos/t7551/T_1.scala b/test/files/pos/t7551/T_1.scala index ac41dceca61b..86e3d0d0ac2c 100644 --- a/test/files/pos/t7551/T_1.scala +++ b/test/files/pos/t7551/T_1.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package p @A(subInterface = classOf[T.S]) diff --git a/test/files/pos/t7551/Test_2.scala b/test/files/pos/t7551/Test_2.scala index 2ca9c0c8d6bd..a8b0e508c497 100644 --- a/test/files/pos/t7551/Test_2.scala +++ b/test/files/pos/t7551/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package p object Foo { diff --git a/test/files/pos/t7591/Demo.scala b/test/files/pos/t7591/Demo.scala index 841bf737eff7..90fee0e02dcd 100644 --- a/test/files/pos/t7591/Demo.scala +++ b/test/files/pos/t7591/Demo.scala @@ -51,7 +51,7 @@ object DemoSpec extends DemoSpec with Property { type ThisCommandLine = SpecCommandLine def creator(args: List[String]) = new SpecCommandLine(args) { - override def errorFn(msg: String) = { println("Error: " + msg) ; sys.exit(0) } + override def errorFn(msg: String) = { throw new Error("Error: " + msg) } } } diff --git a/test/files/pos/t7591/Property.scala b/test/files/pos/t7591/Property.scala index 601d51445c17..65f02fd7449c 100644 --- a/test/files/pos/t7591/Property.scala +++ b/test/files/pos/t7591/Property.scala @@ -1,7 +1,7 @@ /* * Scala (https://www.scala-lang.org) * - * Copyright EPFL and Lightbend, Inc. + * Copyright EPFL and Lightbend, Inc. dba Akka * * Licensed under Apache License 2.0 * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/test/files/pos/t7649.scala b/test/files/pos/t7649.scala index 3d7867536aac..d31c150bc40f 100644 --- a/test/files/pos/t7649.scala +++ b/test/files/pos/t7649.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object Test { val c: scala.reflect.macros.blackbox.Context = ??? diff --git a/test/files/pos/t7683-stop-after-parser/sample_2.scala b/test/files/pos/t7683-stop-after-parser/sample_2.scala index 0547d7212a8e..bc08be642a68 100644 --- a/test/files/pos/t7683-stop-after-parser/sample_2.scala +++ b/test/files/pos/t7683-stop-after-parser/sample_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Xplugin-require:timebomb -Ystop-after:parser +//> using options -Xplugin:. -Xplugin-require:timebomb -Ystop-after:parser package sample // just a sample that is compiled with the explosive plugin disabled diff --git a/test/files/pos/t7707.scala b/test/files/pos/t7707.scala index f47d0b19ad79..fee40c2862af 100644 --- a/test/files/pos/t7707.scala +++ b/test/files/pos/t7707.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // uses apply default, ctor default is unused object O { O() ; def f(): Unit = O() } diff --git a/test/files/pos/t7750.scala b/test/files/pos/t7750.scala index 29aad6461ec4..b0e509072f3d 100644 --- a/test/files/pos/t7750.scala +++ b/test/files/pos/t7750.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -feature +//> using options -Xfatal-warnings -feature // trait LazyCombiner[Elem, +To, Buff <: Growable[Elem] with Sizing] trait Growable[T] diff --git a/test/files/pos/t7864.scala b/test/files/pos/t7864.scala index 6ddec3120356..10f1b926e1b1 100644 --- a/test/files/pos/t7864.scala +++ b/test/files/pos/t7864.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint +//> using options -Xlint // object Test { val f = 0; diff --git a/test/files/pos/t8001/Test_2.scala b/test/files/pos/t8001/Test_2.scala index 10d9f9408b0c..9db1f4636be6 100644 --- a/test/files/pos/t8001/Test_2.scala +++ b/test/files/pos/t8001/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test extends App { Macros.foo (): Unit diff --git a/test/files/pos/t8040.scala b/test/files/pos/t8040.scala index 48ecbae192f7..f55ce3c166ea 100644 --- a/test/files/pos/t8040.scala +++ b/test/files/pos/t8040.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -Ywarn-unused:params +//> using options -Xfatal-warnings -Ywarn-unused:params // object Test { diff --git a/test/files/pos/t8064/Client_2.scala b/test/files/pos/t8064/Client_2.scala index 64ce75cbdee6..4b4f6f199219 100644 --- a/test/files/pos/t8064/Client_2.scala +++ b/test/files/pos/t8064/Client_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// object Test { Macro { def s = "" diff --git a/test/files/pos/t8064/Macro_1.scala b/test/files/pos/t8064/Macro_1.scala index c8de31aad5c9..3faf1bda0a46 100644 --- a/test/files/pos/t8064/Macro_1.scala +++ b/test/files/pos/t8064/Macro_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// import language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/pos/t8064b/Client_2.scala b/test/files/pos/t8064b/Client_2.scala index 6eac7dc4184b..052c14860eb6 100644 --- a/test/files/pos/t8064b/Client_2.scala +++ b/test/files/pos/t8064b/Client_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// object Test { Macro { "".reverse diff --git a/test/files/pos/t8064b/Macro_1.scala b/test/files/pos/t8064b/Macro_1.scala index 941f7ffd2465..e803a072392c 100644 --- a/test/files/pos/t8064b/Macro_1.scala +++ b/test/files/pos/t8064b/Macro_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// import language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/pos/t8121/B_2.scala b/test/files/pos/t8121/B_2.scala index a6e3792c6cac..660dfd6791e3 100644 --- a/test/files/pos/t8121/B_2.scala +++ b/test/files/pos/t8121/B_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror package b import a.Foo class Foo diff --git a/test/files/pos/t8363.scala b/test/files/pos/t8363.scala index e681bf2e7233..b076d5a6a461 100644 --- a/test/files/pos/t8363.scala +++ b/test/files/pos/t8363.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method +//> using options -Ydelambdafy:method // class C(a: Any) class Test { diff --git a/test/files/pos/t8410.scala b/test/files/pos/t8410.scala index 6b420efd8946..8b63b936617d 100644 --- a/test/files/pos/t8410.scala +++ b/test/files/pos/t8410.scala @@ -1,5 +1,4 @@ -// scalac: -opt:inline:** -Wopt:none -Werror -deprecation:false -// +//> using options -opt:inline:** -Wopt:none -Werror -deprecation:false object Test extends App { @deprecated("","") def f = 42 diff --git a/test/files/pos/t8523.scala b/test/files/pos/t8523.scala index 6cc30b869772..b70a4cdc2ee6 100644 --- a/test/files/pos/t8523.scala +++ b/test/files/pos/t8523.scala @@ -1,4 +1,4 @@ -// scalac: -Ywarn-dead-code -Xfatal-warnings +//> using options -Ywarn-dead-code -Xfatal-warnings // import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/pos/t8546.scala b/test/files/pos/t8546.scala index d349f58d169c..da374f427f05 100644 --- a/test/files/pos/t8546.scala +++ b/test/files/pos/t8546.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // package test diff --git a/test/files/pos/t8578.scala b/test/files/pos/t8578.scala index 41ce9afc9e62..be5be85156bb 100644 --- a/test/files/pos/t8578.scala +++ b/test/files/pos/t8578.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method +//> using options -Ydelambdafy:method // class DuplicateClassName { () => { diff --git a/test/files/pos/t8596.scala b/test/files/pos/t8596.scala index 41126bbb0ee7..72a63c3b3b04 100644 --- a/test/files/pos/t8596.scala +++ b/test/files/pos/t8596.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // class TypeTreeObjects { class Container { diff --git a/test/files/pos/t8602.scala b/test/files/pos/t8602.scala index 3ab5e15a445e..b8502b646d88 100644 --- a/test/files/pos/t8602.scala +++ b/test/files/pos/t8602.scala @@ -1,4 +1,4 @@ -// scalac: -language:higherKinds +//> using options -language:higherKinds // object Test { case class Foo[CC[_], D <: CC[Int]](d: D, cc: CC[Int]) diff --git a/test/files/pos/t8617.scala b/test/files/pos/t8617.scala index df5508ff1caf..42ba325f5f05 100644 --- a/test/files/pos/t8617.scala +++ b/test/files/pos/t8617.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object Test { def foo[A] = implicitly[OptManifest[A]] // was "unpositioned tree" under -Yrangepos diff --git a/test/files/pos/t8736-b.scala b/test/files/pos/t8736-b.scala index 903292d23298..1c96b7fd30fa 100644 --- a/test/files/pos/t8736-b.scala +++ b/test/files/pos/t8736-b.scala @@ -1,4 +1,4 @@ -// scalac: -feature -language:_ -Xfatal-warnings +//> using options -feature -language:_ -Xfatal-warnings // showing that all are set class X { def hk[M[_]] = ??? diff --git a/test/files/pos/t8736.scala b/test/files/pos/t8736.scala index 46c0cdfd000e..5768f5f95333 100644 --- a/test/files/pos/t8736.scala +++ b/test/files/pos/t8736.scala @@ -1,4 +1,4 @@ -// scalac: -feature -language:implicitConversions -language:higherKinds -language:-implicitConversions -Xfatal-warnings +//> using options -feature -language:implicitConversions -language:higherKinds -language:-implicitConversions -Xfatal-warnings // showing that multiple settings are respected, and explicit enablement has precedence class X { def hk[M[_]] = ??? diff --git a/test/files/pos/t8781/Test_2.scala b/test/files/pos/t8781/Test_2.scala index d7237eb54c46..c67c7daab081 100644 --- a/test/files/pos/t8781/Test_2.scala +++ b/test/files/pos/t8781/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ymacro-expand:discard -Ystop-after:typer +//> using options -Ymacro-expand:discard -Ystop-after:typer // object Test { implicit class RichT(t: T) { def augmented = "" } diff --git a/test/files/pos/t8828.scala b/test/files/pos/t8828.scala index 3058aa54383e..5015a785157b 100644 --- a/test/files/pos/t8828.scala +++ b/test/files/pos/t8828.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:inaccessible -Xfatal-warnings +//> using options -Xlint:inaccessible -Xfatal-warnings // package outer diff --git a/test/files/pos/t8861.scala b/test/files/pos/t8861.scala index 74d5a8be5497..a560bba1be96 100644 --- a/test/files/pos/t8861.scala +++ b/test/files/pos/t8861.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:infer-any -Xfatal-warnings +//> using options -Xlint:infer-any -Xfatal-warnings // trait Test { diff --git a/test/files/pos/t8934a/Test_2.scala b/test/files/pos/t8934a/Test_2.scala index ecc922db0859..6b25ad28c0ba 100644 --- a/test/files/pos/t8934a/Test_2.scala +++ b/test/files/pos/t8934a/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:typer -Ymacro-expand:discard -nowarn +//> using options -Ystop-after:typer -Ymacro-expand:discard -nowarn object Test { "" match { case Unapply(a, b) => diff --git a/test/files/pos/t8954/t1.scala b/test/files/pos/t8954/t1.scala index 1f015a7d48d0..ccd5cb71b280 100644 --- a/test/files/pos/t8954/t1.scala +++ b/test/files/pos/t8954/t1.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation package scala.foo // 1. a class about to be made final diff --git a/test/files/pos/t8954/t2.scala b/test/files/pos/t8954/t2.scala index 899ad407015d..5002a62a096b 100644 --- a/test/files/pos/t8954/t2.scala +++ b/test/files/pos/t8954/t2.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings -deprecation +//> using options -Xfatal-warnings -deprecation package scala.foo // 1.2 deprecated children should be fine... diff --git a/test/files/pos/t8965.scala b/test/files/pos/t8965.scala index 6386fd996865..729777049d10 100644 --- a/test/files/pos/t8965.scala +++ b/test/files/pos/t8965.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // class A { def f(x: Any with AnyRef, y: Any with AnyRef) = x eq y diff --git a/test/files/pos/t8999.scala b/test/files/pos/t8999.scala index 4ec64da9bb67..23b3870b812d 100644 --- a/test/files/pos/t8999.scala +++ b/test/files/pos/t8999.scala @@ -1,4 +1,4 @@ -// scalac: -nowarn +//> using options -nowarn // object Types { diff --git a/test/files/pos/t9020.scala b/test/files/pos/t9020.scala index 679af42f2aa8..a882772581af 100644 --- a/test/files/pos/t9020.scala +++ b/test/files/pos/t9020.scala @@ -1,4 +1,4 @@ -// scalac: -Ywarn-value-discard -Xfatal-warnings +//> using options -Ywarn-value-discard -Xfatal-warnings // trait ValueDiscard[@specialized U] { def u: U diff --git a/test/files/pos/t9107.scala b/test/files/pos/t9107.scala new file mode 100644 index 000000000000..827971d05444 --- /dev/null +++ b/test/files/pos/t9107.scala @@ -0,0 +1,12 @@ +//> using options -Werror -deprecation + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +class qqq(count: Int) { + def macroTransform(annottees: Any*): Any = macro qqq.qqqImpl +} + +object qqq { + def qqqImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = ??? +} diff --git a/test/files/pos/t9111-inliner-workaround/Test_1.scala b/test/files/pos/t9111-inliner-workaround/Test_1.scala index dd9a7074be57..d8124076edc8 100644 --- a/test/files/pos/t9111-inliner-workaround/Test_1.scala +++ b/test/files/pos/t9111-inliner-workaround/Test_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt // object Test extends App { println(new A_1.Inner()) diff --git a/test/files/pos/t9211.scala b/test/files/pos/t9211.scala new file mode 100644 index 000000000000..5250effd8dea --- /dev/null +++ b/test/files/pos/t9211.scala @@ -0,0 +1,9 @@ +//> using options -Werror -Xlint + +trait T[A] +class C extends T[Any] + +class Test { + def f[A](t: T[A]) = () + def g() = f(new C) +} diff --git a/test/files/pos/t9220.scala b/test/files/pos/t9220.scala index fc09b9a259ad..660791b6f940 100644 --- a/test/files/pos/t9220.scala +++ b/test/files/pos/t9220.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { trait Command diff --git a/test/files/pos/t9285.scala b/test/files/pos/t9285.scala index c9c17cbc1ea9..03e3f0e1691b 100644 --- a/test/files/pos/t9285.scala +++ b/test/files/pos/t9285.scala @@ -1,3 +1,3 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // case class C(placeholder: Unit) diff --git a/test/files/pos/t9369.scala b/test/files/pos/t9369.scala index 2e31eb31f247..15ecc7103216 100644 --- a/test/files/pos/t9369.scala +++ b/test/files/pos/t9369.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test { diff --git a/test/files/pos/t9370/sample_2.scala b/test/files/pos/t9370/sample_2.scala index 8326f3ad9e03..70ae0156aafc 100644 --- a/test/files/pos/t9370/sample_2.scala +++ b/test/files/pos/t9370/sample_2.scala @@ -1,5 +1,5 @@ -// scalac: -Xplugin:/tmp-fake -Xplugin:. -Xplugin-require:timebomb -Ystop-after:parser +//> using options -Xplugin:/tmp-fake -Xplugin:. -Xplugin-require:timebomb -Ystop-after:parser // package sample diff --git a/test/files/pos/t9399.scala b/test/files/pos/t9399.scala index 8de485baa44e..537717ed1df4 100644 --- a/test/files/pos/t9399.scala +++ b/test/files/pos/t9399.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed abstract class TA sealed abstract class TB extends TA diff --git a/test/files/pos/t9411a.scala b/test/files/pos/t9411a.scala index 9679150d5186..b28d5e17871b 100644 --- a/test/files/pos/t9411a.scala +++ b/test/files/pos/t9411a.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object OhNoes { diff --git a/test/files/pos/t9411b.scala b/test/files/pos/t9411b.scala index d15423705b26..77714d038e16 100644 --- a/test/files/pos/t9411b.scala +++ b/test/files/pos/t9411b.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object OhNoes { diff --git a/test/files/pos/t9490.scala b/test/files/pos/t9490.scala index e874724d092b..a7975257ec4c 100644 --- a/test/files/pos/t9490.scala +++ b/test/files/pos/t9490.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:inaccessible +//> using options -Werror -Xlint:inaccessible package ws { private[ws] trait Foo diff --git a/test/files/pos/t9630/t9630b.scala b/test/files/pos/t9630/t9630b.scala index fcd0f5ffc32c..980615abf6a4 100644 --- a/test/files/pos/t9630/t9630b.scala +++ b/test/files/pos/t9630/t9630b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror class Test { def test(b: Base): Unit = b match { case Base_1(Some(_)) => diff --git a/test/files/pos/t9657.scala b/test/files/pos/t9657.scala index eb51a41b0f37..27aa7587a5e4 100644 --- a/test/files/pos/t9657.scala +++ b/test/files/pos/t9657.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror sealed trait PowerSource case object Petrol extends PowerSource case object Pedal extends PowerSource diff --git a/test/files/pos/t9717.scala b/test/files/pos/t9717.scala index 50cb30f0b0a4..fe3b72f9bb3e 100644 --- a/test/files/pos/t9717.scala +++ b/test/files/pos/t9717.scala @@ -1,4 +1,4 @@ -// scalac: -Yno-predef +//> using options -Yno-predef import scala.Predef.implicitly diff --git a/test/files/pos/unchecked-a.scala b/test/files/pos/unchecked-a.scala index 8bcc299c1dcb..d208f98df25e 100644 --- a/test/files/pos/unchecked-a.scala +++ b/test/files/pos/unchecked-a.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait Y trait Z extends Y diff --git a/test/files/pos/unsafe.scala b/test/files/pos/unsafe.scala index 97d769791f77..cbdf7ed218a7 100644 --- a/test/files/pos/unsafe.scala +++ b/test/files/pos/unsafe.scala @@ -1,5 +1,5 @@ -// scalac: --release:8 -Yrelease:sun.misc +//> using options --release:8 -Yrelease:sun.misc import sun.misc.Unsafe diff --git a/test/files/pos/value-class-override-no-spec.scala b/test/files/pos/value-class-override-no-spec.scala index a073503c4cd0..842418aefcd3 100644 --- a/test/files/pos/value-class-override-no-spec.scala +++ b/test/files/pos/value-class-override-no-spec.scala @@ -1,4 +1,4 @@ -// scalac: -no-specialization +//> using options -no-specialization // // There are two versions of this tests: one with and one without specialization. // The bug was only exposed *without* specialization. diff --git a/test/files/pos/varargs-future.scala b/test/files/pos/varargs-future.scala index 8b8c414b47b0..2f60b213e44d 100644 --- a/test/files/pos/varargs-future.scala +++ b/test/files/pos/varargs-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // class Test { diff --git a/test/files/pos/variant-placeholders-future.scala b/test/files/pos/variant-placeholders-future.scala index 383db8420f85..74dcc177c039 100644 --- a/test/files/pos/variant-placeholders-future.scala +++ b/test/files/pos/variant-placeholders-future.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:3 +//> using options -Xsource:3 // object Test { type `-_` = Int diff --git a/test/files/pos/virtpatmat_exhaust_unchecked.scala b/test/files/pos/virtpatmat_exhaust_unchecked.scala index 4e08038803e6..fb0a5efb0529 100644 --- a/test/files/pos/virtpatmat_exhaust_unchecked.scala +++ b/test/files/pos/virtpatmat_exhaust_unchecked.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait Option {} case class Choice(a: Option, b: Option) extends Option; diff --git a/test/files/pos/warn-unused-params-not-implicits.scala b/test/files/pos/warn-unused-params-not-implicits.scala index 4be45127b5e6..f8fa369d2ea5 100644 --- a/test/files/pos/warn-unused-params-not-implicits.scala +++ b/test/files/pos/warn-unused-params-not-implicits.scala @@ -1,4 +1,4 @@ -// scalac: -Ywarn-unused:params,-implicits -Xfatal-warnings +//> using options -Ywarn-unused:params,-implicits -Xfatal-warnings // trait InterFace { diff --git a/test/files/pos/xlint1.scala b/test/files/pos/xlint1.scala index 4d323c731cc6..4ac7706ba3c1 100644 --- a/test/files/pos/xlint1.scala +++ b/test/files/pos/xlint1.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Xfatal-warnings +//> using options -Xlint -Xfatal-warnings // package object foo { implicit class Bar[T](val x: T) extends AnyVal { diff --git a/test/files/pos/xml-attributes.scala b/test/files/pos/xml-attributes.scala index 715acf14a4df..dd50696fa01d 100644 --- a/test/files/pos/xml-attributes.scala +++ b/test/files/pos/xml-attributes.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-comments.scala b/test/files/pos/xml-comments.scala index 0ce2633ee7b4..a38dbe330acb 100644 --- a/test/files/pos/xml-comments.scala +++ b/test/files/pos/xml-comments.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-entityref.scala b/test/files/pos/xml-entityref.scala index 268cf860637b..1240dd5d7098 100644 --- a/test/files/pos/xml-entityref.scala +++ b/test/files/pos/xml-entityref.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-interpolation.scala b/test/files/pos/xml-interpolation.scala index 6230818a1edd..08a2081f3045 100644 --- a/test/files/pos/xml-interpolation.scala +++ b/test/files/pos/xml-interpolation.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-match.scala b/test/files/pos/xml-match.scala index 12a10e36fa18..ddc984aca46b 100644 --- a/test/files/pos/xml-match.scala +++ b/test/files/pos/xml-match.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { def bar(e: Elem) = e match { diff --git a/test/files/pos/xml-nodebuffer.scala b/test/files/pos/xml-nodebuffer.scala index a250636646ae..0aa3d97ada5d 100644 --- a/test/files/pos/xml-nodebuffer.scala +++ b/test/files/pos/xml-nodebuffer.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // import scala.xml.NodeBuffer diff --git a/test/files/pos/xml-ns-empty.scala b/test/files/pos/xml-ns-empty.scala index 4a3aa0c0231b..c74aa70dc4ab 100644 --- a/test/files/pos/xml-ns-empty.scala +++ b/test/files/pos/xml-ns-empty.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val n = diff --git a/test/files/pos/xml-ns-text.scala b/test/files/pos/xml-ns-text.scala index 8718e1ebf014..6eed98e900b2 100644 --- a/test/files/pos/xml-ns-text.scala +++ b/test/files/pos/xml-ns-text.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val xml = diff --git a/test/files/pos/xml-ns.scala b/test/files/pos/xml-ns.scala index 71f90143cc43..092b06d894e9 100644 --- a/test/files/pos/xml-ns.scala +++ b/test/files/pos/xml-ns.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-pcdata.scala b/test/files/pos/xml-pcdata.scala index d2e00e249a7b..f657e2d4166f 100644 --- a/test/files/pos/xml-pcdata.scala +++ b/test/files/pos/xml-pcdata.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-procinstr.scala b/test/files/pos/xml-procinstr.scala index 108ba8dc0c28..254de36885be 100644 --- a/test/files/pos/xml-procinstr.scala +++ b/test/files/pos/xml-procinstr.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val bar = "baz" diff --git a/test/files/pos/xml-quasiquote.scala b/test/files/pos/xml-quasiquote.scala index 203d997e3edc..624a03cd74e9 100644 --- a/test/files/pos/xml-quasiquote.scala +++ b/test/files/pos/xml-quasiquote.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:typer +//> using options -Ystop-after:typer // import reflect.runtime.universe._ diff --git a/test/files/pos/xml-xmlns.scala b/test/files/pos/xml-xmlns.scala index 75d42f242b86..58c552283698 100644 --- a/test/files/pos/xml-xmlns.scala +++ b/test/files/pos/xml-xmlns.scala @@ -1,4 +1,4 @@ -// scalac: -Ystop-after:parser +//> using options -Ystop-after:parser // object foo { val html = diff --git a/test/files/pos/yimports-pkgobj/C_2.scala b/test/files/pos/yimports-pkgobj/C_2.scala index b0a418a6c69f..7f8c8bdaa3ed 100644 --- a/test/files/pos/yimports-pkgobj/C_2.scala +++ b/test/files/pos/yimports-pkgobj/C_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala,scala.Predef,hello.world +//> using options -Yimports:scala,scala.Predef,hello.world // import hello.world.{Numb => _, _} // no effect, world isPackage diff --git a/test/files/pos/yimports-pkgobj/minidef_1.scala b/test/files/pos/yimports-pkgobj/minidef_1.scala index 1681f4b62312..c0107f57d958 100644 --- a/test/files/pos/yimports-pkgobj/minidef_1.scala +++ b/test/files/pos/yimports-pkgobj/minidef_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yimports:scala +//> using options -Yimports:scala // package hello diff --git a/test/files/pos/z1730.scala b/test/files/pos/z1730.scala index e4dcb8727f70..35adc7834684 100644 --- a/test/files/pos/z1730.scala +++ b/test/files/pos/z1730.scala @@ -1,4 +1,4 @@ -// scalac: -Ycheck:_ +//> using options -Ycheck:_ // // /scala/trac/z1730/a.scala // Wed May 23 07:41:25 PDT 2012 diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check index a0640935e9fb..8fc5a7dbaa03 100644 --- a/test/files/presentation/callcc-interpreter.check +++ b/test/files/presentation/callcc-interpreter.check @@ -3,7 +3,11 @@ reload: CallccInterpreter.scala askTypeCompletion at CallccInterpreter.scala(51,34) ================================================================================ [response] askTypeCompletion at (51,34) -retrieved 66 members +retrieved 70 members +[inaccessible] private[this] val self: callccInterpreter.type +[inaccessible] private[this] val self: callccInterpreter.type +[inaccessible] private[this] val self: callccInterpreter.type +[inaccessible] private[this] val self: callccInterpreter.type abstract trait Term extends AnyRef abstract trait Value extends AnyRef case class Add extends callccInterpreter.Term with Product with Serializable diff --git a/test/files/presentation/doc/doc.scala b/test/files/presentation/doc/doc.scala index 2051bad03ebb..761bcd9c96d3 100644 --- a/test/files/presentation/doc/doc.scala +++ b/test/files/presentation/doc/doc.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror import scala.reflect.internal.util.{ BatchSourceFile, SourceFile } import scala.tools.nsc.doc import scala.tools.nsc.doc.base._ diff --git a/test/files/presentation/dollar-completion.check b/test/files/presentation/dollar-completion.check new file mode 100644 index 000000000000..95e5fddaf92d --- /dev/null +++ b/test/files/presentation/dollar-completion.check @@ -0,0 +1,47 @@ +reload: Completions.scala + +askScopeCompletion at Completions.scala(5,2) +================================================================================ +[response] askScopeCompletion at (5,2) +retrieved 16 members +abstract trait T extends AnyRef +case class C1 extends Product with Serializable +class C2 extends AnyRef +def (x: Int): test.C1 +def canEqual(x$1: Any): Boolean +def copy(x: Int): test.C1 +def productArity: Int +def productElement(x$1: Int): Any +object C1 +override def equals(x$1: Any): Boolean +override def hashCode(): Int +override def productElementName(x$1: Int): String +override def productIterator: Iterator[Any] +override def productPrefix: String +override def toString(): String +private[this] val x: Int +================================================================================ + +askScopeCompletion at Completions.scala(12,2) +================================================================================ +[response] askScopeCompletion at (12,2) +retrieved 4 members +abstract trait T extends AnyRef +case class C1 extends Product with Serializable +class C2 extends AnyRef +object C1 +================================================================================ + +askScopeCompletion at Completions.scala(21,2) +================================================================================ +[response] askScopeCompletion at (21,2) +retrieved 8 members +abstract trait T extends AnyRef +case class C1 extends Product with Serializable +class C2 extends AnyRef +def $: Int +def $var: Int +def (): test.C2 +def dollar$: Int +object C1 +================================================================================ diff --git a/test/files/presentation/dollar-completion/Test.scala b/test/files/presentation/dollar-completion/Test.scala new file mode 100644 index 000000000000..14a6aa835064 --- /dev/null +++ b/test/files/presentation/dollar-completion/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest diff --git a/test/files/presentation/dollar-completion/src/Completions.scala b/test/files/presentation/dollar-completion/src/Completions.scala new file mode 100644 index 000000000000..e82a0bdd859a --- /dev/null +++ b/test/files/presentation/dollar-completion/src/Completions.scala @@ -0,0 +1,22 @@ +package test + +case class C1(x: Int) { + // Filter out `def copy$default$1: Int` + /*_*/ +} + +trait T { + println("hello") + + // Filter out `$init$` + /*_*/ +} + +class C2 { + def `$` = 1 + def `dollar$` = 2 + def `$var` = 3 + + // Include explicit dollar methods + /*_*/ +} diff --git a/test/files/presentation/higher-order-completion.check b/test/files/presentation/higher-order-completion.check new file mode 100644 index 000000000000..2a963af4ff13 --- /dev/null +++ b/test/files/presentation/higher-order-completion.check @@ -0,0 +1,153 @@ +reload: Completions.scala + +askTypeCompletion at Completions.scala(12,14) +================================================================================ +[response] askTypeCompletion at (12,14) +retrieved 35 members +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] protected[package lang] def clone(): Object +[inaccessible] protected[package lang] def finalize(): Unit +def +(other: String): String +def ->[B](y: B): (test.Foo, B) +def Bar: Double +def Baz: Double +def ensuring(cond: Boolean): test.Foo +def ensuring(cond: Boolean, msg: => Any): test.Foo +def ensuring(cond: test.Foo => Boolean): test.Foo +def ensuring(cond: test.Foo => Boolean, msg: => Any): test.Foo +def equals(x$1: Object): Boolean +def formatted(fmtstr: String): String +def hashCode(): Int +def toString(): String +def →[B](y: B): (test.Foo, B) +final def !=(x$1: Any): Boolean +final def ## : Int +final def ==(x$1: Any): Boolean +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long, x$2: Int): Unit +================================================================================ + +askTypeCompletion at Completions.scala(15,13) +================================================================================ +[response] askTypeCompletion at (15,13) +retrieved 35 members +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] protected[package lang] def clone(): Object +[inaccessible] protected[package lang] def finalize(): Unit +def +(other: String): String +def ->[B](y: B): (test.Foo, B) +def Bar: Double +def Baz: Double +def ensuring(cond: Boolean): test.Foo +def ensuring(cond: Boolean, msg: => Any): test.Foo +def ensuring(cond: test.Foo => Boolean): test.Foo +def ensuring(cond: test.Foo => Boolean, msg: => Any): test.Foo +def equals(x$1: Object): Boolean +def formatted(fmtstr: String): String +def hashCode(): Int +def toString(): String +def →[B](y: B): (test.Foo, B) +final def !=(x$1: Any): Boolean +final def ## : Int +final def ==(x$1: Any): Boolean +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long, x$2: Int): Unit +================================================================================ + +askTypeCompletion at Completions.scala(18,17) +================================================================================ +[response] askTypeCompletion at (18,17) +retrieved 35 members +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] protected[package lang] def clone(): Object +[inaccessible] protected[package lang] def finalize(): Unit +def +(other: String): String +def ->[B](y: B): (test.Foo, B) +def Bar: Double +def Baz: Double +def ensuring(cond: Boolean): test.Foo +def ensuring(cond: Boolean, msg: => Any): test.Foo +def ensuring(cond: test.Foo => Boolean): test.Foo +def ensuring(cond: test.Foo => Boolean, msg: => Any): test.Foo +def equals(x$1: Object): Boolean +def formatted(fmtstr: String): String +def hashCode(): Int +def toString(): String +def →[B](y: B): (test.Foo, B) +final def !=(x$1: Any): Boolean +final def ## : Int +final def ==(x$1: Any): Boolean +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long, x$2: Int): Unit +================================================================================ + +askTypeCompletion at Completions.scala(21,24) +================================================================================ +[response] askTypeCompletion at (21,24) +retrieved 35 members +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] private[this] val self: test.Foo +[inaccessible] protected[package lang] def clone(): Object +[inaccessible] protected[package lang] def finalize(): Unit +def +(other: String): String +def ->[B](y: B): (test.Foo, B) +def Bar: Double +def Baz: Double +def ensuring(cond: Boolean): test.Foo +def ensuring(cond: Boolean, msg: => Any): test.Foo +def ensuring(cond: test.Foo => Boolean): test.Foo +def ensuring(cond: test.Foo => Boolean, msg: => Any): test.Foo +def equals(x$1: Object): Boolean +def formatted(fmtstr: String): String +def hashCode(): Int +def toString(): String +def →[B](y: B): (test.Foo, B) +final def !=(x$1: Any): Boolean +final def ## : Int +final def ==(x$1: Any): Boolean +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long, x$2: Int): Unit +================================================================================ diff --git a/test/files/presentation/higher-order-completion/Test.scala b/test/files/presentation/higher-order-completion/Test.scala new file mode 100644 index 000000000000..14a6aa835064 --- /dev/null +++ b/test/files/presentation/higher-order-completion/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest diff --git a/test/files/presentation/higher-order-completion/src/Completions.scala b/test/files/presentation/higher-order-completion/src/Completions.scala new file mode 100644 index 000000000000..afb423d3a1af --- /dev/null +++ b/test/files/presentation/higher-order-completion/src/Completions.scala @@ -0,0 +1,22 @@ +package test + +/* check that members are visible when completing inside an Apply with insufficient args */ + +class Foo { + def Bar: Double = 2.0 + def Baz: Double = 1.0 +} + +class Completion1 { + def singleArg(f: Foo => Double): Nothing = ??? + singleArg(_./*!*/) + + def multiArg(f: Foo => Double, s: String): Nothing = ??? + multiArg(_./*!*/) // importantly we want to see Bar and Baz as completions here + + def multiArgFull(f: Foo => Double, s: String): Nothing = ??? + multiArgFull(_./*!*/,???) + + def multiArgWithDefault(f: Foo => Double, s: String = "hello"): Nothing = ??? + multiArgWithDefault(_./*!*/) +} diff --git a/test/files/presentation/ide-bug-1000349.check b/test/files/presentation/ide-bug-1000349.check index cb3f5f12b773..c57099342e29 100644 --- a/test/files/presentation/ide-bug-1000349.check +++ b/test/files/presentation/ide-bug-1000349.check @@ -3,7 +3,11 @@ reload: CompletionOnEmptyArgMethod.scala askTypeCompletion at CompletionOnEmptyArgMethod.scala(2,17) ================================================================================ [response] askTypeCompletion at (2,17) -retrieved 30 members +retrieved 34 members +[inaccessible] private[this] val self: Foo +[inaccessible] private[this] val self: Foo +[inaccessible] private[this] val self: Foo +[inaccessible] private[this] val self: Foo def +(other: String): String def ->[B](y: B): (Foo, B) def ensuring(cond: Boolean): Foo diff --git a/test/files/presentation/ide-bug-1000475.check b/test/files/presentation/ide-bug-1000475.check index 2cd22c0d5d56..d9a785ea7476 100644 --- a/test/files/presentation/ide-bug-1000475.check +++ b/test/files/presentation/ide-bug-1000475.check @@ -3,7 +3,11 @@ reload: Foo.scala askTypeCompletion at Foo.scala(3,7) ================================================================================ [response] askTypeCompletion at (3,7) -retrieved 29 members +retrieved 33 members +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit def +(other: String): String @@ -35,7 +39,11 @@ final def wait(x$1: Long, x$2: Int): Unit askTypeCompletion at Foo.scala(6,10) ================================================================================ [response] askTypeCompletion at (6,10) -retrieved 29 members +retrieved 33 members +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit def +(other: String): String @@ -67,7 +75,11 @@ final def wait(x$1: Long, x$2: Int): Unit askTypeCompletion at Foo.scala(7,7) ================================================================================ [response] askTypeCompletion at (7,7) -retrieved 29 members +retrieved 33 members +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object +[inaccessible] private[this] val self: Object [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit def +(other: String): String diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check index 5812b9fbe42d..5569188c1252 100644 --- a/test/files/presentation/ide-bug-1000531.check +++ b/test/files/presentation/ide-bug-1000531.check @@ -3,7 +3,11 @@ reload: CrashOnLoad.scala, TestIterable.java askTypeCompletion at CrashOnLoad.scala(9,11) ================================================================================ [response] askTypeCompletion at (9,11) -retrieved 30 members +retrieved 34 members +[inaccessible] private[this] val self: other.TestIterator[Nothing] +[inaccessible] private[this] val self: other.TestIterator[Nothing] +[inaccessible] private[this] val self: other.TestIterator[Nothing] +[inaccessible] private[this] val self: other.TestIterator[Nothing] [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit def +(other: String): String diff --git a/test/files/presentation/implicit-member.check b/test/files/presentation/implicit-member.check index a6989f5f87ba..4fe2b05ebeb6 100644 --- a/test/files/presentation/implicit-member.check +++ b/test/files/presentation/implicit-member.check @@ -3,7 +3,11 @@ reload: ImplicitMember.scala askTypeCompletion at ImplicitMember.scala(7,7) ================================================================================ [response] askTypeCompletion at (7,7) -retrieved 32 members +retrieved 36 members +[inaccessible] private[this] val self: Implicit.type +[inaccessible] private[this] val self: Implicit.type +[inaccessible] private[this] val self: Implicit.type +[inaccessible] private[this] val self: Implicit.type def +(other: String): String def ->[B](y: B): (Implicit.type, B) def ensuring(cond: Boolean): Implicit.type diff --git a/test/files/presentation/infix-completion.check b/test/files/presentation/infix-completion.check index a6549c83911b..ad4aa0cd6c79 100644 --- a/test/files/presentation/infix-completion.check +++ b/test/files/presentation/infix-completion.check @@ -4,10 +4,14 @@ askTypeCompletion at Snippet.scala(1,34) ================================================================================ [response] askTypeCompletion at (1,34) #partest !java15+ -retrieved 203 members +retrieved 207 members #partest java15+ -retrieved 205 members +retrieved 209 members #partest +[inaccessible] private[this] val self: Int +[inaccessible] private[this] val self: Int +[inaccessible] private[this] val self: Int +[inaccessible] private[this] val self: Int [inaccessible] protected def num: Fractional[Double] [inaccessible] protected def ord: Ordering[Double] [inaccessible] protected def unifiedPrimitiveEquals(x: Any): Boolean diff --git a/test/files/presentation/infix-completion2.check b/test/files/presentation/infix-completion2.check index a6549c83911b..ad4aa0cd6c79 100644 --- a/test/files/presentation/infix-completion2.check +++ b/test/files/presentation/infix-completion2.check @@ -4,10 +4,14 @@ askTypeCompletion at Snippet.scala(1,34) ================================================================================ [response] askTypeCompletion at (1,34) #partest !java15+ -retrieved 203 members +retrieved 207 members #partest java15+ -retrieved 205 members +retrieved 209 members #partest +[inaccessible] private[this] val self: Int +[inaccessible] private[this] val self: Int +[inaccessible] private[this] val self: Int +[inaccessible] private[this] val self: Int [inaccessible] protected def num: Fractional[Double] [inaccessible] protected def ord: Ordering[Double] [inaccessible] protected def unifiedPrimitiveEquals(x: Any): Boolean diff --git a/test/files/presentation/package-object-issues.check b/test/files/presentation/package-object-issues.check new file mode 100644 index 000000000000..c3f750f0b7f8 --- /dev/null +++ b/test/files/presentation/package-object-issues.check @@ -0,0 +1,42 @@ +reload: Main.scala + +askTypeCompletion at Main.scala(7,6) +================================================================================ +[response] askTypeCompletion at (7,6) +def +(other: String): String +def ->[B](y: B): (concurrent.ExecutionException, B) +def ensuring(cond: Boolean): concurrent.ExecutionException +def ensuring(cond: Boolean, msg: => Any): concurrent.ExecutionException +def ensuring(cond: concurrent.ExecutionException => Boolean): concurrent.ExecutionException +def ensuring(cond: concurrent.ExecutionException => Boolean, msg: => Any): concurrent.ExecutionException +def equals(x$1: Object): Boolean +def fillInStackTrace(): Throwable +def formatted(fmtstr: String): String +def getCause(): Throwable +def getLocalizedMessage(): String +def getMessage(): String +def getStackTrace(): Array[StackTraceElement] +def hashCode(): Int +def initCause(x$1: Throwable): Throwable +def printStackTrace(): Unit +def printStackTrace(x$1: java.io.PrintStream): Unit +def printStackTrace(x$1: java.io.PrintWriter): Unit +def setStackTrace(x$1: Array[StackTraceElement]): Unit +def toString(): String +def →[B](y: B): (concurrent.ExecutionException, B) +final def !=(x$1: Any): Boolean +final def ## : Int +final def ==(x$1: Any): Boolean +final def addSuppressed(x$1: Throwable): Unit +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def getSuppressed(): Array[Throwable] +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long, x$2: Int): Unit +================================================================================ diff --git a/test/files/presentation/package-object-issues/Test.scala b/test/files/presentation/package-object-issues/Test.scala new file mode 100644 index 000000000000..75c2533dd923 --- /dev/null +++ b/test/files/presentation/package-object-issues/Test.scala @@ -0,0 +1,8 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest { + + override protected def filterOutLines(line: String) = + line.contains("inaccessible") || line.contains("retrieved ") + +} diff --git a/test/files/presentation/package-object-issues/src/Main.scala b/test/files/presentation/package-object-issues/src/Main.scala new file mode 100644 index 000000000000..8c0f481c0ac0 --- /dev/null +++ b/test/files/presentation/package-object-issues/src/Main.scala @@ -0,0 +1,10 @@ +package scala.concurrent + +import scala.concurrent.ExecutionException + +object Main extends App { + def foo(n: ExecutionException, k: Int): Unit = { + n./*!*/ + k + } +} diff --git a/test/files/presentation/package-object-type.check b/test/files/presentation/package-object-type.check new file mode 100644 index 000000000000..c3f750f0b7f8 --- /dev/null +++ b/test/files/presentation/package-object-type.check @@ -0,0 +1,42 @@ +reload: Main.scala + +askTypeCompletion at Main.scala(7,6) +================================================================================ +[response] askTypeCompletion at (7,6) +def +(other: String): String +def ->[B](y: B): (concurrent.ExecutionException, B) +def ensuring(cond: Boolean): concurrent.ExecutionException +def ensuring(cond: Boolean, msg: => Any): concurrent.ExecutionException +def ensuring(cond: concurrent.ExecutionException => Boolean): concurrent.ExecutionException +def ensuring(cond: concurrent.ExecutionException => Boolean, msg: => Any): concurrent.ExecutionException +def equals(x$1: Object): Boolean +def fillInStackTrace(): Throwable +def formatted(fmtstr: String): String +def getCause(): Throwable +def getLocalizedMessage(): String +def getMessage(): String +def getStackTrace(): Array[StackTraceElement] +def hashCode(): Int +def initCause(x$1: Throwable): Throwable +def printStackTrace(): Unit +def printStackTrace(x$1: java.io.PrintStream): Unit +def printStackTrace(x$1: java.io.PrintWriter): Unit +def setStackTrace(x$1: Array[StackTraceElement]): Unit +def toString(): String +def →[B](y: B): (concurrent.ExecutionException, B) +final def !=(x$1: Any): Boolean +final def ## : Int +final def ==(x$1: Any): Boolean +final def addSuppressed(x$1: Throwable): Unit +final def asInstanceOf[T0]: T0 +final def eq(x$1: AnyRef): Boolean +final def getSuppressed(): Array[Throwable] +final def isInstanceOf[T0]: Boolean +final def ne(x$1: AnyRef): Boolean +final def notify(): Unit +final def notifyAll(): Unit +final def synchronized[T0](x$1: T0): T0 +final def wait(): Unit +final def wait(x$1: Long): Unit +final def wait(x$1: Long, x$2: Int): Unit +================================================================================ diff --git a/test/files/presentation/package-object-type/Test.scala b/test/files/presentation/package-object-type/Test.scala new file mode 100644 index 000000000000..b06e25d8dd1c --- /dev/null +++ b/test/files/presentation/package-object-type/Test.scala @@ -0,0 +1,9 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest +import scala.tools.nsc.util + +object Test extends InteractiveTest { + + override protected def filterOutLines(line: String) = + line.contains("inaccessible") || line.contains("retrieved ") + +} diff --git a/test/files/presentation/package-object-type/src/Main.scala b/test/files/presentation/package-object-type/src/Main.scala new file mode 100644 index 000000000000..493984f55654 --- /dev/null +++ b/test/files/presentation/package-object-type/src/Main.scala @@ -0,0 +1,10 @@ +package example + +import scala.concurrent.ExecutionException + +object Main extends App { + def foo(n: ExecutionException, k: Int): Unit = { + n./*!*/ + k + } +} diff --git a/test/files/presentation/ping-pong.check b/test/files/presentation/ping-pong.check index 58a63de475a4..b02cf1cec8e9 100644 --- a/test/files/presentation/ping-pong.check +++ b/test/files/presentation/ping-pong.check @@ -3,8 +3,12 @@ reload: PingPong.scala askTypeCompletion at PingPong.scala(10,31) ================================================================================ [response] askTypeCompletion at (10,31) -retrieved 32 members +retrieved 36 members [inaccessible] private[this] val ping: Ping +[inaccessible] private[this] val self: Pong +[inaccessible] private[this] val self: Pong +[inaccessible] private[this] val self: Pong +[inaccessible] private[this] val self: Pong [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit def +(other: String): String @@ -38,7 +42,11 @@ private[this] val name: String askTypeCompletion at PingPong.scala(19,28) ================================================================================ [response] askTypeCompletion at (19,28) -retrieved 33 members +retrieved 37 members +[inaccessible] private[this] val self: Ping +[inaccessible] private[this] val self: Ping +[inaccessible] private[this] val self: Ping +[inaccessible] private[this] val self: Ping [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit def +(other: String): String diff --git a/test/files/presentation/random/src/Random.scala b/test/files/presentation/random/src/Random.scala index a4514dbc2240..d4f7c2d5b348 100644 --- a/test/files/presentation/random/src/Random.scala +++ b/test/files/presentation/random/src/Random.scala @@ -63,8 +63,8 @@ object randomserver { } catch { case e: IOException => - System.err.println("Could not listen on port: 9999."); - System.exit(-1) + System.err.println("Could not listen on port: 9999.") + throw e } } diff --git a/test/files/presentation/t13083.check b/test/files/presentation/t13083.check new file mode 100644 index 000000000000..d4e3e7cc2a30 --- /dev/null +++ b/test/files/presentation/t13083.check @@ -0,0 +1,7 @@ +reload: CompleteLocalImport.scala + +askTypeCompletion at CompleteLocalImport.scala(2,14) +================================================================================ +[response] askTypeCompletion at (2,14) +retrieved 14 members +================================================================================ diff --git a/test/files/presentation/t13083/Runner.scala b/test/files/presentation/t13083/Runner.scala new file mode 100644 index 000000000000..13e63ea4ed7e --- /dev/null +++ b/test/files/presentation/t13083/Runner.scala @@ -0,0 +1,5 @@ +import scala.tools.nsc.interactive.tests._ + +object Test extends InteractiveTest { + override protected def filterOutLines(line: String) = line.contains("package") +} diff --git a/test/files/presentation/t13083/src/CompleteLocalImport.scala b/test/files/presentation/t13083/src/CompleteLocalImport.scala new file mode 100644 index 000000000000..6e5d3df40b76 --- /dev/null +++ b/test/files/presentation/t13083/src/CompleteLocalImport.scala @@ -0,0 +1,3 @@ +object Autocompletewrapper { + import java./*!*/ +} diff --git a/test/files/presentation/t5708.check b/test/files/presentation/t5708.check index 78a77673f013..81bbf4f386b7 100644 --- a/test/files/presentation/t5708.check +++ b/test/files/presentation/t5708.check @@ -3,10 +3,14 @@ reload: Completions.scala askTypeCompletion at Completions.scala(17,9) ================================================================================ [response] askTypeCompletion at (17,9) -retrieved 37 members +retrieved 41 members [inaccessible] private def privateM: String [inaccessible] private[this] val privateV: String [inaccessible] private[this] val protectedV: String +[inaccessible] private[this] val self: test.Compat.type +[inaccessible] private[this] val self: test.Compat.type +[inaccessible] private[this] val self: test.Compat.type +[inaccessible] private[this] val self: test.Compat.type [inaccessible] protected def protectedValM: String [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit diff --git a/test/files/presentation/visibility.check b/test/files/presentation/visibility.check index 0c628427a5b7..eb40acef3b3b 100644 --- a/test/files/presentation/visibility.check +++ b/test/files/presentation/visibility.check @@ -3,8 +3,12 @@ reload: Completions.scala askTypeCompletion at Completions.scala(14,12) ================================================================================ [response] askTypeCompletion at (14,12) -retrieved 35 members +retrieved 39 members [inaccessible] private[this] def secretPrivateThis(): Unit +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo def +(other: String): String def ->[B](y: B): (accessibility.Foo, B) def ensuring(cond: Boolean): accessibility.Foo @@ -41,7 +45,11 @@ protected[package lang] def finalize(): Unit askTypeCompletion at Completions.scala(16,11) ================================================================================ [response] askTypeCompletion at (16,11) -retrieved 35 members +retrieved 39 members +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo def +(other: String): String def ->[B](y: B): (accessibility.Foo, B) def ensuring(cond: Boolean): accessibility.Foo @@ -79,7 +87,11 @@ protected[package lang] def finalize(): Unit askTypeCompletion at Completions.scala(22,11) ================================================================================ [response] askTypeCompletion at (22,11) -retrieved 34 members +retrieved 38 members +[inaccessible] private[this] val self: accessibility.AccessibilityChecks +[inaccessible] private[this] val self: accessibility.AccessibilityChecks +[inaccessible] private[this] val self: accessibility.AccessibilityChecks +[inaccessible] private[this] val self: accessibility.AccessibilityChecks def +(other: String): String def ->[B](y: B): (accessibility.AccessibilityChecks, B) def ensuring(cond: Boolean): accessibility.AccessibilityChecks @@ -116,9 +128,13 @@ protected[package lang] def finalize(): Unit askTypeCompletion at Completions.scala(28,10) ================================================================================ [response] askTypeCompletion at (28,10) -retrieved 35 members +retrieved 39 members [inaccessible] private def secretPrivate(): Unit [inaccessible] private[this] def secretPrivateThis(): Unit +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo [inaccessible] protected def secretProtected(): Unit [inaccessible] protected[package lang] def clone(): Object [inaccessible] protected[package lang] def finalize(): Unit @@ -154,9 +170,13 @@ protected[package accessibility] def secretProtectedInPackage(): Unit askTypeCompletion at Completions.scala(37,8) ================================================================================ [response] askTypeCompletion at (37,8) -retrieved 35 members +retrieved 39 members [inaccessible] private def secretPrivate(): Unit [inaccessible] private[this] def secretPrivateThis(): Unit +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo +[inaccessible] private[this] val self: accessibility.Foo [inaccessible] protected def secretProtected(): Unit [inaccessible] protected[package accessibility] def secretProtectedInPackage(): Unit [inaccessible] protected[package lang] def clone(): Object diff --git a/test/files/run/StringConcat.scala b/test/files/run/StringConcat.scala index 568c3e68aa26..95c8026b6258 100644 --- a/test/files/run/StringConcat.scala +++ b/test/files/run/StringConcat.scala @@ -1,4 +1,4 @@ -// java: -Xss128M +//> using javaOpt -Xss128M import scala.tools.partest.ReplTest diff --git a/test/files/run/abstype_implicits.scala b/test/files/run/abstype_implicits.scala index 7187e6c7de61..7283f6fb4cac 100644 --- a/test/files/run/abstype_implicits.scala +++ b/test/files/run/abstype_implicits.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // trait Functor[F[_]] diff --git a/test/files/run/annot-infix-tostr.check b/test/files/run/annot-infix-tostr.check new file mode 100644 index 000000000000..2ff6d74fb48e --- /dev/null +++ b/test/files/run/annot-infix-tostr.check @@ -0,0 +1,20 @@ + +scala> class ann extends annotation.StaticAnnotation +class ann + +scala> def a: Int => (Int @ann) = ??? +def a: Int => Int @ann + +scala> def b: Int => Int @ann = ??? +def b: Int => Int @ann + +scala> def c: (Int => Int) @ann = ??? +def c: (Int => Int) @ann + +scala> def d: Int => (Int => Int) @ann = ??? +def d: Int => ((Int => Int) @ann) + +scala> def e: (Int => Int => Int) @ann = ??? +def e: (Int => (Int => Int)) @ann + +scala> :quit diff --git a/test/files/run/annot-infix-tostr.scala b/test/files/run/annot-infix-tostr.scala new file mode 100644 index 000000000000..1b5f4a41bd4e --- /dev/null +++ b/test/files/run/annot-infix-tostr.scala @@ -0,0 +1,12 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + |class ann extends annotation.StaticAnnotation + |def a: Int => (Int @ann) = ??? + |def b: Int => Int @ann = ??? + |def c: (Int => Int) @ann = ??? + |def d: Int => (Int => Int) @ann = ??? + |def e: (Int => Int => Int) @ann = ??? + |""".stripMargin +} diff --git a/test/files/run/applydynamic_sip.scala b/test/files/run/applydynamic_sip.scala index cb87dbe1fb79..cdc16ac7f5ac 100644 --- a/test/files/run/applydynamic_sip.scala +++ b/test/files/run/applydynamic_sip.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false -language:dynamics +//> using options -Yrangepos:false -language:dynamics // object Test extends App { object stubUpdate { diff --git a/test/files/run/bcodeInlinerMixed/B_1.scala b/test/files/run/bcodeInlinerMixed/B_1.scala index bb6cf8220962..c80ef4b69067 100644 --- a/test/files/run/bcodeInlinerMixed/B_1.scala +++ b/test/files/run/bcodeInlinerMixed/B_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // // Since 1.0.18, partest does mixed compilation only in two stages // 1. scalac *.scala *.java diff --git a/test/files/run/bcodeInlinerMixed/Test_2.scala b/test/files/run/bcodeInlinerMixed/Test_2.scala index fe0ee721a7b1..91a005185c11 100644 --- a/test/files/run/bcodeInlinerMixed/Test_2.scala +++ b/test/files/run/bcodeInlinerMixed/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // import scala.tools.partest.BytecodeTest import scala.tools.testkit.ASMConverters diff --git a/test/files/run/blank.scala b/test/files/run/blank.scala index 0a96ee5f5b49..9bb437490070 100644 --- a/test/files/run/blank.scala +++ b/test/files/run/blank.scala @@ -1,4 +1,4 @@ -// javaVersion: 11+ +//> using jvm 11+ // // skalac: --release:8 // trivial manual test for partest --realeasy, which sets --release:8. diff --git a/test/files/run/bridges.scala b/test/files/run/bridges.scala index de641f03f6b5..dfe7efad8b74 100644 --- a/test/files/run/bridges.scala +++ b/test/files/run/bridges.scala @@ -1,4 +1,4 @@ -// java: -Xss128M +//> using javaOpt -Xss128M //############################################################################ // Test bridge methods diff --git a/test/files/run/bugs.scala b/test/files/run/bugs.scala index b210946dbbdc..1ab3ec0aae1a 100644 --- a/test/files/run/bugs.scala +++ b/test/files/run/bugs.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // import annotation.unused diff --git a/test/files/run/caseClassHash.scala b/test/files/run/caseClassHash.scala index 34e140219076..af7c7b999ac5 100644 --- a/test/files/run/caseClassHash.scala +++ b/test/files/run/caseClassHash.scala @@ -11,8 +11,8 @@ object Test { println("## method 1: " + foo1.##) println("## method 2: " + foo2.##) - println(" Murmur 1: " + scala.util.hashing.MurmurHash3.productHash(foo1)) - println(" Murmur 2: " + scala.util.hashing.MurmurHash3.productHash(foo2)) + println(" Murmur 1: " + scala.util.hashing.MurmurHash3.caseClassHash(foo1)) + println(" Murmur 2: " + scala.util.hashing.MurmurHash3.caseClassHash(foo2)) } } diff --git a/test/files/run/checked.scala b/test/files/run/checked.scala index 4d814e9a48f6..a7352e859832 100644 --- a/test/files/run/checked.scala +++ b/test/files/run/checked.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit -nowarn +//> using options -Xcheckinit -nowarn // /* Test checked initializers. Needs to be run with -checkinit */ diff --git a/test/files/run/checkinit.scala b/test/files/run/checkinit.scala index 2a37f2eef63e..7d13bdb05bda 100644 --- a/test/files/run/checkinit.scala +++ b/test/files/run/checkinit.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // class C(val x: AnyRef, val y: AnyRef) class D(val x: AnyRef, val y: AnyRef) { diff --git a/test/files/run/contrib674.check b/test/files/run/contrib674.check index 7fcac8e06d44..491bb717fbb0 100644 --- a/test/files/run/contrib674.check +++ b/test/files/run/contrib674.check @@ -1,6 +1,3 @@ -contrib674.scala:15: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - 1 - ^ -contrib674.scala:15: warning: a pure expression does nothing in statement position +contrib674.scala:15: warning: discarded pure expression does nothing 1 ^ diff --git a/test/files/run/ctor-order.scala b/test/files/run/ctor-order.scala index 904dca107073..158eb320238f 100644 --- a/test/files/run/ctor-order.scala +++ b/test/files/run/ctor-order.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 0 +//> using options -Xmaxwarns 0 /** Test that constructor operations are reordered correctly. */ class Outer { diff --git a/test/files/run/deadlock.scala b/test/files/run/deadlock.scala new file mode 100644 index 000000000000..f3dc67244e03 --- /dev/null +++ b/test/files/run/deadlock.scala @@ -0,0 +1,18 @@ +object Test extends App { + val createPredef = new Runnable { + def run = { + val _ = Predef; + } + } + val createVector = new Runnable { + def run = { + val _ = scala.collection.immutable.Vector; + } + } + val t1 = new Thread(createPredef) + val t2 = new Thread(createVector) + t1.start() + t2.start() + t1.join() + t2.join() +} diff --git a/test/files/run/debug-type-error.scala b/test/files/run/debug-type-error.scala index 4a3e007a9d7d..2652815d6bdc 100644 --- a/test/files/run/debug-type-error.scala +++ b/test/files/run/debug-type-error.scala @@ -1,4 +1,4 @@ -// filter: (\s*)at(.*) +//> using filter (\s*)at(.*) import scala.tools.partest._ diff --git a/test/files/run/defaults-serizaliable-no-forwarders.scala b/test/files/run/defaults-serizaliable-no-forwarders.scala index f49f526daec0..0c77afda79c6 100644 --- a/test/files/run/defaults-serizaliable-no-forwarders.scala +++ b/test/files/run/defaults-serizaliable-no-forwarders.scala @@ -1,4 +1,4 @@ -// scalac: -Xmixin-force-forwarders:false +//> using options -Xmixin-force-forwarders:false import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream} diff --git a/test/files/run/delambdafy-dependent-on-param-subst.scala b/test/files/run/delambdafy-dependent-on-param-subst.scala index 68f3b44d0ecc..77985f6dd2d4 100644 --- a/test/files/run/delambdafy-dependent-on-param-subst.scala +++ b/test/files/run/delambdafy-dependent-on-param-subst.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method +//> using options -Ydelambdafy:method // trait M[-X] { def m(x: X): Boolean diff --git a/test/files/run/delay-bad.scala b/test/files/run/delay-bad.scala index fd32d9edf647..a743285791e3 100644 --- a/test/files/run/delay-bad.scala +++ b/test/files/run/delay-bad.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 0 +//> using options -Xmaxwarns 0 trait A extends DelayedInit { print("-A") diff --git a/test/files/run/delay-good.scala b/test/files/run/delay-good.scala index 5fe32194f412..5787db7b4b5f 100644 --- a/test/files/run/delay-good.scala +++ b/test/files/run/delay-good.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 0 +//> using options -Xmaxwarns 0 trait A { print("-A") diff --git a/test/files/run/deprecate-early-type-defs.scala b/test/files/run/deprecate-early-type-defs.scala index 8636e1d140f5..cc0a32bf18a8 100644 --- a/test/files/run/deprecate-early-type-defs.scala +++ b/test/files/run/deprecate-early-type-defs.scala @@ -1,3 +1,3 @@ -// scalac: -deprecation +//> using options -deprecation // object Test extends { type T = Int } with App diff --git a/test/files/run/disable-assertions.scala b/test/files/run/disable-assertions.scala index 3d77ce4fc92d..e00efd00e71e 100644 --- a/test/files/run/disable-assertions.scala +++ b/test/files/run/disable-assertions.scala @@ -1,4 +1,4 @@ -// scalac: -Xdisable-assertions +//> using options -Xdisable-assertions // object Elided { diff --git a/test/files/run/dotty-i11332b.scala b/test/files/run/dotty-i11332b.scala index 2627029541fa..cf6374fc56ea 100644 --- a/test/files/run/dotty-i11332b.scala +++ b/test/files/run/dotty-i11332b.scala @@ -1,5 +1,5 @@ -// javaVersion: 11+ -// scalac: -release:11 +//> using jvm 11+ +//> using options -release:11 import java.lang.invoke._, MethodType.methodType diff --git a/test/files/run/dotty-t12348.scala b/test/files/run/dotty-t12348.scala index b655da3012dc..93cc39c7bd51 100644 --- a/test/files/run/dotty-t12348.scala +++ b/test/files/run/dotty-t12348.scala @@ -1,5 +1,5 @@ -// javaVersion: 11+ -// scalac: -release:11 +//> using jvm 11+ +//> using options -release:11 import java.lang.invoke._ import scala.runtime.IntRef diff --git a/test/files/run/dynamic-applyDynamic.scala b/test/files/run/dynamic-applyDynamic.scala index 25a7cf1dcfeb..d6c6e8190ca6 100644 --- a/test/files/run/dynamic-applyDynamic.scala +++ b/test/files/run/dynamic-applyDynamic.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:typer -Yrangepos -Ystop-after:typer -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:typer -Ystop-after:typer -cp ${testOutput.path}" override def code = """ object X { diff --git a/test/files/run/dynamic-applyDynamicNamed.scala b/test/files/run/dynamic-applyDynamicNamed.scala index d5185476ba1b..f48003acc735 100644 --- a/test/files/run/dynamic-applyDynamicNamed.scala +++ b/test/files/run/dynamic-applyDynamicNamed.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:typer -Yrangepos -Ystop-after:typer -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:typer -Ystop-after:typer -cp ${testOutput.path}" override def code = """ object X { diff --git a/test/files/run/dynamic-selectDynamic.scala b/test/files/run/dynamic-selectDynamic.scala index 8383c1f45823..061dd5055810 100644 --- a/test/files/run/dynamic-selectDynamic.scala +++ b/test/files/run/dynamic-selectDynamic.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:typer -Yrangepos -Ystop-after:typer -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:typer -Ystop-after:typer -cp ${testOutput.path}" override def code = """ object X { diff --git a/test/files/run/dynamic-updateDynamic.scala b/test/files/run/dynamic-updateDynamic.scala index 0c5914b61604..c44d7704e89c 100644 --- a/test/files/run/dynamic-updateDynamic.scala +++ b/test/files/run/dynamic-updateDynamic.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:typer -Yrangepos -Ystop-after:typer -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:typer -Ystop-after:typer -cp ${testOutput.path}" override def code = """ object X { diff --git a/test/files/run/elidable-opt.scala b/test/files/run/elidable-opt.scala index 672a1ab41035..efed09bd5af6 100644 --- a/test/files/run/elidable-opt.scala +++ b/test/files/run/elidable-opt.scala @@ -1,4 +1,4 @@ -// scalac: -Xelide-below 900 -deprecation -Xmaxwarns 0 +//> using options -Xelide-below 900 -deprecation -Xmaxwarns 0 // import annotation._ import elidable._ diff --git a/test/files/run/elidable.scala b/test/files/run/elidable.scala index 2a9edffd7057..1daa6a8acff3 100644 --- a/test/files/run/elidable.scala +++ b/test/files/run/elidable.scala @@ -1,4 +1,4 @@ -// scalac: -Xelide-below WARNING -deprecation +//> using options -Xelide-below WARNING -deprecation // import annotation._ import elidable._ diff --git a/test/files/run/existential-rangepos.scala b/test/files/run/existential-rangepos.scala index d31a5e754f53..e9493b8d175f 100644 --- a/test/files/run/existential-rangepos.scala +++ b/test/files/run/existential-rangepos.scala @@ -1,7 +1,7 @@ import scala.tools.partest._ object Test extends DirectTest { - override def extraSettings: String = "-usejavacp -Yrangepos -Vprint:patmat -Vprint-pos" + override def extraSettings: String = "-usejavacp -Vprint:patmat -Vprint-pos" override def code = """ abstract class A[T] { diff --git a/test/files/run/f-interpolator-unit.scala b/test/files/run/f-interpolator-unit.scala index dddf7411a3fc..68be88da51a2 100644 --- a/test/files/run/f-interpolator-unit.scala +++ b/test/files/run/f-interpolator-unit.scala @@ -33,7 +33,7 @@ object Test extends App { final val tester = "hello" final val number = "42" // strings only, alas - def assertEquals(s0: String, s1: String) = assert(s0 == s1, s"$s0 == $s1") + def assertEquals(s0: String, s1: String, i: Int = -1) = assert(s0 == s1, s"$s0 == $s1${if (i >= 0) " at " + i.toString else ""}") def noEscape() = { val s = "string" @@ -134,7 +134,7 @@ object Test extends App { f"${null}%b" -> "false", f"${false}%b" -> "false", f"${true}%b" -> "true", - f"${true && false}%b" -> "false", + f"${true && false}%b" -> "false", f"${java.lang.Boolean.valueOf(false)}%b" -> "false", f"${java.lang.Boolean.valueOf(true)}%b" -> "true", @@ -255,7 +255,7 @@ object Test extends App { f"z" -> "z" ) - for ((f, s) <- ss) assertEquals(s, f) + for (((f, s), i) <- ss.zipWithIndex) assertEquals(s, f, i) } noEscape() diff --git a/test/files/run/fail-non-value-types.scala b/test/files/run/fail-non-value-types.scala index 8baeb6856c0a..d140558c9916 100644 --- a/test/files/run/fail-non-value-types.scala +++ b/test/files/run/fail-non-value-types.scala @@ -35,6 +35,6 @@ object Test { println(map.info) println(map.infoIn(cil)) println(distinct.info) - if (failed) sys.exit(1) + assert(!failed) } } diff --git a/test/files/run/hk-typevar-unification.scala b/test/files/run/hk-typevar-unification.scala index 2afd26c875f1..81d6ab4e0081 100644 --- a/test/files/run/hk-typevar-unification.scala +++ b/test/files/run/hk-typevar-unification.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // trait Forall[F[_]] { diff --git a/test/files/run/huge-string.check b/test/files/run/huge-string.check new file mode 100644 index 000000000000..8dc07a5a6cbf --- /dev/null +++ b/test/files/run/huge-string.check @@ -0,0 +1,3 @@ +error: Error while emitting C +UTF8 string too large +error: Method s in class C has a bad String constant of length 393210 diff --git a/test/files/run/huge-string.scala b/test/files/run/huge-string.scala new file mode 100644 index 000000000000..f60db3c376c4 --- /dev/null +++ b/test/files/run/huge-string.scala @@ -0,0 +1,13 @@ +//> abusing options -Vdebug -Xverify + +import scala.tools.partest.DirectTest + +object Test extends DirectTest { + def genStr = "ohohoh" * 0xFFFF + def code = s""" + class C { + def s = "$genStr" + } + """ + def show() = assert(!compile()) +} diff --git a/test/files/run/idempotency-case-classes.check b/test/files/run/idempotency-case-classes.check index 7339a68be71b..78cc54bfa694 100644 --- a/test/files/run/idempotency-case-classes.check +++ b/test/files/run/idempotency-case-classes.check @@ -29,7 +29,7 @@ C(2,3) }; override def hashCode(): Int = { var acc: Int = -889275714; - acc = scala.runtime.Statics.mix(acc, C.this.productPrefix.hashCode()); + acc = scala.runtime.Statics.mix(acc, 67); acc = scala.runtime.Statics.mix(acc, x); acc = scala.runtime.Statics.mix(acc, y); scala.runtime.Statics.finalizeHash(acc, 2) diff --git a/test/files/run/indyLambdaKinds.check b/test/files/run/indyLambdaKinds.check index 863f89a24d44..6476d0dbc91b 100644 --- a/test/files/run/indyLambdaKinds.check +++ b/test/files/run/indyLambdaKinds.check @@ -18,12 +18,21 @@ Inlining into Main$.main Inlining into Main$.t1a: inlined A_1.a (the callsite is annotated `@inline`). Before: 7 ins, after: 14 ins. Inlining into Main$.t2a: inlined A_1.b (the callsite is annotated `@inline`). Before: 7 ins, after: 14 ins. Inlining into Main$.t3a: inlined A_1.c (the callsite is annotated `@inline`). Before: 7 ins, after: 14 ins. +#partest java24+ +Inlining into Main$.t4a: failed A_1.d (the callsite is annotated `@inline`). A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; is annotated @inline but could not be inlined: The callee A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/BiFunction; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$d$0(Ljava/lang/String;LA_1;Ljava/lang/String;)Ljava/lang/String;, (LA_1;Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. +Inlining into Main$.t4b: failed A_1.d (the callsite is annotated `@inline`). A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; is annotated @inline but could not be inlined: The callee A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/BiFunction; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$d$0(Ljava/lang/String;LA_1;Ljava/lang/String;)Ljava/lang/String;, (LA_1;Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. +Inlining into Main$.t5a: failed A_1.e (the callsite is annotated `@inline`). A_1::e(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::e(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$e$0(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, (Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. +Inlining into Main$.t5b: failed A_1.e (the callsite is annotated `@inline`). A_1::e(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::e(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$e$0(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, (Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. +Inlining into Main$.t6a: failed A_1.f (the callsite is annotated `@inline`). A_1::f(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::f(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$f$0(Ljava/lang/String;Ljava/lang/String;)LA_1;, (Ljava/lang/String;)LA_1; ] that would cause an IllegalAccessError when inlined into class Main$. +Inlining into Main$.t6b: failed A_1.f (the callsite is annotated `@inline`). A_1::f(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::f(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$f$0(Ljava/lang/String;Ljava/lang/String;)LA_1;, (Ljava/lang/String;)LA_1; ] that would cause an IllegalAccessError when inlined into class Main$. +#partest !java24+ Inlining into Main$.t4a: failed A_1.d (the callsite is annotated `@inline`). A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; is annotated @inline but could not be inlined: The callee A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/BiFunction; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$d$0(Ljava/lang/String;LA_1;Ljava/lang/String;)Ljava/lang/String;, (LA_1;Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. Inlining into Main$.t4b: failed A_1.d (the callsite is annotated `@inline`). A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; is annotated @inline but could not be inlined: The callee A_1::d(Ljava/lang/String;)Ljava/util/function/BiFunction; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/BiFunction; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$d$0(Ljava/lang/String;LA_1;Ljava/lang/String;)Ljava/lang/String;, (LA_1;Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. Inlining into Main$.t5a: failed A_1.e (the callsite is annotated `@inline`). A_1::e(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::e(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$e$1(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, (Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. Inlining into Main$.t5b: failed A_1.e (the callsite is annotated `@inline`). A_1::e(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::e(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$e$1(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, (Ljava/lang/String;)Ljava/lang/String; ] that would cause an IllegalAccessError when inlined into class Main$. Inlining into Main$.t6a: failed A_1.f (the callsite is annotated `@inline`). A_1::f(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::f(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$f$2(Ljava/lang/String;Ljava/lang/String;)LA_1;, (Ljava/lang/String;)LA_1; ] that would cause an IllegalAccessError when inlined into class Main$. Inlining into Main$.t6b: failed A_1.f (the callsite is annotated `@inline`). A_1::f(Ljava/lang/String;)Ljava/util/function/Function; is annotated @inline but could not be inlined: The callee A_1::f(Ljava/lang/String;)Ljava/util/function/Function; contains the instruction INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [ // handle kind 0x6 : INVOKESTATIC java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; // arguments: (Ljava/lang/Object;)Ljava/lang/Object;, // handle kind 0x6 : INVOKESTATIC A_1.lambda$f$2(Ljava/lang/String;Ljava/lang/String;)LA_1;, (Ljava/lang/String;)LA_1; ] that would cause an IllegalAccessError when inlined into class Main$. +#partest Inlining into Main$.t1b inlined A_1.a (the callsite is annotated `@inline`). Before: 11 ins, after: 18 ins. rewrote invocations of closure allocated in Main$.t1b with body m1: INVOKEINTERFACE java/util/function/BiFunction.apply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; (itf) diff --git a/test/files/run/inferred-structural-3.check b/test/files/run/inferred-structural-3.check new file mode 100644 index 000000000000..6f270aa5313b --- /dev/null +++ b/test/files/run/inferred-structural-3.check @@ -0,0 +1,32 @@ + +scala> trait A { def f: AnyRef } // refinement dropped +trait A + +scala> def a = Option(new { def g = 1 }) // refinement dropped +def a: Option[AnyRef] + +scala> def b: Option[{ def g: Int }] = Option(new { def g = 1 }) +def b: Option[AnyRef{def g: Int}] + +scala> def c(p: { def i: Int }): Int = 0 +def c(p: AnyRef{def i: Int}): Int + +scala> def d = new A { def f: A = this } // refinement of existing method is kept, in Scala 3 too +def d: A{def f: A} + +scala> def e = new A { def f: AnyRef = new AnyRef } // no refinement in 2.13 eihter +def e: A + +scala> def f = new A { def f = new AnyRef } // no refinement in 2.13 either +def f: A + +scala> def g = new A { def f = this } // inferred type of `f` is AnyRef because of infer-override +def g: A + +scala> def h = new AnyRef { type T = String } // TODO: dropped in Scala 3; figure out the rules Scala 3 uses and approximate them +def h: AnyRef{type T = String} + +scala> def i = new AnyRef { val x = 2 } // dropped +def i: AnyRef + +scala> :quit diff --git a/test/files/run/inferred-structural-3.scala b/test/files/run/inferred-structural-3.scala new file mode 100644 index 000000000000..03196dda6c99 --- /dev/null +++ b/test/files/run/inferred-structural-3.scala @@ -0,0 +1,17 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xsource:3 -Xsource-features:no-infer-structural,infer-override" + def code = + """trait A { def f: AnyRef } // refinement dropped + |def a = Option(new { def g = 1 }) // refinement dropped + |def b: Option[{ def g: Int }] = Option(new { def g = 1 }) + |def c(p: { def i: Int }): Int = 0 + |def d = new A { def f: A = this } // refinement of existing method is kept, in Scala 3 too + |def e = new A { def f: AnyRef = new AnyRef } // no refinement in 2.13 eihter + |def f = new A { def f = new AnyRef } // no refinement in 2.13 either + |def g = new A { def f = this } // inferred type of `f` is AnyRef because of infer-override + |def h = new AnyRef { type T = String } // TODO: dropped in Scala 3; figure out the rules Scala 3 uses and approximate them + |def i = new AnyRef { val x = 2 } // dropped + |""".stripMargin +} diff --git a/test/files/run/infix-rangepos.scala b/test/files/run/infix-rangepos.scala index 8d2a16a0b536..5221ef503ea0 100644 --- a/test/files/run/infix-rangepos.scala +++ b/test/files/run/infix-rangepos.scala @@ -2,7 +2,7 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos" + override def sources = List( "class C1 { def t = List(1).map ( x => x ) }", "class C2 { def t = List(1).map { x => x } }", diff --git a/test/files/run/infixPostfixAttachments.scala b/test/files/run/infixPostfixAttachments.scala index a5505a456b5b..14ef3226d9e5 100644 --- a/test/files/run/infixPostfixAttachments.scala +++ b/test/files/run/infixPostfixAttachments.scala @@ -2,7 +2,7 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos -Ystop-after:typer -deprecation" + override def extraSettings = super.extraSettings + " -Ystop-after:typer -deprecation" override def code = """class C { diff --git a/test/files/run/inline-stack-map-frames/A_1.scala b/test/files/run/inline-stack-map-frames/A_1.scala index 942b8591271b..477835051395 100644 --- a/test/files/run/inline-stack-map-frames/A_1.scala +++ b/test/files/run/inline-stack-map-frames/A_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** class A { @noinline final def b: B = null @inline final def a: A = b diff --git a/test/files/run/inline-stack-map-frames/Test_2.scala b/test/files/run/inline-stack-map-frames/Test_2.scala index 3a904a6e940d..13ca041f45a2 100644 --- a/test/files/run/inline-stack-map-frames/Test_2.scala +++ b/test/files/run/inline-stack-map-frames/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** class C { def t(a: A): AnyRef = { // a.a is inlined, resulting in a.b, which has return type B diff --git a/test/files/run/inner-obj-auto.scala b/test/files/run/inner-obj-auto.scala index 3277d9f042ca..bac5dedc8944 100644 --- a/test/files/run/inner-obj-auto.scala +++ b/test/files/run/inner-obj-auto.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 0 +//> using options -Xmaxwarns 0 /* ================================================================================ Automatically generated on 2011-05-11. Do Not Edit (unless you have to). diff --git a/test/files/run/interop_typetags_are_manifests.scala b/test/files/run/interop_typetags_are_manifests.scala index 3eb36e292c2c..bc7f0840c37b 100644 --- a/test/files/run/interop_typetags_are_manifests.scala +++ b/test/files/run/interop_typetags_are_manifests.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false // import scala.reflect.runtime.universe._ import scala.reflect.ClassTag diff --git a/test/files/run/is-valid-num.scala b/test/files/run/is-valid-num.scala index ef2388f8baa3..5e0f17405c2e 100644 --- a/test/files/run/is-valid-num.scala +++ b/test/files/run/is-valid-num.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint -Werror +//> using options -Xlint -Werror @annotation.nowarn("cat=deprecation&msg=isWhole") object Test { def x = BigInt("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") diff --git a/test/files/run/iterableonce-deprecations.scala b/test/files/run/iterableonce-deprecations.scala index 35bce673824a..5a8108368c23 100644 --- a/test/files/run/iterableonce-deprecations.scala +++ b/test/files/run/iterableonce-deprecations.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // // // diff --git a/test/files/run/lambda-serialization-gc.scala b/test/files/run/lambda-serialization-gc.scala index 529a32146302..2195e027a356 100644 --- a/test/files/run/lambda-serialization-gc.scala +++ b/test/files/run/lambda-serialization-gc.scala @@ -1,4 +1,4 @@ -// java: -Xmx512m +//> using javaOpt -Xmx512m import java.io._ diff --git a/test/files/run/lazy-locals.scala b/test/files/run/lazy-locals.scala index 11801fa96c1c..de4fff901bbb 100644 --- a/test/files/run/lazy-locals.scala +++ b/test/files/run/lazy-locals.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 0 +//> using options -Xmaxwarns 0 object Test extends App { lazy val w = 10 diff --git a/test/files/run/literals-parsing.scala b/test/files/run/literals-parsing.scala index 04a0c5f4d359..dde2de6023b2 100644 --- a/test/files/run/literals-parsing.scala +++ b/test/files/run/literals-parsing.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:parser -Yrangepos -Ystop-after:parser -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:parser -Ystop-after:parser -cp ${testOutput.path}" // test/files/pos/t6124.scala override def code = """ diff --git a/test/files/run/literals.scala b/test/files/run/literals.scala index 358c330138f1..06e6cacf4fb1 100644 --- a/test/files/run/literals.scala +++ b/test/files/run/literals.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // //############################################################################ // Literals diff --git a/test/files/run/macro-duplicate.check b/test/files/run/macro-duplicate.check index 7006b1661162..136e30c8a8d3 100644 --- a/test/files/run/macro-duplicate.check +++ b/test/files/run/macro-duplicate.check @@ -1,3 +1,3 @@ -Test_2.scala:5: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +Test_2.scala:5: warning: a pure expression does nothing in statement position Macros.foo ^ diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala index 03e9ae0c5fff..85857b8a17c6 100644 --- a/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala +++ b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation import scala.reflect.macros.blackbox.Context object Impls { diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala index 50bac1eedbfa..db8742b67eb1 100644 --- a/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala +++ b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation object Macros { import scala.language.experimental.macros diff --git a/test/files/run/macro-nonrangepos-args/Macros_1.scala b/test/files/run/macro-nonrangepos-args/Macros_1.scala new file mode 100644 index 000000000000..97b938613c5d --- /dev/null +++ b/test/files/run/macro-nonrangepos-args/Macros_1.scala @@ -0,0 +1,10 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macros { + def impl(c: Context)(x: c.Tree): c.Tree = { + import c.universe._ + Literal(Constant(s"Line: ${x.pos.line}. Width: ${x.pos.end - x.pos.start}.")) + } + def pos(x: Any): String = macro impl +} diff --git a/test/files/run/macro-nonrangepos-args/Test_2.scala b/test/files/run/macro-nonrangepos-args/Test_2.scala new file mode 100644 index 000000000000..8cc5c6ad52d6 --- /dev/null +++ b/test/files/run/macro-nonrangepos-args/Test_2.scala @@ -0,0 +1,7 @@ +//> using options -Yrangepos:false +object Test extends App { + val num = 42 + val pos = Macros.pos(num + 17) + val text = "num + 17" + assert(pos == s"Line: 4. Width: ${text.length}.", pos) // position of binary op is always a range +} diff --git a/test/files/run/macro-openmacros.check b/test/files/run/macro-openmacros.check index 81cd1bbba5c2..d923d03544b0 100644 --- a/test/files/run/macro-openmacros.check +++ b/test/files/run/macro-openmacros.check @@ -1,3 +1,3 @@ -List(MacroContext(foo@source-Test_2.scala,line-3,offset=63 +0)) -List(MacroContext(foo@source-Test_2.scala,line-3,offset=63 +1), MacroContext(foo@source-Test_2.scala,line-3,offset=63 +0)) -List(MacroContext(foo@source-Test_2.scala,line-3,offset=63 +2), MacroContext(foo@source-Test_2.scala,line-3,offset=63 +1), MacroContext(foo@source-Test_2.scala,line-3,offset=63 +0)) +List(MacroContext(foo@source-Test_2.scala,line-3,offset=70 +0)) +List(MacroContext(foo@source-Test_2.scala,line-3,offset=70 +1), MacroContext(foo@source-Test_2.scala,line-3,offset=70 +0)) +List(MacroContext(foo@source-Test_2.scala,line-3,offset=70 +2), MacroContext(foo@source-Test_2.scala,line-3,offset=70 +1), MacroContext(foo@source-Test_2.scala,line-3,offset=70 +0)) diff --git a/test/files/run/macro-openmacros/Impls_Macros_1.scala b/test/files/run/macro-openmacros/Impls_Macros_1.scala index 341ea63bd6c6..2e2069c89411 100644 --- a/test/files/run/macro-openmacros/Impls_Macros_1.scala +++ b/test/files/run/macro-openmacros/Impls_Macros_1.scala @@ -1,6 +1,7 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context +import scala.util.Properties.isWin object Macros { def impl(c: Context): c.Expr[Unit] = { @@ -10,7 +11,6 @@ object Macros { def normalizePaths(s: String) = { val base = (dir.getCanonicalPath + java.io.File.separator).replace('\\', '/') var regex = """\Q%s\E""" format base - val isWin = System.getProperty("os.name", "") startsWith "Windows" if (isWin) regex = "(?i)" + regex s.replace('\\', '/').replaceAll(regex, "") } diff --git a/test/files/run/macro-openmacros/Test_2.scala b/test/files/run/macro-openmacros/Test_2.scala index 8a085961570d..976a6c0011e3 100644 --- a/test/files/run/macro-openmacros/Test_2.scala +++ b/test/files/run/macro-openmacros/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false object Test extends App { Macros.foo } diff --git a/test/files/run/macro-parse-position.check b/test/files/run/macro-parse-position.check index 3da0320696d2..feceb9fac88f 100644 --- a/test/files/run/macro-parse-position.check +++ b/test/files/run/macro-parse-position.check @@ -1,5 +1,5 @@ false -source-,line-1,offset=4 +RangePosition(, 0, 4, 7) 8 foo bar diff --git a/test/files/run/macro-parse-position/Impls_Macros_1.scala b/test/files/run/macro-parse-position/Impls_Macros_1.scala index a17f0cdbfa63..34a0e6ad2d70 100644 --- a/test/files/run/macro-parse-position/Impls_Macros_1.scala +++ b/test/files/run/macro-parse-position/Impls_Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/run/macro-parse-position/Test_2.scala b/test/files/run/macro-parse-position/Test_2.scala index db0bac2510ff..fcf7a1ef9210 100644 --- a/test/files/run/macro-parse-position/Test_2.scala +++ b/test/files/run/macro-parse-position/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false object Test extends App { println(Macros.foo) } diff --git a/test/files/run/macro-rangepos-args.check b/test/files/run/macro-rangepos-args.check deleted file mode 100644 index d779505c66c1..000000000000 --- a/test/files/run/macro-rangepos-args.check +++ /dev/null @@ -1 +0,0 @@ -Line: 3. Width: 5. diff --git a/test/files/run/macro-rangepos-args/Test_2.scala b/test/files/run/macro-rangepos-args/Test_2.scala index 3fcf3d5a39ec..0e6c5834d18c 100644 --- a/test/files/run/macro-rangepos-args/Test_2.scala +++ b/test/files/run/macro-rangepos-args/Test_2.scala @@ -1,4 +1,6 @@ object Test extends App { val x = 2 - println(Macros.pos(x + 2)) + val pos = Macros.pos(x + 2 + "42".toString) + val text = """x + 2 + "42".toString""" + assert(pos == s"Line: 3. Width: ${text.length}.", pos) } diff --git a/test/files/run/macro-rangepos-subpatterns/Macros_1.scala b/test/files/run/macro-rangepos-subpatterns/Macros_1.scala index 9f0b7a5dc537..988dfb744053 100644 --- a/test/files/run/macro-rangepos-subpatterns/Macros_1.scala +++ b/test/files/run/macro-rangepos-subpatterns/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// import scala.reflect.macros.whitebox.Context import language.experimental.macros diff --git a/test/files/run/macro-rangepos-subpatterns/Test_2.scala b/test/files/run/macro-rangepos-subpatterns/Test_2.scala index b2559e34eddc..c9b1982c9db2 100644 --- a/test/files/run/macro-rangepos-subpatterns/Test_2.scala +++ b/test/files/run/macro-rangepos-subpatterns/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// object Test extends App { 42 match { case Extractor(a) => println(a) diff --git a/test/files/run/macro-settings/Test_2.scala b/test/files/run/macro-settings/Test_2.scala index 830b25335057..fc891cfc1dd6 100644 --- a/test/files/run/macro-settings/Test_2.scala +++ b/test/files/run/macro-settings/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xmacro-settings:hello=1 +//> using options -Xmacro-settings:hello=1 object Test extends App { Macros.foo } diff --git a/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala index 785e92873a96..4bb5879d9a9b 100644 --- a/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -language:experimental.macros +//> using options -language:experimental.macros //import scala.language.experimental.macros import scala.language.reflectiveCalls diff --git a/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala index 738f7fc836d1..a00059ec44de 100644 --- a/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -language:experimental.macros +//> using options -language:experimental.macros //import scala.language.experimental.macros import scala.language.reflectiveCalls diff --git a/test/files/run/macro-vampire-false-warning/Macros_1.scala b/test/files/run/macro-vampire-false-warning/Macros_1.scala index a2e31ba61b37..169506de2e5e 100644 --- a/test/files/run/macro-vampire-false-warning/Macros_1.scala +++ b/test/files/run/macro-vampire-false-warning/Macros_1.scala @@ -1,5 +1,5 @@ // As per https://meta.plasm.us/posts/2013/08/31/feeding-our-vampires/ -// scalac: -Werror +//> using options -Werror import scala.annotation.StaticAnnotation import scala.reflect.macros.whitebox.Context diff --git a/test/files/run/macro-vampire-false-warning/Test_2.scala b/test/files/run/macro-vampire-false-warning/Test_2.scala index 154cc430c855..a9dd906bbae5 100644 --- a/test/files/run/macro-vampire-false-warning/Test_2.scala +++ b/test/files/run/macro-vampire-false-warning/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test extends App { val foo = mkObject("x" -> "2", "y" -> 3) println(foo.x) diff --git a/test/files/run/macroPlugins-enterStats.scala b/test/files/run/macroPlugins-enterStats.scala index de1701640cbe..346f1fe01e82 100644 --- a/test/files/run/macroPlugins-enterStats.scala +++ b/test/files/run/macroPlugins-enterStats.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // import scala.tools.partest._ import scala.tools.nsc._ diff --git a/test/files/run/macroPlugins-isBlackbox/Test_3.scala b/test/files/run/macroPlugins-isBlackbox/Test_3.scala index 68eb05dc8eb5..d3397c023ddf 100644 --- a/test/files/run/macroPlugins-isBlackbox/Test_3.scala +++ b/test/files/run/macroPlugins-isBlackbox/Test_3.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. +//> using options -Xplugin:. object Test extends App { val x: Int = Macros.foo } diff --git a/test/files/run/macroPlugins-macroArgs/Test_3.scala b/test/files/run/macroPlugins-macroArgs/Test_3.scala index de0c68bb4c00..37440cdcccc6 100644 --- a/test/files/run/macroPlugins-macroArgs/Test_3.scala +++ b/test/files/run/macroPlugins-macroArgs/Test_3.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. +//> using options -Xplugin:. object Test extends App { Macros.foo("1") Macros.foo("2") diff --git a/test/files/run/macroPlugins-macroExpand/Test_3.scala b/test/files/run/macroPlugins-macroExpand/Test_3.scala index 178b2f6b57bc..5351095330c8 100644 --- a/test/files/run/macroPlugins-macroExpand/Test_3.scala +++ b/test/files/run/macroPlugins-macroExpand/Test_3.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. +//> using options -Xplugin:. object Test extends App { Macros.foo1 Macros.foo2 diff --git a/test/files/run/macroPlugins-macroRuntime/Test_3.scala b/test/files/run/macroPlugins-macroRuntime/Test_3.scala index de0c68bb4c00..37440cdcccc6 100644 --- a/test/files/run/macroPlugins-macroRuntime/Test_3.scala +++ b/test/files/run/macroPlugins-macroRuntime/Test_3.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. +//> using options -Xplugin:. object Test extends App { Macros.foo("1") Macros.foo("2") diff --git a/test/files/run/macroPlugins-namerHooks.check b/test/files/run/macroPlugins-namerHooks.check index fe93a6cc8637..41670ba66ad1 100644 --- a/test/files/run/macroPlugins-namerHooks.check +++ b/test/files/run/macroPlugins-namerHooks.check @@ -18,11 +18,11 @@ enterStat(super.()) enterSym( def copy$default$1 = x) enterSym( def copy$default$2 = y) enterSym( var acc: Int = -889275714) -enterSym(acc = scala.runtime.Statics.mix(acc, C.this.productPrefix.hashCode())) +enterSym(acc = scala.runtime.Statics.mix(acc, 67)) enterSym(acc = scala.runtime.Statics.mix(acc, x)) enterSym(acc = scala.runtime.Statics.mix(acc, y)) enterStat( var acc: Int = -889275714) -enterStat(acc = scala.runtime.Statics.mix(acc, C.this.productPrefix.hashCode())) +enterStat(acc = scala.runtime.Statics.mix(acc, 67)) enterStat(acc = scala.runtime.Statics.mix(acc, x)) enterStat(acc = scala.runtime.Statics.mix(acc, y)) enterSym( val C$1: C = x$1.asInstanceOf[C]) diff --git a/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala b/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala index 7dafd5bfac91..d92c4a257cfb 100644 --- a/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala +++ b/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala @@ -1,4 +1,4 @@ -// scalac: -Xplugin:. -Yrangepos:false +//> using options -Xplugin:. -Yrangepos:false import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context diff --git a/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala b/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala index b9445dd9d30a..e9df77f49580 100644 --- a/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala +++ b/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false package typedMacroBody import scala.tools.nsc.Global diff --git a/test/files/run/macroPlugins-typedMacroBody/Test_3.scala b/test/files/run/macroPlugins-typedMacroBody/Test_3.scala index 360d9bbaa0f6..7ababf77324f 100644 --- a/test/files/run/macroPlugins-typedMacroBody/Test_3.scala +++ b/test/files/run/macroPlugins-typedMacroBody/Test_3.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false object Test extends App { Macros.foo1 Macros.foo2 diff --git a/test/files/run/manifests-undeprecated-in-2.10.0.scala b/test/files/run/manifests-undeprecated-in-2.10.0.scala index dc1b8373ed70..6cea26e304ab 100644 --- a/test/files/run/manifests-undeprecated-in-2.10.0.scala +++ b/test/files/run/manifests-undeprecated-in-2.10.0.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // object Test extends App { def m1a: scala.reflect.Manifest[Int] = scala.reflect.Manifest.Int diff --git a/test/files/run/module-serialization-proxy-class-unload.scala b/test/files/run/module-serialization-proxy-class-unload.scala index f6405d33a2c0..eb0d4daf8a40 100644 --- a/test/files/run/module-serialization-proxy-class-unload.scala +++ b/test/files/run/module-serialization-proxy-class-unload.scala @@ -1,4 +1,4 @@ -// scalac: -Ddummy=run-in-forked-process +//> using options -Ddummy=run-in-forked-process object Module { val data = new Array[Byte](32 * 1024 * 1024) } diff --git a/test/files/run/multiLineOps.scala b/test/files/run/multiLineOps.scala index 2b51b95e9262..bcb218a3bba1 100644 --- a/test/files/run/multiLineOps.scala +++ b/test/files/run/multiLineOps.scala @@ -1,8 +1,8 @@ -//> using options -Xsource:3-cross -// +//> using options -Xsource:3 -Xsource-features:leading-infix + // was: without backticks, "not found: value +" (but parsed here as +a * 6, where backticks fool the lexer) // now: + is taken as "solo" infix op -// + object Test extends App { val a = 7 val x = 1 diff --git a/test/files/run/name-based-patmat.scala b/test/files/run/name-based-patmat.scala index b47c6f76d6f9..50693595b24f 100644 --- a/test/files/run/name-based-patmat.scala +++ b/test/files/run/name-based-patmat.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:stars-align +//> using options -Xlint:stars-align final class MiniSome[T](val get: T) extends AnyVal { def isEmpty = false } package p0 { diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check index 7e38494250da..982fff64dcd3 100644 --- a/test/files/run/names-defaults.check +++ b/test/files/run/names-defaults.check @@ -1,3 +1,15 @@ +names-defaults.scala:318: warning: value q has an inferred structural type: Test.Test3207_1.p.Inner{def g: Int} + members that can be accessed with a reflective call: def g: Int + val q = new p.Inner() { + ^ +names-defaults.scala:325: warning: value inner has an inferred structural type: this.Inner{def g: Int} + members that can be accessed with a reflective call: def g: Int + val inner = new Inner() { + ^ +names-defaults.scala:324: warning: value p has an inferred structural type: Test.P3207[Int]{val inner: this.Inner{def g: Int}} + members that can be accessed with a reflective call: val inner: this.Inner{def g: Int} + val p = new P3207[Int] { + ^ names-defaults.scala:359: warning: the parameter name y is deprecated: use b instead deprNam1(y = 10, a = 1) ^ @@ -22,10 +34,7 @@ names-defaults.scala:280: warning: local val v in method foo is never used names-defaults.scala:280: warning: local val u in method foo is never used class A2489x2 { def foo(): Unit = { val v = 10; def bar(a: Int = 1, b: Int = 2) = a; bar(); val u = 0 } } ^ -names-defaults.scala:269: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - spawn(b = { val ttt = 1; ttt }, a = 0) - ^ -names-defaults.scala:269: warning: a pure expression does nothing in statement position +names-defaults.scala:269: warning: discarded pure expression does nothing spawn(b = { val ttt = 1; ttt }, a = 0) ^ 1: @ diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index f2c3ac3e2f70..136d656f7a5d 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint +//> using options -Xlint import scala.language.existentials object Test extends App { diff --git a/test/files/run/nonfatal.scala b/test/files/run/nonfatal.scala index 2581d01f1c6b..60e2becd8eaa 100644 --- a/test/files/run/nonfatal.scala +++ b/test/files/run/nonfatal.scala @@ -12,6 +12,7 @@ object Test extends BytecodeTest { val g = getMethod(classNode, "g") assertEquals(instructionsFromMethod(f), instructionsFromMethod(g)) //sameBytecode(f, g) // prints + new C().run() // should not crash } } @@ -19,5 +20,14 @@ class C { import scala.util.control.NonFatal def x = 42 def f = try x catch { case NonFatal(e) => e.printStackTrace(); -1 } - def g = try x catch { case e if NonFatal(e) => e.printStackTrace(); -1 } + def g = try x catch { case e: Throwable if NonFatal(e) => e.printStackTrace(); -1 } + + def run(): Unit = { + val any: Any = 42 + + any match { + case NonFatal(e) => ??? + case _ => + } + } } diff --git a/test/files/run/nonlocalreturn.scala b/test/files/run/nonlocalreturn.scala index 0bc4a8d29a85..3d6b18507ada 100644 --- a/test/files/run/nonlocalreturn.scala +++ b/test/files/run/nonlocalreturn.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:-nonlocal-return +//> using options -Xlint:-nonlocal-return object Test { def wrap[K](body: => K): K = body diff --git a/test/files/run/nothingTypeDce.scala b/test/files/run/nothingTypeDce.scala index e2753f2e9a4a..e39efaf53b61 100644 --- a/test/files/run/nothingTypeDce.scala +++ b/test/files/run/nothingTypeDce.scala @@ -1,4 +1,4 @@ -// scalac: -opt:unreachable-code +//> using options -opt:unreachable-code // // See comment in BCodeBodyBuilder diff --git a/test/files/run/nowarn.scala b/test/files/run/nowarn.scala index 9b52dd464c89..e49ce061090a 100644 --- a/test/files/run/nowarn.scala +++ b/test/files/run/nowarn.scala @@ -10,7 +10,7 @@ class Driven extends Driver { true } protected def newCompiler(): Global = Global(settings, reporter) - override protected def doCompile(compiler: Global): Unit = reporter.warning(NoPosition, "I don't do anything.") + override protected def doCompile(compiler: Global): Unit = reporter.warning(NoPosition, s"I can't do anything for ${reporter.getClass}.") def run(): Unit = process(Array("file.scala")) } object Test { diff --git a/test/files/run/patmat-exprs.scala b/test/files/run/patmat-exprs.scala index 0f7b71803a3f..faa2b2b75d7b 100644 --- a/test/files/run/patmat-exprs.scala +++ b/test/files/run/patmat-exprs.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint +//> using options -Werror -Xlint // import scala.language.{ implicitConversions } diff --git a/test/files/run/patmat-mix-case-extractor.scala b/test/files/run/patmat-mix-case-extractor.scala index 55c101a3fab2..fac2c0a6320f 100644 --- a/test/files/run/patmat-mix-case-extractor.scala +++ b/test/files/run/patmat-mix-case-extractor.scala @@ -1,4 +1,4 @@ -// scalac: -Xmaxwarns 0 +//> using options -Xmaxwarns 0 trait CaseClass trait ProdCaseClass extends CaseClass { def x: Int } trait SeqCaseClass extends CaseClass { def xs: Seq[Int] } diff --git a/test/files/run/patmat-seq.check b/test/files/run/patmat-seq.check index ffd4b8c20ac7..3521edc2682a 100644 --- a/test/files/run/patmat-seq.check +++ b/test/files/run/patmat-seq.check @@ -264,7 +264,7 @@ package { () }; def t(): Object = { - case val x1: Int(2) = 2; + case val x1: Int = 2; case16(){ val o18: scala.collection.SeqOps = A.unapplySeq(x1); if (scala.collection.SeqFactory.UnapplySeqWrapper.isEmpty$extension(o18).unary_!()) diff --git a/test/files/run/patmatnew.check b/test/files/run/patmatnew.check index ff9eb4579d7e..cc42f919a9f1 100644 --- a/test/files/run/patmatnew.check +++ b/test/files/run/patmatnew.check @@ -4,16 +4,10 @@ patmatnew.scala:673: warning: This catches all Throwables. If this is really int patmatnew.scala:354: warning: a pure expression does nothing in statement position case 1 => "OK" ^ -patmatnew.scala:355: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected +patmatnew.scala:355: warning: discarded pure expression does nothing case 2 => assert(false); "KO" ^ -patmatnew.scala:355: warning: a pure expression does nothing in statement position - case 2 => assert(false); "KO" - ^ -patmatnew.scala:356: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - case 3 => assert(false); "KO" - ^ -patmatnew.scala:356: warning: a pure expression does nothing in statement position +patmatnew.scala:356: warning: discarded pure expression does nothing case 3 => assert(false); "KO" ^ patmatnew.scala:178: warning: match may not be exhaustive. diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala index 145eb7b55c4e..53addeb8ae27 100644 --- a/test/files/run/patmatnew.scala +++ b/test/files/run/patmatnew.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // import scala.language.{ postfixOps } diff --git a/test/files/run/position-val-def.check b/test/files/run/position-val-def.check index b0ce48239ba9..e9d120e50abc 100644 --- a/test/files/run/position-val-def.check +++ b/test/files/run/position-val-def.check @@ -1,30 +1,113 @@ -val x = 0 -[0:9]val x = [8:9]0 - -var x = 0 -[0:9]var x = [8:9]0 - -val x, y = 0 -[NoPosition]{ - [4]val x = [11]0; - [7:12]val y = [11:12]0; - [NoPosition]() -} - -var x, y = 0 -[NoPosition]{ - [4]var x = [11]0; - [7:12]var y = [11:12]0; - [NoPosition]() -} - -val (x, y) = 0 -[NoPosition]{ - <0:14> private[this] val x$1 = <4:14>[13:14][13:14]0: @[13]scala.unchecked match { - <4:10>case <4:10>[4]scala.Tuple2(<5:6>(x @ [5]_), <8:9>(y @ [8]_)) => <4:10><4:10>scala.Tuple2(<4:10>x, <4:10>y) - }; - [5:6]val x = [5]x$1._1; - [8:9]val y = [8]x$1._2; - [NoPosition]() -} - +newSource8.scala:1: warning: Pattern definition introduces Unit-valued member of C7; consider wrapping it in `locally { ... }`. +class C7 { val Some(_) = Option(42) } + ^ +class C0 { val x = 42 } +[15:16] [11:21] [NoPosition] -> private[this] val x: Int = _ +[15] [15] [15] -> def x(): Int = C0.this.x +[15:16] [19:21] -> C0.this.x = 42 +-- +class C1 { var x = 42 } +[15:16] [11:21] [NoPosition] -> private[this] var x: Int = _ +[15] [15] [15] -> def x(): Int = C1.this.x +[15] [15] [15] -> def x_=(x$1: Int): Unit = C1.this.x = x$1 +[15] [15] -> C1.this.x = x$1 +[15:16] [19:21] -> C1.this.x = 42 +-- +class C2 { val x, y = 42 } +[15:16] <11:24> [NoPosition] -> private[this] val x: Int = _ +[15] [15] [15] -> def x(): Int = C2.this.x +[18:19] <11:24> [NoPosition] -> private[this] val y: Int = _ +[18] [18] [18] -> def y(): Int = C2.this.y +[15:16] [22] -> C2.this.x = 42 +[18:19] [22:24] -> C2.this.y = 42 +-- +class C3 { var x, y = 42 } +[15:16] <11:24> [NoPosition] -> private[this] var x: Int = _ +[15] [15] [15] -> def x(): Int = C3.this.x +[15] [15] [15] -> def x_=(x$1: Int): Unit = C3.this.x = x$1 +[15] [15] -> C3.this.x = x$1 +[18:19] <11:24> [NoPosition] -> private[this] var y: Int = _ +[18] [18] [18] -> def y(): Int = C3.this.y +[18] [18] [18] -> def y_=(x$1: Int): Unit = C3.this.y = x$1 +[18] [18] -> C3.this.y = x$1 +[15:16] [22] -> C3.this.x = 42 +[18:19] [22:24] -> C3.this.y = 42 +-- +class C4 { val (x, y) = (42, 27) } +<15:32> <15:32> [NoPosition] -> private[this] val x$1: Tuple2 = _ +[16:17] <11:32> [NoPosition] -> private[this] val x: Int = _ +[16] [16] [16] -> def x(): Int = C4.this.x +[19:20] <11:32> [NoPosition] -> private[this] val y: Int = _ +[19] [19] [19] -> def y(): Int = C4.this.y +<15:32> [24:32] -> C4.this.x$1 = {... +[24:32] [24:32] [24:32] -> case val x1: Tuple2 = (new Tuple2$mcII$sp(42, 27): Tuple2) +[24:32] -> new Tuple2$mcII$sp(42, 27) + [25:27] -> 42 + [29:31] -> 27 +<15:21> -> x1.ne(null) + <15:21> -> null +<16:17> <16:17> <16:17> -> val x: Int = x1._1$mcI$sp() +<19:20> <19:20> <19:20> -> val y: Int = x1._2$mcI$sp() +<15:21> -> new Tuple2$mcII$sp(x, y) + <16:17> -> x + <19:20> -> y +[16:17] [16] -> C4.this.x = C4.this.x$1._1$mcI$sp() +[19:20] [19] -> C4.this.y = C4.this.x$1._2$mcI$sp() +-- +class C5 { val (x, y), (w, z) = (42, 27) } +<15:40> <15:40> [NoPosition] -> private[this] val x$1: Tuple2 = _ +[16:17] <11:40> [NoPosition] -> private[this] val x: Int = _ +[16] [16] [16] -> def x(): Int = C5.this.x +[19:20] <11:40> [NoPosition] -> private[this] val y: Int = _ +[19] [19] [19] -> def y(): Int = C5.this.y +<23:40> <23:40> [NoPosition] -> private[this] val x$2: Tuple2 = _ +[24:25] <11:40> [NoPosition] -> private[this] val w: Int = _ +[24] [24] [24] -> def w(): Int = C5.this.w +[27:28] <11:40> [NoPosition] -> private[this] val z: Int = _ +[27] [27] [27] -> def z(): Int = C5.this.z +<15:40> [32] -> C5.this.x$1 = {... +[32] [32] [32] -> case val x1: Tuple2 = (new Tuple2$mcII$sp(42, 27): Tuple2) +<15:21> -> x1.ne(null) + <15:21> -> null +<16:17> <16:17> <16:17> -> val x: Int = x1._1$mcI$sp() +<19:20> <19:20> <19:20> -> val y: Int = x1._2$mcI$sp() +<15:21> -> new Tuple2$mcII$sp(x, y) + <16:17> -> x + <19:20> -> y +[16:17] [16] -> C5.this.x = C5.this.x$1._1$mcI$sp() +[19:20] [19] -> C5.this.y = C5.this.x$1._2$mcI$sp() +<23:40> [32:40] -> C5.this.x$2 = {... +[32:40] [32:40] [32:40] -> case val x1: Tuple2 = (new Tuple2$mcII$sp(42, 27): Tuple2) +[32:40] -> new Tuple2$mcII$sp(42, 27) + [33:35] -> 42 + [37:39] -> 27 +<23:29> -> x1.ne(null) + <23:29> -> null +<24:25> <24:25> <24:25> -> val w: Int = x1._1$mcI$sp() +<27:28> <27:28> <27:28> -> val z: Int = x1._2$mcI$sp() +<23:29> -> new Tuple2$mcII$sp(w, z) + <24:25> -> w + <27:28> -> z +[24:25] [24] -> C5.this.w = C5.this.x$2._1$mcI$sp() +[27:28] [27] -> C5.this.z = C5.this.x$2._2$mcI$sp() +-- +class C6 { val x, y, z: String = "hello, worlds" } +[15:16] <11:48> [NoPosition] -> private[this] val x: String = _ +[15] [15] [15] -> def x(): String = C6.this.x +[18:19] <11:48> [NoPosition] -> private[this] val y: String = _ +[18] [18] [18] -> def y(): String = C6.this.y +[21:22] <11:48> [NoPosition] -> private[this] val z: String = _ +[21] [21] [21] -> def z(): String = C6.this.z +[15:16] [33] -> C6.this.x = "hello, worlds" +[18:19] [33] -> C6.this.y = "hello, worlds" +[21:22] [33:48] -> C6.this.z = "hello, worlds" +-- +class C7 { val Some(_) = Option(42) } +[11:35] [11:35] [NoPosition] -> private[this] val x$1: scala.runtime.BoxedUnit = _ +[11:35] [25:35] -> C7.this.x$1 = {... +[25:35] [25:35] [25:35] -> case val x1: Option = (scala.Option.apply(scala.Int.box(42)): Option) +[25:35] -> scala.Option.apply(scala.Int.box(42)) + [32:34] -> scala.Int.box(42) +[32:34] -> scala.Int.box(42) + [32:34] -> 42 +-- diff --git a/test/files/run/position-val-def.scala b/test/files/run/position-val-def.scala index b79e120f746a..2b0da2598dbd 100644 --- a/test/files/run/position-val-def.scala +++ b/test/files/run/position-val-def.scala @@ -1,26 +1,61 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.runtime.{universe => ru} -import scala.reflect.runtime.{currentMirror => cm} -import scala.tools.reflect.ToolBox +//> using options -Xsource:3-cross -object Test { - val toolbox = cm.mkToolBox(options = "-Yrangepos") +import scala.reflect.internal.util.StringContextStripMarginOps +import scala.tools.partest.CompilerTest +import java.util.concurrent.atomic.AtomicInteger - def main(args: Array[String]): Unit = { - def test(expr: String): Unit = { - val t = toolbox.parse(expr) - println(expr) - println(show(t, printPositions = true)) - println() +object Test extends CompilerTest { + import global.{show as tshow, *} + + val counter = new AtomicInteger + + override def sources = + sm""" + val x = 42 + var x = 42 + val x, y = 42 + var x, y = 42 + val (x, y) = (42, 27) + val (x, y), (w, z) = (42, 27) + val x, y, z: String = "hello, worlds" + val Some(_) = Option(42) + """.linesIterator.map(_.trim).filter(_.nonEmpty) + .map(s => s"class C${counter.getAndIncrement} { $s }") + .toList + + def check(source: String, unit: CompilationUnit): Unit = { + println(source) + //println("--") + //println(tshow(unit.body)) + //println("--") + unit.body.foreach { + case t: ValOrDefDef if !t.symbol.isConstructor && !t.symbol.isParameter => + println(f"${tshow(t.namePos)}%-8s${tshow(t.pos)}%-8s${tshow(t.rhs.pos)}%-14s -> ${tshow(t).clipped}") + case t: Assign => + println(f"${tshow(t.pos)}%-8s${tshow(t.rhs.pos)}%-22s -> ${tshow(t).clipped}") + case t @ treeInfo.Application(fun, _, argss) + if !t.pos.isZeroExtent + && argss.exists(_.nonEmpty) + && !fun.symbol.isLabel + && fun.symbol.owner != definitions.MatchErrorClass + && !treeInfo.isSuperConstrCall(t) + => + println(f"${tshow(t.pos)}%-30s -> ${tshow(t).clipped}") + for (args <- argss; arg <- args) + println(f" ${tshow(arg.pos)}%-28s -> ${tshow(arg).clipped}") + case _ => } - val tests = """ - val x = 0 - var x = 0 - val x, y = 0 - var x, y = 0 - val (x, y) = 0 - """ - val exprs = tests.split("\\n").map(_.trim).filterNot(_.isEmpty) - exprs foreach test + println("--") + } + implicit class Clippy(val s: String) extends AnyVal { + def clipped = { + val it = s.linesIterator + val t = it.next() + if (it.hasNext) s"$t..." else t + } + } + implicit class Positional(val pos: Position) extends AnyVal { + def isZeroExtent = + !pos.isRange || pos.start == pos.end } } diff --git a/test/files/run/primitive-sigs-2-new.scala b/test/files/run/primitive-sigs-2-new.scala index d76707cb00e9..00718a318fff 100644 --- a/test/files/run/primitive-sigs-2-new.scala +++ b/test/files/run/primitive-sigs-2-new.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline // import scala.language.{ postfixOps } diff --git a/test/files/run/primitive-sigs-2-old.scala b/test/files/run/primitive-sigs-2-old.scala index faebedb25883..a3145e81fd25 100644 --- a/test/files/run/primitive-sigs-2-old.scala +++ b/test/files/run/primitive-sigs-2-old.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline // import scala.language.{ postfixOps } diff --git a/test/files/run/print-args.scala b/test/files/run/print-args.scala index 57c78b2d0d0f..88070f35c046 100644 --- a/test/files/run/print-args.scala +++ b/test/files/run/print-args.scala @@ -1,23 +1,25 @@ - import java.nio.file.Files +import org.junit.Assert.assertFalse import scala.jdk.CollectionConverters._ import scala.reflect.internal.util._ import scala.tools.partest.DirectTest +import scala.tools.testkit.AssertUtil.assertSameElements + +import org.junit.Assert._ object Test extends DirectTest { lazy val argfile = testOutput.jfile.toPath().resolve("print-args.txt") - override def extraSettings = s"${super.extraSettings} -Xsource:3 -Vprint-args ${argfile}" + override def extraSettings = s"${super.extraSettings} -Vprint-args ${argfile}" def expected = sm""" |-usejavacp |-d |${testOutput.jfile.toPath()} - |-Xsource:3.0.0 |-Vprint-args |${testOutput.jfile.toPath().resolve(argfile)} |newSource1.scala - """ + """.trim def code = sm""" |class C { @@ -25,7 +27,7 @@ object Test extends DirectTest { |} """ def show() = { - assert(!compile()) - assert(expected.linesIterator.toList.tail.init.sameElements(Files.readAllLines(argfile).asScala)) + assertFalse(compile()) + assertSameElements(expected.linesIterator, Files.readAllLines(argfile).asScala) } } diff --git a/test/files/run/productElementName.scala b/test/files/run/productElementName.scala index ff09355c39bd..9755dacac826 100644 --- a/test/files/run/productElementName.scala +++ b/test/files/run/productElementName.scala @@ -1,4 +1,4 @@ -//> using options -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:leading-infix import scala.tools.testkit.AssertUtil.assertThrown import scala.util.chaining.* diff --git a/test/files/run/pure-warning-post-macro/test_2.scala b/test/files/run/pure-warning-post-macro/test_2.scala index 328a0038195c..4b4934c08392 100644 --- a/test/files/run/pure-warning-post-macro/test_2.scala +++ b/test/files/run/pure-warning-post-macro/test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { def main(args: Array[String]): Unit = { // We don't want a "pure expression discarded" warning here as the macro will diff --git a/test/files/run/reflect-java-param-names/J_1.java b/test/files/run/reflect-java-param-names/J_1.java index 1585c86ae491..e19f6e46a16c 100644 --- a/test/files/run/reflect-java-param-names/J_1.java +++ b/test/files/run/reflect-java-param-names/J_1.java @@ -1,4 +1,4 @@ -// javac: -parameters +//> using javacOpt -parameters public class J_1 { public J_1(int i, int j) {} public void inst(int i, J j) {} diff --git a/test/files/run/reflection-mem-glbs.scala b/test/files/run/reflection-mem-glbs.scala index 790a445cc6d7..fe3c9a83e8ff 100644 --- a/test/files/run/reflection-mem-glbs.scala +++ b/test/files/run/reflection-mem-glbs.scala @@ -1,4 +1,4 @@ -// java: -Xmx512m +//> using javaOpt -Xmx512m import scala.tools.partest.MemoryTest diff --git a/test/files/run/reflection-mem-tags.scala b/test/files/run/reflection-mem-tags.scala index 0ae1b9406afb..dbd434b4422c 100644 --- a/test/files/run/reflection-mem-tags.scala +++ b/test/files/run/reflection-mem-tags.scala @@ -1,4 +1,4 @@ -// java: -Xmx512m +//> using javaOpt -Xmx512m import scala.tools.partest.MemoryTest diff --git a/test/files/run/reflection-valueclasses-magic.scala b/test/files/run/reflection-valueclasses-magic.scala index bc461f629359..07cd824283e6 100644 --- a/test/files/run/reflection-valueclasses-magic.scala +++ b/test/files/run/reflection-valueclasses-magic.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe.definitions._ diff --git a/test/files/run/reify_copypaste1.scala b/test/files/run/reify_copypaste1.scala index 16b6ffed21c7..d11dcc563043 100644 --- a/test/files/run/reify_copypaste1.scala +++ b/test/files/run/reify_copypaste1.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.forked.jvm +//> using javaOpt -Dneeds.forked.jvm import scala.reflect.runtime._ import scala.reflect.runtime.universe._ diff --git a/test/files/run/repl-assign.check b/test/files/run/repl-assign.check index 300638ba5202..247fbbd8252d 100644 --- a/test/files/run/repl-assign.check +++ b/test/files/run/repl-assign.check @@ -1,14 +1,14 @@ -scala> var x = 10 -var x: Int = 10 +scala> var x = 42 +var x: Int = 42 -scala> var y = 11 -var y: Int = 11 +scala> x = 17 +// mutated x -scala> x = 12 +scala> x += 10 // mutated x -scala> y = 13 -// mutated y +scala> x +val res0: Int = 27 scala> :quit diff --git a/test/files/run/repl-assign.scala b/test/files/run/repl-assign.scala index 4b540c9557cd..7c12d3d2b4d7 100644 --- a/test/files/run/repl-assign.scala +++ b/test/files/run/repl-assign.scala @@ -1,10 +1,4 @@ -import scala.tools.partest.ReplTest -object Test extends ReplTest { - def code = """ -var x = 10 -var y = 11 -x = 12 -y = 13 - """ -} +import scala.tools.partest.SessionTest + +object Test extends SessionTest diff --git a/test/files/run/repl-paste-6.check b/test/files/run/repl-paste-6.check old mode 100755 new mode 100644 diff --git a/test/files/run/repl-paste-error.check b/test/files/run/repl-paste-error.check index 5842b7bdc2cf..265b69e83d5d 100644 --- a/test/files/run/repl-paste-error.check +++ b/test/files/run/repl-paste-error.check @@ -15,11 +15,7 @@ END 42 ^ -:3: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - - 42 - ^ -:3: warning: a pure expression does nothing in statement position +:3: warning: discarded pure expression does nothing def f(): Unit scala> :quit diff --git a/test/files/run/repl-paste-parse.check b/test/files/run/repl-paste-parse.check deleted file mode 100755 index 02b42a4da518..000000000000 --- a/test/files/run/repl-paste-parse.check +++ /dev/null @@ -1,8 +0,0 @@ - -val case = 9 - ^ -repl-paste-parse.script:1: error: illegal start of simple pattern - -scala> - -scala> :quit diff --git a/test/files/run/repl-paste-parse.scala b/test/files/run/repl-paste-parse.scala deleted file mode 100644 index 9f10c9abe68b..000000000000 --- a/test/files/run/repl-paste-parse.scala +++ /dev/null @@ -1,19 +0,0 @@ -import scala.tools.partest.ReplTest -import scala.tools.nsc.Settings -import scala.tools.nsc.GenericRunnerSettings -import scala.tools.nsc.settings.MutableSettings - -object Test extends ReplTest { - def scriptPath = testPath.changeExtension("script") - override def transformSettings(s: Settings) = s match { - case m: MutableSettings => - val t = new GenericRunnerSettings(s.errorFn) - m copyInto t - t processArgumentString s"-usejavacp -i $scriptPath" - t - case _ => s - } - - def code = "" -} - diff --git a/test/files/run/repl-paste-parse.script b/test/files/run/repl-paste-parse.script deleted file mode 100644 index 903f6e7b0c07..000000000000 --- a/test/files/run/repl-paste-parse.script +++ /dev/null @@ -1 +0,0 @@ -val case = 9 diff --git a/test/files/run/sd187.check b/test/files/run/sd187.check index 2c97874a2a65..ff192d9bf60e 100644 --- a/test/files/run/sd187.check +++ b/test/files/run/sd187.check @@ -51,8 +51,8 @@ [1112:1126] val x2: [1120]Product2[T1,T2] = [1120]([1120][1120]x1.asInstanceOf[[1120]Product2[T1,T2]]: [1120]Product2[T1,T2]); [1112:1120]{ [1112:1120] val o8: [1112]Option[Product2[T1,T2]] = [1112:1120][1112:1120][1112:1120]scala.Product2.unapply[[1112]T1, [1112]T2]([1112]x2); - [1121:1211]if ([1112]o8.isEmpty.unary_!) - [1121:1211]{ + [1112:1211]if ([1112]o8.isEmpty.unary_!) + [1112:1211]{ [1121:1122]val a: [1121]Any = [1121]o8.get._1; [1210:1211][1210]matchEnd5([1210:1211]a) } @@ -73,13 +73,13 @@ [1403:2204]def swatch: [1407]String = [1505:2106]try { [1607:1615][1607:1615][1607]C.this.toString() } catch { - [1505:2106]case [1505](ex6 @ [1505]_) => [1812:1824]{ + [1812:2022]case [1812](ex6 @ [1812]_) => [1812:1824]{ [1812:1824] val x4: [1812]Throwable = [1812]ex6; [1812:1824]case9(){ [1812:1824]if ([1812][1812]x4.ne([1812]null)) [1812:2022]{ [1812:1824] val x5: [1812]Throwable = [1812]x4; - [1912:2022]if ([1912:1922][1912:1922][1912:1914]"".isEmpty()) + [1812:2022]if ([1912:1922][1912:1922][1912:1914]"".isEmpty()) [2012:2022][2014]matchEnd8([2014][2014]x5.toString()) else [1812][1812]case10() @@ -87,11 +87,11 @@ else [1812][1812]case10() }; - [1505]case10(){ - [1505][1505]matchEnd8([1505]throw [1505]ex6) + [1812]case10(){ + [1812][1812]matchEnd8([1812]throw [1812]ex6) }; - [1505]matchEnd8(x: [NoPosition]String){ - [1505]x + [1812]matchEnd8(x: [NoPosition]String){ + [1812]x } } } diff --git a/test/files/run/sd884.check b/test/files/run/sd884.check new file mode 100644 index 000000000000..d64c0b9305bd --- /dev/null +++ b/test/files/run/sd884.check @@ -0,0 +1,186 @@ + +scala> import annotation._, scala.util.chaining._ +import annotation._ +import scala.util.chaining._ + +scala> class ann(x: Int = 1, y: Int = 2) extends Annotation +class ann + +scala> class naa(x: Int = 1, y: Int = 2) extends Annotation { + def this(s: String) = this(1, 2) +} +class naa + +scala> class mul(x: Int = 1, y: Int = 2)(z: Int = 3, zz: Int = 4) extends Annotation +class mul + +scala> class kon(x: Int = 1, y: Int = 2) extends ConstantAnnotation +class kon + +scala> class rann(x: Int = 1.tap(println), y: Int) extends Annotation +class rann + +scala> class C { + val a = 1 + val b = 2 + + @ann(y = b, x = a) def m1 = 1 + + @ann(x = a) def m2 = 1 + @ann(y = b) def m3 = 1 + + @naa(a, b) def m4 = 1 + @naa(y = b, x = a) def m5 = 1 + @naa("") def m6 = 1 + + // warn, only first argument list is kept + @mul(a, b)(a, b) def m7 = 1 + @mul(y = b)(a, b) def m8 = 1 + @mul(y = b, x = a)(zz = b) def m9 = 1 + @mul(y = b)(zz = b) def m10 = 1 + + @kon(y = 22) def m11 = 1 + @kon(11) def m12 = 1 +} + @mul(a, b)(a, b) def m7 = 1 + ^ +On line 15: warning: Implementation limitation: multiple argument lists on annotations are + currently not supported; ignoring arguments List(C.this.a, C.this.b) + @mul(y = b)(a, b) def m8 = 1 + ^ +On line 16: warning: Implementation limitation: multiple argument lists on annotations are + currently not supported; ignoring arguments List(C.this.a, C.this.b) + @mul(y = b, x = a)(zz = b) def m9 = 1 + ^ +On line 17: warning: Implementation limitation: multiple argument lists on annotations are + currently not supported; ignoring arguments List(3, C.this.b) + @mul(y = b)(zz = b) def m10 = 1 + ^ +On line 18: warning: Implementation limitation: multiple argument lists on annotations are + currently not supported; ignoring arguments List(3, C.this.b) +class C + +scala> :power +Power mode enabled. :phase is at typer. +import scala.tools.nsc._, intp.global._, definitions._ +Try :help or completions for vals._ and power._ + +scala> println(typeOf[C].members.toList.filter(_.name.startsWith("m")).sortBy(_.name).map(_.annotations.head).mkString("\n")) +ann(C.this.a, C.this.b) +mul(1, C.this.b) +kon(y = 22) +kon(x = 11) +ann(C.this.a, 2) +ann(1, C.this.b) +naa(C.this.a, C.this.b) +naa(C.this.a, C.this.b) +naa("") +mul(C.this.a, C.this.b) +mul(1, C.this.b) +mul(C.this.a, C.this.b) + +scala> val i6 = typeOf[C].member(TermName("m6")).annotations.head +val i6: $r.intp.global.AnnotationInfo = naa("") + +scala> i6.constructorSymbol(global.typer.typed).paramss +val res1: List[List[$r.intp.global.Symbol]] = List(List(value s)) + +scala> val i11 = typeOf[C].member(TermName("m11")).annotations.head +val i11: $r.intp.global.AnnotationInfo = kon(y = 22) + +scala> i11.assocs +val res2: List[($r.intp.global.Name, $r.intp.global.ClassfileAnnotArg)] = List((y,22)) + +scala> i11.assocsWithDefaults +val res3: List[($r.intp.global.Name, $r.intp.global.ClassfileAnnotArg)] = List((x,1), (y,22)) + +scala> val i3 = typeOf[C].member(TermName("m3")).annotations.head +val i3: $r.intp.global.AnnotationInfo = ann(1, C.this.b) + +scala> i3.args.map(_.tpe) +val res4: List[$r.intp.global.Type] = List(Int(1) @scala.annotation.meta.defaultArg, Int) + +scala> i3.args.map(i3.argIsDefault) +val res5: List[Boolean] = List(true, false) + +scala> // ordinary named/default args when using annotation class in executed code + +scala> new rann(y = 2.tap(println)); () // prints 2, then the default 1 +2 +1 + +scala> @rann(y = {new rann(y = 2.tap(println)); 2}) class r1 +class r1 + +scala> println(typeOf[r1].typeSymbol.annotations.head.args) +List(scala.util.`package`.chaining.scalaUtilChainingOps[Int](1).tap[Unit](((x: Any) => scala.Predef.println(x))), { + { + val x$1: Int = scala.util.`package`.chaining.scalaUtilChainingOps[Int](2).tap[Unit](((x: Any) => scala.Predef.println(x))); + val x$2: Int = $line17.$read.INSTANCE.$iw.rann.$default$1; + new $line17.$read.INSTANCE.$iw.rann(x$2, x$1) + }; + 2 +}) + +scala> // subclassing + +scala> class sub1(z: Int = 3) extends ann(11, z) +class sub1 + +scala> class sub2(z: Int = 3) extends ann(y = z) +class sub2 + +scala> class suk(z: Int = 3) extends kon(y = 22) +class suk + +scala> class sum(z: Int) extends mul(11, 22)(z) +class sum + +scala> println(typeOf[sub1].typeSymbol.annotations) +List(scala.annotation.meta.superArg("x", 11), scala.annotation.meta.superFwdArg("y", "z")) + +scala> println(typeOf[sub2].typeSymbol.annotations) +List(scala.annotation.meta.superArg("x", 1), scala.annotation.meta.superFwdArg("y", "z")) + +scala> println(typeOf[suk].typeSymbol.annotations) +List(scala.annotation.meta.superArg("y", 22)) + +scala> println(typeOf[sum].typeSymbol.annotations) // none +List() + +scala> class D { + val a = 1 + + @sub1() def m1 = 1 + @sub1(a) def m2 = 1 + @sub2 def m3 = 1 + @sub2(33) def m4 = 1 + + @suk() def k1 = 1 + @suk(33) def k2 = 1 +} +class D + +scala> val ms = typeOf[D].members.toList.filter(_.name.startsWith("m")).sortBy(_.name).map(_.annotations.head) +val ms: List[$r.intp.global.AnnotationInfo] = List(sub1(3), sub1(D.this.a), sub2(3), sub2(33)) + +scala> ms.foreach(m => {println(m.args); println(m.argsForSuper(typeOf[ann].typeSymbol)) }) +List(3) +List(11, 3) +List(D.this.a) +List(11, D.this.a) +List(3) +List(1, 3) +List(33) +List(1, 33) + +scala> val ks = typeOf[D].members.toList.filter(_.name.startsWith("k")).sortBy(_.name).map(_.annotations.head) +val ks: List[$r.intp.global.AnnotationInfo] = List(suk, suk(z = 33)) + +scala> ks.foreach(k => {println(k.assocs); println(k.assocsForSuper(typeOf[kon].typeSymbol)) }) +List() +List((y,22)) +List((z,33)) +List((y,22)) + +scala> :quit diff --git a/test/files/run/sd884.scala b/test/files/run/sd884.scala new file mode 100644 index 000000000000..ec45116e7440 --- /dev/null +++ b/test/files/run/sd884.scala @@ -0,0 +1,74 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def code = + """import annotation._, scala.util.chaining._ + |class ann(x: Int = 1, y: Int = 2) extends Annotation + |class naa(x: Int = 1, y: Int = 2) extends Annotation { + | def this(s: String) = this(1, 2) + |} + |class mul(x: Int = 1, y: Int = 2)(z: Int = 3, zz: Int = 4) extends Annotation + |class kon(x: Int = 1, y: Int = 2) extends ConstantAnnotation + |class rann(x: Int = 1.tap(println), y: Int) extends Annotation + |class C { + | val a = 1 + | val b = 2 + | + | @ann(y = b, x = a) def m1 = 1 + | + | @ann(x = a) def m2 = 1 + | @ann(y = b) def m3 = 1 + | + | @naa(a, b) def m4 = 1 + | @naa(y = b, x = a) def m5 = 1 + | @naa("") def m6 = 1 + | + | // warn, only first argument list is kept + | @mul(a, b)(a, b) def m7 = 1 + | @mul(y = b)(a, b) def m8 = 1 + | @mul(y = b, x = a)(zz = b) def m9 = 1 + | @mul(y = b)(zz = b) def m10 = 1 + | + | @kon(y = 22) def m11 = 1 + | @kon(11) def m12 = 1 + |} + |:power + |println(typeOf[C].members.toList.filter(_.name.startsWith("m")).sortBy(_.name).map(_.annotations.head).mkString("\n")) + |val i6 = typeOf[C].member(TermName("m6")).annotations.head + |i6.constructorSymbol(global.typer.typed).paramss + |val i11 = typeOf[C].member(TermName("m11")).annotations.head + |i11.assocs + |i11.assocsWithDefaults + |val i3 = typeOf[C].member(TermName("m3")).annotations.head + |i3.args.map(_.tpe) + |i3.args.map(i3.argIsDefault) + |// ordinary named/default args when using annotation class in executed code + |new rann(y = 2.tap(println)); () // prints 2, then the default 1 + |@rann(y = {new rann(y = 2.tap(println)); 2}) class r1 + |println(typeOf[r1].typeSymbol.annotations.head.args) + |// subclassing + |class sub1(z: Int = 3) extends ann(11, z) + |class sub2(z: Int = 3) extends ann(y = z) + |class suk(z: Int = 3) extends kon(y = 22) + |class sum(z: Int) extends mul(11, 22)(z) + |println(typeOf[sub1].typeSymbol.annotations) + |println(typeOf[sub2].typeSymbol.annotations) + |println(typeOf[suk].typeSymbol.annotations) + |println(typeOf[sum].typeSymbol.annotations) // none + |class D { + | val a = 1 + | + | @sub1() def m1 = 1 + | @sub1(a) def m2 = 1 + | @sub2 def m3 = 1 + | @sub2(33) def m4 = 1 + | + | @suk() def k1 = 1 + | @suk(33) def k2 = 1 + |} + |val ms = typeOf[D].members.toList.filter(_.name.startsWith("m")).sortBy(_.name).map(_.annotations.head) + |ms.foreach(m => {println(m.args); println(m.argsForSuper(typeOf[ann].typeSymbol)) }) + |val ks = typeOf[D].members.toList.filter(_.name.startsWith("k")).sortBy(_.name).map(_.annotations.head) + |ks.foreach(k => {println(k.assocs); println(k.assocsForSuper(typeOf[kon].typeSymbol)) }) + |""".stripMargin +} diff --git a/test/files/run/sd884b.check b/test/files/run/sd884b.check new file mode 100644 index 000000000000..f3369404f848 --- /dev/null +++ b/test/files/run/sd884b.check @@ -0,0 +1,54 @@ + +scala> class B { + @ann(x = 11) def m1 = 1 + @ann(y = 22) def m2 = 1 + + @kon(x = 11) def k1 = 1 + @kon(y = 22) def k2 = 1 +} +class B + +scala> :power +Power mode enabled. :phase is at typer. +import scala.tools.nsc._, intp.global._, definitions._ +Try :help or completions for vals._ and power._ + +scala> def t(tp: Type) = { + val ms = tp.members.toList.filter(_.name.startsWith("m")).sortBy(_.name) + for (m <- ms) { + val i = m.annotations.head + println(i) + println(i.args.map(_.tpe)) + println(i.args.map(i.argIsDefault)) + } + val ks = tp.members.toList.filter(_.name.startsWith("k")).sortBy(_.name) + ks.foreach(k => println(k.annotations.head)) + ks.foreach(k => println(k.annotations.head.assocsWithDefaults)) +} +def t(tp: $r.intp.global.Type): Unit + +scala> t(typeOf[A]) +ann(11, T.i) +List(Int, Int @scala.annotation.meta.defaultArg) +List(false, true) +ann(1, 22) +List(Int(1) @scala.annotation.meta.defaultArg, Int) +List(true, false) +kon(x = 11) +kon(y = 22) +List((x,11), (y,2)) +List((x,1), (y,22)) + +scala> t(typeOf[B]) +ann(11, T.i) +List(Int(11), Int @scala.annotation.meta.defaultArg) +List(false, true) +ann(1, 22) +List(Int @scala.annotation.meta.defaultArg, Int(22)) +List(true, false) +kon(x = 11) +kon(y = 22) +List((x,11), (y,2)) +List((x,1), (y,22)) + +scala> :quit diff --git a/test/files/run/sd884b/A.scala b/test/files/run/sd884b/A.scala new file mode 100644 index 000000000000..77524c80ff98 --- /dev/null +++ b/test/files/run/sd884b/A.scala @@ -0,0 +1,12 @@ +class ann(x: Int = 1, y: Int = T.i) extends annotation.StaticAnnotation +class kon(x: Int = 1, y: Int = 2) extends annotation.ConstantAnnotation + +object T { def i = 0 } + +class A { + @ann(x = 11) def m1 = 1 + @ann(y = 22) def m2 = 1 + + @kon(x = 11) def k1 = 1 + @kon(y = 22) def k2 = 1 +} diff --git a/test/files/run/sd884b/Test_1.scala b/test/files/run/sd884b/Test_1.scala new file mode 100644 index 000000000000..84e619eae845 --- /dev/null +++ b/test/files/run/sd884b/Test_1.scala @@ -0,0 +1,28 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def code = + """class B { + | @ann(x = 11) def m1 = 1 + | @ann(y = 22) def m2 = 1 + | + | @kon(x = 11) def k1 = 1 + | @kon(y = 22) def k2 = 1 + |} + |:power + |def t(tp: Type) = { + | val ms = tp.members.toList.filter(_.name.startsWith("m")).sortBy(_.name) + | for (m <- ms) { + | val i = m.annotations.head + | println(i) + | println(i.args.map(_.tpe)) + | println(i.args.map(i.argIsDefault)) + | } + | val ks = tp.members.toList.filter(_.name.startsWith("k")).sortBy(_.name) + | ks.foreach(k => println(k.annotations.head)) + | ks.foreach(k => println(k.annotations.head.assocsWithDefaults)) + |} + |t(typeOf[A]) + |t(typeOf[B]) + |""".stripMargin +} diff --git a/test/files/run/sequenceComparisons.scala b/test/files/run/sequenceComparisons.scala index 7304745ea248..183b7257412a 100644 --- a/test/files/run/sequenceComparisons.scala +++ b/test/files/run/sequenceComparisons.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation import scala.collection.{ mutable, immutable } import collection.Seq diff --git a/test/files/run/settings-parse.check b/test/files/run/settings-parse.check index 03c363b55186..10401a66435b 100644 --- a/test/files/run/settings-parse.check +++ b/test/files/run/settings-parse.check @@ -12,55 +12,46 @@ 3) List(-cp, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 4) List(-cp, , , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 5) List(-cp, , -deprecation, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 6) List(, -cp, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 7) List(-cp, , -deprecation, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 8) List(-cp, , , -deprecation, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 9) List(-cp, , -deprecation, , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 10) List(-cp, , -deprecation, foo.scala, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 11) List(, -cp, , -deprecation, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } @@ -82,115 +73,96 @@ 16) List(-cp, , foo.scala, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 17) List(-cp, , , foo.scala, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 18) List(-cp, , foo.scala, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 19) List(-cp, , foo.scala, -deprecation, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 20) List(, -cp, , foo.scala, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 21) List(-deprecation, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 22) List(, -deprecation, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 23) List(-deprecation, -cp, , ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 24) List(-deprecation, , -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 25) List(-deprecation, -cp, , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 26) List(, -deprecation, -cp, , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 27) List(-deprecation, -cp, , , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 28) List(-deprecation, -cp, , foo.scala, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 29) List(-deprecation, , -cp, , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 30) List(-deprecation, foo.scala, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 31) List(, -deprecation, foo.scala, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 32) List(-deprecation, , foo.scala, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 33) List(-deprecation, foo.scala, -cp, , ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 34) List(-deprecation, foo.scala, , -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } @@ -212,61 +184,51 @@ 39) List(foo.scala, -cp, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 40) List(, foo.scala, -cp, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 41) List(foo.scala, -cp, , , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 42) List(foo.scala, -cp, , -deprecation, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 43) List(foo.scala, , -cp, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 44) List(foo.scala, -deprecation, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 45) List(, foo.scala, -deprecation, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 46) List(foo.scala, , -deprecation, -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 47) List(foo.scala, -deprecation, -cp, , ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } 48) List(foo.scala, -deprecation, , -cp, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = "" } @@ -284,55 +246,46 @@ 3) List(-cp, /tmp:/bippy, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 4) List(-cp, /tmp:/bippy, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 5) List(-cp, /tmp:/bippy, -deprecation, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 6) List(, -cp, /tmp:/bippy, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 7) List(-cp, /tmp:/bippy, -deprecation, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 8) List(-cp, /tmp:/bippy, , -deprecation, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 9) List(-cp, /tmp:/bippy, -deprecation, , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 10) List(-cp, /tmp:/bippy, -deprecation, foo.scala, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 11) List(, -cp, /tmp:/bippy, -deprecation, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } @@ -354,115 +307,96 @@ 16) List(-cp, /tmp:/bippy, foo.scala, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 17) List(-cp, /tmp:/bippy, , foo.scala, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 18) List(-cp, /tmp:/bippy, foo.scala, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 19) List(-cp, /tmp:/bippy, foo.scala, -deprecation, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 20) List(, -cp, /tmp:/bippy, foo.scala, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 21) List(-deprecation, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 22) List(, -deprecation, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 23) List(-deprecation, -cp, /tmp:/bippy, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 24) List(-deprecation, , -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 25) List(-deprecation, -cp, /tmp:/bippy, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 26) List(, -deprecation, -cp, /tmp:/bippy, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 27) List(-deprecation, -cp, /tmp:/bippy, , foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 28) List(-deprecation, -cp, /tmp:/bippy, foo.scala, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 29) List(-deprecation, , -cp, /tmp:/bippy, foo.scala) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 30) List(-deprecation, foo.scala, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 31) List(, -deprecation, foo.scala, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 32) List(-deprecation, , foo.scala, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 33) List(-deprecation, foo.scala, -cp, /tmp:/bippy, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 34) List(-deprecation, foo.scala, , -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } @@ -484,61 +418,51 @@ 39) List(foo.scala, -cp, /tmp:/bippy, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 40) List(, foo.scala, -cp, /tmp:/bippy, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 41) List(foo.scala, -cp, /tmp:/bippy, , -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 42) List(foo.scala, -cp, /tmp:/bippy, -deprecation, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 43) List(foo.scala, , -cp, /tmp:/bippy, -deprecation) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 44) List(foo.scala, -deprecation, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 45) List(, foo.scala, -deprecation, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 46) List(foo.scala, , -deprecation, -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 47) List(foo.scala, -deprecation, -cp, /tmp:/bippy, ) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } 48) List(foo.scala, -deprecation, , -cp, /tmp:/bippy) ==> Settings { -deprecation = true - -Wconf = List(cat=deprecation:w, cat=deprecation:ws, cat=feature:ws, cat=optimizer:ws) -classpath = /tmp:/bippy } diff --git a/test/files/run/shutdownhooks.scala b/test/files/run/shutdownhooks.scala index 1d22ea78380d..df076fd0a118 100644 --- a/test/files/run/shutdownhooks.scala +++ b/test/files/run/shutdownhooks.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.forked.jvm +//> using javaOpt -Dneeds.forked.jvm object Test { scala.sys.addShutdownHook { diff --git a/test/files/run/sip23-rangepos.scala b/test/files/run/sip23-rangepos.scala index 69cf08b3c6d4..a3dad706310c 100644 --- a/test/files/run/sip23-rangepos.scala +++ b/test/files/run/sip23-rangepos.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // object Test extends App { val foo: "foo" = "foo" diff --git a/test/files/run/source3Xrun.scala b/test/files/run/source3Xrun.scala index 8ebb44d49f2a..3ed48a23c156 100644 --- a/test/files/run/source3Xrun.scala +++ b/test/files/run/source3Xrun.scala @@ -1,4 +1,4 @@ -//> using options -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:_ // StringContext hygiene class SC1 { diff --git a/test/files/run/staticQualifier.check b/test/files/run/staticQualifier.check new file mode 100644 index 000000000000..fe81901643b0 --- /dev/null +++ b/test/files/run/staticQualifier.check @@ -0,0 +1,3 @@ +42 +hai +42 diff --git a/test/files/run/staticQualifier/A_1.scala b/test/files/run/staticQualifier/A_1.scala new file mode 100644 index 000000000000..d056596542f5 --- /dev/null +++ b/test/files/run/staticQualifier/A_1.scala @@ -0,0 +1,21 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object A { + def foo(x: Int): Int = macro foo_impl + + def foo_impl(c: Context)(x: c.Expr[Int]): c.Tree = { + val g = c.universe.asInstanceOf[scala.tools.nsc.Global] + import g._ + import scala.tools.nsc.symtab.Flags._ + + val t = x.tree.asInstanceOf[Tree] match { + case s @ Select(_, n) if n.toString == "f2" => + val field = s.symbol.accessed + field.setFlag(STATIC).resetFlag(PRIVATE | LOCAL) + s.setSymbol(field) + } + + t.asInstanceOf[c.Tree] + } +} diff --git a/test/files/run/staticQualifier/Test_2.scala b/test/files/run/staticQualifier/Test_2.scala new file mode 100644 index 000000000000..bff989413cdb --- /dev/null +++ b/test/files/run/staticQualifier/Test_2.scala @@ -0,0 +1,24 @@ +import scala.tools.partest.BytecodeTest +import scala.tools.testkit.ASMConverters._ +import scala.tools.asm.Opcodes._ + +object Test extends BytecodeTest { + val f2 = 42 + + def getT: Test.type = { + println("hai") + Test + } + + def show(): Unit = { + println(A.foo(Test.f2)) + println(A.foo(getT.f2)) + + val ins = instructionsFromMethod(getMethod(loadClassNode("Test$"), "show")) + val gs = ins.count { + case Field(GETSTATIC, "Test$", "f2", _) => true + case _ => false + } + assert(gs == 2) + } +} diff --git a/test/files/run/stream-gc.scala b/test/files/run/stream-gc.scala index 182ba3244b70..decacf669fa8 100644 --- a/test/files/run/stream-gc.scala +++ b/test/files/run/stream-gc.scala @@ -1,4 +1,4 @@ -// java: -Xmx5M -Xms5M +//> using javaOpt -Xmx5M -Xms5M import scala.collection.immutable._ diff --git a/test/files/run/string-switch-pos.check b/test/files/run/string-switch-pos.check index 27ea7da767af..59a35068b477 100644 --- a/test/files/run/string-switch-pos.check +++ b/test/files/run/string-switch-pos.check @@ -10,7 +10,7 @@ [56:57][56:57]x1 match { [56:57]case [75:81]"AaAa" => [93:94]1 [56:57]case [104:110]"asdf" => [122:123]2 - [133:139]case [133:139]"BbBb" => [143:181]if ([143:147]cond) + [133:181]case [133:139]"BbBb" => [133:181]if ([143:147]cond) [151:152]3 else [180:181]4 @@ -35,12 +35,12 @@ [56][56]case4() else [56][56]defaultCase1() - [75:81]case [56]2031744 => [75:81]if ([75][75][75]"AaAa".equals([75]x1)) - [93:94][75]matchEnd1([93:94]1) + [56:81]case [56]2031744 => [75:81]if ([75][75][75]"AaAa".equals([75]x1)) + [75:94][75]matchEnd1([93:94]1) else [56][56]defaultCase1() - [133:139]case [56]2062528 => [133:139]if ([133][133][133]"BbBb".equals([133]x1)) - [143:181][133]matchEnd1([143:181]if ([143:147]cond) + [56:139]case [56]2062528 => [133:139]if ([133][133][133]"BbBb".equals([133]x1)) + [133:181][133]matchEnd1([133:181]if ([143:147]cond) [151:152]3 else [180:181]4) @@ -50,8 +50,8 @@ [56][56]case4() else [56][56]defaultCase1() - [104:110]case [56]3003444 => [104:110]if ([104][104][104]"asdf".equals([104]x1)) - [122:123][104]matchEnd1([122:123]2) + [56:110]case [56]3003444 => [104:110]if ([104][104][104]"asdf".equals([104]x1)) + [104:123][104]matchEnd1([122:123]2) else [56][56]defaultCase1() [56]case [56]_ => [56][56]defaultCase1() diff --git a/test/files/run/string-switch.scala b/test/files/run/string-switch.scala index 6a1522b416d9..fb1d5f9ffa7a 100644 --- a/test/files/run/string-switch.scala +++ b/test/files/run/string-switch.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import annotation.switch import util.Try diff --git a/test/files/run/substSymRefinementOwner.check b/test/files/run/substSymRefinementOwner.check new file mode 100644 index 000000000000..d0768e38b9bc --- /dev/null +++ b/test/files/run/substSymRefinementOwner.check @@ -0,0 +1,31 @@ + +scala> :power +Power mode enabled. :phase is at typer. +import scala.tools.nsc._, intp.global._, definitions._ +Try :help or completions for vals._ and power._ + +scala> class C { + def f = new { + def g = new { + def h = 1 + } + } +} +class C + +scala> val f = typeOf[C].decl(TermName("f")) +val f: $r.intp.global.Symbol = method f + +scala> val g = f.tpe.resultType.decls.head +val g: $r.intp.global.Symbol = method g + +scala> g.ownerChain.take(4) +val res0: List[$r.intp.global.Symbol] = List(method g, , method f, class C) + +scala> g.tpe.resultType.typeSymbol +val res1: $r.intp.global.Symbol = + +scala> g.tpe.resultType.typeSymbol.ownerChain.take(4) +val res2: List[$r.intp.global.Symbol] = List(, method g, , method f) + +scala> :quit diff --git a/test/files/run/substSymRefinementOwner.scala b/test/files/run/substSymRefinementOwner.scala new file mode 100644 index 000000000000..d7077c2d2f72 --- /dev/null +++ b/test/files/run/substSymRefinementOwner.scala @@ -0,0 +1,19 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = + """:power + |class C { + | def f = new { + | def g = new { + | def h = 1 + | } + | } + |} + |val f = typeOf[C].decl(TermName("f")) + |val g = f.tpe.resultType.decls.head + |g.ownerChain.take(4) + |g.tpe.resultType.typeSymbol + |g.tpe.resultType.typeSymbol.ownerChain.take(4) + |""".stripMargin +} diff --git a/test/files/run/synchronized.scala b/test/files/run/synchronized.scala index 8cd024f60755..a8e0fb5375cd 100644 --- a/test/files/run/synchronized.scala +++ b/test/files/run/synchronized.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt:none +//> using options -opt:inline:** -Wopt:none import java.lang.Thread.holdsLock import scala.collection.mutable.StringBuilder diff --git a/test/files/run/t10203.scala b/test/files/run/t10203.scala index c718ee7995c7..c4d02f3a88b2 100644 --- a/test/files/run/t10203.scala +++ b/test/files/run/t10203.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:typer -Yrangepos -Ystop-after:typer -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:typer -Ystop-after:typer -cp ${testOutput.path}" override def code = """ object X { diff --git a/test/files/run/t10231/A_1.java b/test/files/run/t10231/A_1.java index db6d46a22f98..1f37b878f297 100644 --- a/test/files/run/t10231/A_1.java +++ b/test/files/run/t10231/A_1.java @@ -1,4 +1,4 @@ -// javac: -parameters +//> using javacOpt -parameters public class A_1 { public class Inner { public int x; diff --git a/test/files/run/t10240.check b/test/files/run/t10240.check new file mode 100644 index 000000000000..68646df19745 --- /dev/null +++ b/test/files/run/t10240.check @@ -0,0 +1,33 @@ + +List apply 1 +[0:12][0:10]List.apply([11:12]1) +List apply 1 + +List apply[Int] 2 +[0:17][0:15][0:10]List.apply[[11:14]Int]([16:17]2) +List apply[Int] 2 +List apply[Int] + +List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) +[0:72][0:63][0:52]List.apply[List[Int]](List(1), List(2)).mapConserve[[53:62][53:57]List[[58:61]Any]]([65:71](([65:66]x) => [70:71]x)) +List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x) +List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] +List apply[List[Int]] + +1 ->[Int] 2 +[0:11][0:9][0:4]1.$minus$greater[[5:8]Int]([10:11]2) +1 ->[Int] 2 +1 ->[Int] + +new A() op [Int, String ] 42 +[0:36][0:32][0:10]new A().op[[13:16]Int, [20:26]String]([34:36]42) +new A() op [Int, String ] 42 +new A() op [Int, String ] + +42 ::[Int] Nil +[0:14]{ + [0:2]final val rassoc$1 = [0:2]42; + [3:14]<3:14><3:14>Nil.$colon$colon[[6:9]Int]([0]rassoc$1) +} +42 ::[Int] Nil +::[Int] Nil diff --git a/test/files/run/t10240.scala b/test/files/run/t10240.scala new file mode 100644 index 000000000000..e4d28baae2ba --- /dev/null +++ b/test/files/run/t10240.scala @@ -0,0 +1,35 @@ +object Test extends App { + import scala.reflect.internal.util.StringContextStripMarginOps + import scala.reflect.runtime._ + import scala.reflect.runtime.universe._ + import scala.tools.reflect.ToolBox + + val mirror = universe.runtimeMirror(universe.getClass.getClassLoader) + val toolbox = mirror.mkToolBox() + def showParsed(code: String) = { + val parsed = toolbox.parse(code) + def codeOf(pos: Position) = code.substring(pos.start, pos.end) + val recovered = codeOf(parsed.pos) + val pieces = parsed.collect { + case tree @ TypeApply(fun, args) => codeOf(tree.pos) + } + val display = + if (pieces.isEmpty) recovered + else + sm"""|$recovered + |${pieces.mkString("\n")}""" + println { + sm"""| + |$code + |${show(parsed, printPositions = true)} + |$display""" + } + } + showParsed("List apply 1") + showParsed("List apply[Int] 2") + showParsed("List apply[List[Int]] (List(1), List(2)) mapConserve[List[Any]] (x => x)") + showParsed("1 ->[Int] 2") + //def op[A, B](i: Int): Int = 2*i + showParsed("new A() op [Int, String ] 42") + showParsed("42 ::[Int] Nil") +} diff --git a/test/files/run/t10283.scala b/test/files/run/t10283.scala index a206aa010976..8a432fdec202 100644 --- a/test/files/run/t10283.scala +++ b/test/files/run/t10283.scala @@ -1,4 +1,4 @@ -// scalac: -Xsource:2.13 +//> using options -Xsource:2.13 // trait OpacityTypes { type T diff --git a/test/files/run/t10439.scala b/test/files/run/t10439.scala index 6b2f077cbdd2..a96a79095a04 100644 --- a/test/files/run/t10439.scala +++ b/test/files/run/t10439.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // object Test { private var s: String = _ diff --git a/test/files/run/t10450/A.java b/test/files/run/t10450/A.java index 062d267a1d9d..efef3d1a53fb 100644 --- a/test/files/run/t10450/A.java +++ b/test/files/run/t10450/A.java @@ -1,4 +1,4 @@ -// filter: unchecked +//> using filter unchecked package a; class B> { diff --git a/test/files/run/t10539.scala b/test/files/run/t10539.scala index 00a0abe6b5ca..fe120eee956e 100644 --- a/test/files/run/t10539.scala +++ b/test/files/run/t10539.scala @@ -1,4 +1,4 @@ -// scalac: -Xdev +//> using options -Xdev // class A { def ==(a: A) = "LOL" diff --git a/test/files/run/t10692.scala b/test/files/run/t10692.scala index 23f2a8f1b779..de41e5d562d9 100644 --- a/test/files/run/t10692.scala +++ b/test/files/run/t10692.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // trait T { private var s: String = _ diff --git a/test/files/run/t10699/A_1.java b/test/files/run/t10699/A_1.java index 2dbfaf160b30..4fa02d8d7371 100644 --- a/test/files/run/t10699/A_1.java +++ b/test/files/run/t10699/A_1.java @@ -1,4 +1,4 @@ -// javac: -parameters +//> using javacOpt -parameters public class A_1 { public T identity_inst(T t, T other) { return t; } public static T identity_static(T t, T other) { return t; } diff --git a/test/files/run/t10751.scala b/test/files/run/t10751.scala index bcef4e169a3f..1c019b4e78a9 100644 --- a/test/files/run/t10751.scala +++ b/test/files/run/t10751.scala @@ -3,7 +3,7 @@ import scala.tools.partest.DirectTest object Test extends DirectTest { override def extraSettings: String = - s"-usejavacp -Vprint-pos -Vprint:typer -Yrangepos -Ystop-after:typer -cp ${testOutput.path}" + s"-usejavacp -Vprint-pos -Vprint:typer -Ystop-after:typer -cp ${testOutput.path}" override def code = """ object Test { diff --git a/test/files/run/t11042.scala b/test/files/run/t11042.scala index c0acbcbed328..cdb7fca04e7f 100644 --- a/test/files/run/t11042.scala +++ b/test/files/run/t11042.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation +//> using options -Xlint:deprecation object Test extends App { def f(xs: Array[Int]): Boolean = xs.isInstanceOf[scala.collection.immutable.Seq[_]] def g(xs: Int*): Boolean = xs.isInstanceOf[scala.collection.immutable.Seq[_]] diff --git a/test/files/run/t11255/A_1.scala b/test/files/run/t11255/A_1.scala index ad879d0c16f8..2c7eef1fa0d2 100644 --- a/test/files/run/t11255/A_1.scala +++ b/test/files/run/t11255/A_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** class K(val f: Int => Int) extends Serializable class A { @inline final def f = new K(x => x + 1) diff --git a/test/files/run/t11255/Test_2.scala b/test/files/run/t11255/Test_2.scala index 3a257086c6a4..eec0b877a672 100644 --- a/test/files/run/t11255/Test_2.scala +++ b/test/files/run/t11255/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** object Test { def serializeDeserialize(obj: Object): Object = { import java.io._ diff --git a/test/files/run/t11534c.scala b/test/files/run/t11534c.scala index a1fbaf0d72e6..1563a6dfac44 100644 --- a/test/files/run/t11534c.scala +++ b/test/files/run/t11534c.scala @@ -1,4 +1,4 @@ -// scalac: -unchecked +//> using options -unchecked import scala.util.Try object Test { diff --git a/test/files/run/t1167.scala b/test/files/run/t1167.scala index 13d715e3f3f3..d1cb83be67f8 100644 --- a/test/files/run/t1167.scala +++ b/test/files/run/t1167.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline /** Tests for compatible InnerClasses attribute between trait and * impl classes, as well as anonymous classes. */ diff --git a/test/files/run/t11938.scala b/test/files/run/t11938.scala index e52cfd50e54a..cf48c82fdf1a 100644 --- a/test/files/run/t11938.scala +++ b/test/files/run/t11938.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wunused +//> using options -Werror -Wunused object Test extends App { for (x @ 1 <- List(1.0)) { assert(x.isInstanceOf[Double]) diff --git a/test/files/run/t12062.scala b/test/files/run/t12062.scala index fb278bcfef94..0817367896ba 100644 --- a/test/files/run/t12062.scala +++ b/test/files/run/t12062.scala @@ -1,7 +1,7 @@ import scala.tools.partest._ object Test extends CompilerTest { - override def extraSettings = super.extraSettings + " -Yrangepos" + override def sources = List( number("TestByte", "val value:Byte = 1.toByte"), number("TestShort", "val value:Short = 1.toShort"), diff --git a/test/files/run/t12071.scala b/test/files/run/t12071.scala index e22f73b8550e..4144181cd160 100644 --- a/test/files/run/t12071.scala +++ b/test/files/run/t12071.scala @@ -1,4 +1,4 @@ -//> using options -Werror -Xlint -Xsource:3-cross +//> using options -Werror -Xlint -Xsource:3 -Xsource-features:_ class C { def `c c`(n: Int): Int = n + 1 diff --git a/test/files/run/t12074-norange.check b/test/files/run/t12074-norange.check new file mode 100644 index 000000000000..f643ba9eb93b --- /dev/null +++ b/test/files/run/t12074-norange.check @@ -0,0 +1,6 @@ + +2 + 2 +[0:5][0:3]2.$plus([4]2) + +List(42).map(_ + 27) +[12][9]List(42).map([13:19](([13]x$1) => [13:19][13:16]x$1.$plus([17]27))) diff --git a/test/files/run/t12074-norange.scala b/test/files/run/t12074-norange.scala new file mode 100644 index 000000000000..f74e9719c9ad --- /dev/null +++ b/test/files/run/t12074-norange.scala @@ -0,0 +1,19 @@ + +object Test extends App { + import scala.reflect.internal.util.StringContextStripMarginOps + import scala.reflect.runtime._, universe._ + import scala.tools.reflect.ToolBox + + val mirror = universe.runtimeMirror(universe.getClass.getClassLoader) + val toolbox = mirror.mkToolBox(options = "-Yrangepos:false") + def showParsed(code: String) = { + val parsed = toolbox.parse(code) + println { + sm"""| + |$code + |${show(parsed, printPositions = true)}""" + } + } + showParsed("2 + 2") + showParsed("List(42).map(_ + 27)") +} diff --git a/test/files/run/t12198.scala b/test/files/run/t12198.scala new file mode 100644 index 000000000000..fcdf0ac3e04c --- /dev/null +++ b/test/files/run/t12198.scala @@ -0,0 +1,22 @@ + +class C { + def f = List(null: _*) +} +object Test extends App { + import scala.tools.testkit.AssertUtil._ + val c = new C + assertThrows[NullPointerException](c.f) +} +/* +java.lang.NullPointerException: Cannot invoke "scala.collection.IterableOnce.knownSize()" because "prefix" is null + at scala.collection.immutable.List.prependedAll(List.scala:148) + at scala.collection.immutable.List$.from(List.scala:685) + at scala.collection.immutable.List$.from(List.scala:682) + at scala.collection.IterableFactory.apply(Factory.scala:103) + at scala.collection.IterableFactory.apply$(Factory.scala:103) + at scala.collection.immutable.List$.apply(List.scala:682) + at C.f(t12198.scala:3) + +was exception caught in pickler: +error: erroneous or inaccessible type +*/ diff --git a/test/files/run/t12222.check b/test/files/run/t12222.check deleted file mode 100644 index 573541ac9702..000000000000 --- a/test/files/run/t12222.check +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/files/run/t12222/Test_2.scala b/test/files/run/t12222/Test_2.scala index a5c975cd349e..bf908d84c5cb 100644 --- a/test/files/run/t12222/Test_2.scala +++ b/test/files/run/t12222/Test_2.scala @@ -2,6 +2,6 @@ object Test { def main(args: Array[String]): Unit = { val vertices = Array[Float]() val attribute = new Float32Buffer(vertices) - println(attribute.count) + assert(attribute.count == 0) } -} \ No newline at end of file +} diff --git a/test/files/run/t12289.check b/test/files/run/t12289.check new file mode 100644 index 000000000000..9d709dc7502b --- /dev/null +++ b/test/files/run/t12289.check @@ -0,0 +1,2 @@ +pos: source-newSource1.scala,line-3,offset=41 not found: type T +A class on the class path is shadowed by a companion artifact currently compiled; companions must be compiled together. ERROR diff --git a/test/files/run/t12289.scala b/test/files/run/t12289.scala new file mode 100644 index 000000000000..b642fdd77aa0 --- /dev/null +++ b/test/files/run/t12289.scala @@ -0,0 +1,39 @@ + +import scala.reflect.io.AbstractFile +import scala.tools.nsc._ +import scala.tools.partest.StoreReporterDirectTest +import scala.util.chaining._ + +object Test extends StoreReporterDirectTest { + var round = 0 + val rounds = List( + "package p { trait T }", + sm"""|package p { + | object T + | class C extends T + |}""", + ) + def code = rounds(round).tap(_ => round += 1) + // intercept the settings created for compile() + override def newSettings(args: List[String]) = { + val outDir = testOutput / s"test-output-$round" + def prevOutDir = testOutput / s"test-output-${round - 1}" + outDir.createDirectory(force = true) + val af = AbstractFile.getDirectory(outDir) + // put the previous round on the class path + val args1 = if (round > 0) "-cp" :: prevOutDir.path :: args else args + super.newSettings(args1) + .tap(_.outputDirs.setSingleOutput(af)) + } + // avoid setting -d + override def newCompiler(args: String*): Global = { + val settings = newSettings(tokenize(extraSettings) ++ args.toList) + newCompiler(settings) + } + // report helpful message when output dir is programmatically set + def show() = { + assert(compile()) + assert(!compile()) + filteredInfos.foreach(println) + } +} diff --git a/test/files/run/t12289b.check b/test/files/run/t12289b.check new file mode 100644 index 000000000000..0f5c4efa54da --- /dev/null +++ b/test/files/run/t12289b.check @@ -0,0 +1,2 @@ +pos: RangePosition(newSource1.scala, 72, 72, 73) not found: value T +A value on the class path is shadowed by a companion artifact currently compiled; companions must be compiled together. ERROR diff --git a/test/files/run/t12289b.scala b/test/files/run/t12289b.scala new file mode 100644 index 000000000000..191322e05f1d --- /dev/null +++ b/test/files/run/t12289b.scala @@ -0,0 +1,41 @@ + +import scala.reflect.io.AbstractFile +import scala.tools.nsc._ +import scala.tools.partest.StoreReporterDirectTest +import scala.util.chaining._ + +object Test extends StoreReporterDirectTest { + var round = 0 + val rounds = List( + "package p { object T }", + sm"""|package p { + | trait T + | class C extends T { + | def companion: AnyRef = T + | } + |}""", + ) + def code = rounds(round).tap(_ => round += 1) + // intercept the settings created for compile() + override def newSettings(args: List[String]) = { + val outDir = testOutput / s"test-output-$round" + def prevOutDir = testOutput / s"test-output-${round - 1}" + outDir.createDirectory(force = true) + val af = AbstractFile.getDirectory(outDir) + // put the previous round on the class path + val args1 = if (round > 0) "-cp" :: prevOutDir.path :: args else args + super.newSettings(args1) + .tap(_.outputDirs.setSingleOutput(af)) + } + // avoid setting -d + override def newCompiler(args: String*): Global = { + val settings = newSettings(tokenize(extraSettings) ++ args.toList) + newCompiler(settings) + } + // report helpful message when output dir is programmatically set + def show() = { + assert(compile()) + assert(!compile()) + filteredInfos.foreach(println) + } +} diff --git a/test/files/run/t12289c.check b/test/files/run/t12289c.check new file mode 100644 index 000000000000..9d709dc7502b --- /dev/null +++ b/test/files/run/t12289c.check @@ -0,0 +1,2 @@ +pos: source-newSource1.scala,line-3,offset=41 not found: type T +A class on the class path is shadowed by a companion artifact currently compiled; companions must be compiled together. ERROR diff --git a/test/files/run/t12289c.scala b/test/files/run/t12289c.scala new file mode 100644 index 000000000000..beb1c3b9d269 --- /dev/null +++ b/test/files/run/t12289c.scala @@ -0,0 +1,38 @@ + +import scala.tools.nsc._ +import scala.tools.partest.StoreReporterDirectTest +import scala.util.chaining._ + +object Test extends StoreReporterDirectTest { + var round = 0 + def code1 = "package p { trait T }" + def code2 = + sm"""|package p { + | object T + | class C extends T + |}""" + def code = + if (round > 0) code2 + else code1.tap(_ => round += 1) + // intercept the settings created for compile() + override def newSettings(args: List[String]) = { + val outDir = testOutput / s"test-output-$round" + def prevOutDir = testOutput / s"test-output-${round - 1}" + outDir.createDirectory(force = true) + // put the previous round on the class path + val args1 = if (round > 0) "-cp" :: prevOutDir.path :: args else args + super.newSettings(args1) + .tap(_.outputDirs.add(srcDir = testPath.parent.path, outDir = outDir.path)) + } + // avoid setting -d + override def newCompiler(args: String*): Global = { + val settings = newSettings(tokenize(extraSettings) ++ args.toList) + newCompiler(settings) + } + // report helpful message when output dir is programmatically set + def show() = { + assert(compile()) + assert(!compile()) + filteredInfos.foreach(println) + } +} diff --git a/test/files/run/t12290/Test.scala b/test/files/run/t12290/Test.scala index 904dde2e141f..cc6257cb838c 100644 --- a/test/files/run/t12290/Test.scala +++ b/test/files/run/t12290/Test.scala @@ -1,4 +1,4 @@ -// javaVersion: 15+ +//> using jvm 15+ /* Using `valueOf` is a way to check that the Java string literals were properly * parsed, since the parsed value is what the Scala compiler will use when * resolving the singleton types diff --git a/test/files/run/t12301.scala b/test/files/run/t12301.scala new file mode 100644 index 000000000000..048af4894cff --- /dev/null +++ b/test/files/run/t12301.scala @@ -0,0 +1,36 @@ +trait P { + def p: String = "p" +} + +object X extends P { + override final val p = "x" +} + +object X2 extends P { + override final val p: "x" = "x" +} + +trait Q { + def q: Int = 27 +} + +object Y extends Q { + override final val q = 42 +} + +object Y2 extends Q { + override final val q: 42 = 42 +} + +class K { + def k: Class[_] = classOf[K] +} + +object L extends K { + override final val k = classOf[L.type] +} + +// was: Exception in thread "main" java.lang.ClassFormatError: Duplicate method name "p" with signature "()Ljava.lang.String;" in class file X$ +object Test extends App { + (X, Y, L) +} diff --git a/test/files/run/t12301b/E.java b/test/files/run/t12301b/E.java new file mode 100644 index 000000000000..9e719d0bad33 --- /dev/null +++ b/test/files/run/t12301b/E.java @@ -0,0 +1,4 @@ + +enum E { + X, Y; +} diff --git a/test/files/run/t12301b/Test.scala b/test/files/run/t12301b/Test.scala new file mode 100644 index 000000000000..04884f6e5aeb --- /dev/null +++ b/test/files/run/t12301b/Test.scala @@ -0,0 +1,11 @@ +trait P { + def p: E = E.X +} + +object X extends P { + override final val p = E.Y +} + +object Test extends App { + (X, X.p) +} diff --git a/test/files/run/t12301c.scala b/test/files/run/t12301c.scala new file mode 100644 index 000000000000..7f06233c30e5 --- /dev/null +++ b/test/files/run/t12301c.scala @@ -0,0 +1,11 @@ + +trait T { + private final val HASH_SIZE = 0x8000 +} +class C { + private final val HASH_SIZE = 0x8000 +} +object Test extends App { + assert(new C().toString != null) + assert(new T {}.toString != null) +} diff --git a/test/files/run/t12348.scala b/test/files/run/t12348.scala index eddac0626950..a55cf9d60317 100644 --- a/test/files/run/t12348.scala +++ b/test/files/run/t12348.scala @@ -1,5 +1,5 @@ -// javaVersion: 11+ -// scalac: -release:11 +//> using jvm 11+ +//> using options -release:11 // this a sequel to t7965. that one only tests MethodHandle. JDK 11 added // signature polymorphic methods to VarHandle, so let's test that too diff --git a/test/files/run/t12380/A.java b/test/files/run/t12380/A.java index 1cdbd7e83bbf..c636f2f906ab 100644 --- a/test/files/run/t12380/A.java +++ b/test/files/run/t12380/A.java @@ -1,4 +1,4 @@ -// filter: unchecked +//> using filter unchecked package p; diff --git a/test/files/run/t12490.scala b/test/files/run/t12490.scala index 422ef3fb4222..0f106b9cbf0a 100644 --- a/test/files/run/t12490.scala +++ b/test/files/run/t12490.scala @@ -3,7 +3,7 @@ import scala.collection.mutable.LinkedHashMap object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos -Ystop-after:parser" + override def extraSettings = super.extraSettings + " -Ystop-after:parser" val tests = LinkedHashMap( "class A { def t = new C() }" -> (24, 31), "class B { def t = (new C) }" -> (25, 30), diff --git a/test/files/run/t12597.scala b/test/files/run/t12597.scala index f3e75da8e848..09f2cf6104f1 100644 --- a/test/files/run/t12597.scala +++ b/test/files/run/t12597.scala @@ -3,7 +3,7 @@ import scala.collection.mutable.LinkedHashMap object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos -Ystop-after:parser" + override def extraSettings = super.extraSettings + " -Ystop-after:parser" val tests = List( "class A1 { def t = }", "class A2 { def t = }", diff --git a/test/files/run/t12720.check b/test/files/run/t12720.check new file mode 100644 index 000000000000..34016b50a0a1 --- /dev/null +++ b/test/files/run/t12720.check @@ -0,0 +1,38 @@ +newSource1.scala:14: error: missing argument list for method f*** in class D*** +with overloaded members in D*** + (x***: Int***): String*** + (x***: String***): String*** +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `f _` or `f(_)` instead of `f`. + def f = d.f + ^ +newSource1.scala:9: warning: private constructor in class Test*** is never used + private def this(stuff: Int) = this() + ^ +newSource1.scala:11: warning: private class Subtle*** in class Test*** is never used + private class Subtle + ^ +newSource1.scala:15: warning: parameter x*** in method g*** is never used + def g(x: Int) = println("error") + ^ +newSource1.scala:19: warning: local method m*** in method forgone*** is never used + def m = 17 + ^ +newSource1.scala:20: warning: local object j*** in method forgone*** is never used + object j + ^ +newSource1.scala:21: warning: local var totally*** in method forgone*** is never used + var totally = 27 + ^ +newSource1.scala:22: warning: local var unset*** in method forgone*** is never updated: consider using immutable val + var unset: Int = 0 + ^ +newSource1.scala:23: warning: local val z*** in method forgone*** is never used + val z = unset + ^ +newSource1.scala:27: warning: private var misbegotten*** in class Test*** is never used + private var misbegotten: Int = 42 + ^ +newSource1.scala:29: warning: private var forgotten (forgotten_=***) in class Test*** is never updated: consider using immutable val + private var forgotten: Int = 42 + ^ diff --git a/test/files/run/t12720.scala b/test/files/run/t12720.scala new file mode 100644 index 000000000000..5f8a186a2952 --- /dev/null +++ b/test/files/run/t12720.scala @@ -0,0 +1,54 @@ +import scala.tools.partest.DirectTest +import scala.tools.nsc.Settings +import scala.tools.nsc.reporters.ConsoleReporter +import scala.reflect.internal.util.{CodeAction, Position} + +object Test extends DirectTest { + override def extraSettings = "-uniqid -usejavacp -Werror -Wunused" + + def code = """ +class C { + def f(x: Int) = "" +} +class D extends C { + def f(x: String) = "" +} +final class Test { + private def this(stuff: Int) = this() + + private class Subtle + + val d = new D + def f = d.f + def g(x: Int) = println("error") + + // -Vprint shows two symbols `y` + def forgone(i: Int) = { + def m = 17 + object j + var totally = 27 + var unset: Int = 0 + val z = unset + for (x <- Option(42); y <- Option(27) if x < i; res = x - y) yield res + } + + private var misbegotten: Int = 42 + def touch() = misbegotten = 17 + private var forgotten: Int = 42 + def fetch = forgotten +}""" + + override def reporter(settings: Settings) = new HidingReporter(settings, raw"#\d+") + + def show() = assert(!compile()) +} + +class HidingReporter(settings: Settings, pattern: String) extends ConsoleReporter(settings) { + + val hider = pattern.r + + def hiding(msg: String) = hider.replaceAllIn(msg, _ => "***") + + override def doReport(pos: Position, msg: String, severity: Severity, actions: List[CodeAction]): Unit = + super.doReport(pos, hiding(msg), severity, actions) +} diff --git a/test/files/run/t12799/Test_2.scala b/test/files/run/t12799/Test_2.scala index 030b48e35068..8463af1e831f 100644 --- a/test/files/run/t12799/Test_2.scala +++ b/test/files/run/t12799/Test_2.scala @@ -1,5 +1,5 @@ -// scalac: -Xlint +//> using options -Xlint import example._ diff --git a/test/files/run/t12918.scala b/test/files/run/t12918.scala index 3bd0a1689bdd..addb794fef93 100644 --- a/test/files/run/t12918.scala +++ b/test/files/run/t12918.scala @@ -1,4 +1,4 @@ -// javaVersion: 9+ +//> using jvm 9+ import java.util.concurrent._ import scala.jdk.FutureConverters._ diff --git a/test/files/run/t13004.check b/test/files/run/t13004.check new file mode 100644 index 000000000000..470466c9be83 --- /dev/null +++ b/test/files/run/t13004.check @@ -0,0 +1,4 @@ +t13004.scala:12: applied implicit conversion from Money to ?{def + : ?} = implicit def MoneySyntax(self: Money): Money.MoneySyntax + Money(3.14) + Money(1.7) + ^ +Money(4.84) diff --git a/test/files/run/t13004.scala b/test/files/run/t13004.scala new file mode 100644 index 000000000000..961de34d6c4a --- /dev/null +++ b/test/files/run/t13004.scala @@ -0,0 +1,14 @@ +//> using options -Xsource:3 -Xsource-features:any2stringadd -Vimplicit-conversions + +case class Money(value: Double) +object Money { + implicit class MoneySyntax(private val self: Money) extends AnyVal { + def +(other: Money): Money = Money(self.value + other.value) + } +} + +object Test extends App { + println { + Money(3.14) + Money(1.7) + } +} diff --git a/test/files/run/t13004c.check b/test/files/run/t13004c.check new file mode 100644 index 000000000000..143a6deffc1a --- /dev/null +++ b/test/files/run/t13004c.check @@ -0,0 +1,7 @@ +t13004c.scala:9: applied implicit conversion from Money to ?{def + : ?} = final implicit def any2stringadd[A](self: A): any2stringadd[A] + Money(3.14) + " is a lotta dough!" + ^ +t13004c.scala:9: warning: method any2stringadd in object Predef is deprecated (since 2.13.0): Implicit injection of + is deprecated. Convert to String to call + + Money(3.14) + " is a lotta dough!" + ^ +Money(3.14) is a lotta dough! diff --git a/test/files/run/t13004c.scala b/test/files/run/t13004c.scala new file mode 100644 index 000000000000..b0848b335dd4 --- /dev/null +++ b/test/files/run/t13004c.scala @@ -0,0 +1,11 @@ +//> using options -Vimplicit-conversions -Xlint -Xsource:3 -Xsource-features:any2stringadd + +import scala.Predef.* + +case class Money(value: Double) + +object Test extends App { + println { + Money(3.14) + " is a lotta dough!" + } +} diff --git a/test/files/run/t13007/J.java b/test/files/run/t13007/J.java new file mode 100644 index 000000000000..da76473a48c0 --- /dev/null +++ b/test/files/run/t13007/J.java @@ -0,0 +1,7 @@ +package j; + +public class J { + protected boolean i() { return false; } + protected boolean j() { return false; } + public boolean k() { return false; } +} diff --git a/test/files/run/t13007/Test.scala b/test/files/run/t13007/Test.scala new file mode 100644 index 000000000000..b8ec25cab188 --- /dev/null +++ b/test/files/run/t13007/Test.scala @@ -0,0 +1,33 @@ +package s { + + trait T { + self: j.J => + override def i(): Boolean = true + + def t1 = i() + def t2 = this.i() + def t3 = self.i() + + // def t4 = j() + // def t5 = this.j() + // def t6 = self.j() + + def t7 = k() + def t8 = this.k() + def t9 = self.k() + } + + class C extends j.J with T +} + +object Test { + def main(args: Array[String]): Unit = { + val c = new s.C + assert(c.t1) + assert(c.t2) + assert(c.t3) + assert(!c.t7) + assert(!c.t8) + assert(!c.t9) + } +} diff --git a/test/files/run/t13022.scala b/test/files/run/t13022.scala new file mode 100644 index 000000000000..f1e3752cd35b --- /dev/null +++ b/test/files/run/t13022.scala @@ -0,0 +1,23 @@ + +case class StringValue(value: String) extends AnyVal + +trait Foo[A] { + def singleMethod(arg: A): StringValue +} + +class R { + val foo1: Foo[Int] = new Foo[Int] { + override def singleMethod(arg: Int): StringValue = new StringValue(arg.toString) + } + val foo2: Foo[Int] = (arg: Int) => new StringValue(arg.toString) + val foo3 = (arg: Int) => new StringValue(arg.toString) + + def run() = { + assert(foo1.singleMethod(1).toString == "StringValue(1)") + assert(foo2.singleMethod(1).toString == "StringValue(1)") // throws ClassCastException + assert(foo3(1).toString == "StringValue(1)") + } +} +object Test extends App { + new R().run() +} diff --git a/test/files/run/t13033.scala b/test/files/run/t13033.scala new file mode 100644 index 000000000000..c9daec5c6b89 --- /dev/null +++ b/test/files/run/t13033.scala @@ -0,0 +1,56 @@ +//> using options -deprecation + +import scala.util.hashing.MurmurHash3.caseClassHash + +case class C1(a: Int) +class C2(a: Int) extends C1(a) { override def productPrefix = "C2" } +class C3(a: Int) extends C1(a) { override def productPrefix = "C3" } +case class C4(a: Int) { override def productPrefix = "Sea4" } +case class C5() +case object C6 +case object C6b { override def productPrefix = "Sea6b" } +case class C7(s: String) // hashCode forwards to ScalaRunTime._hashCode if there are no primitives +class C8(s: String) extends C7(s) { override def productPrefix = "C8" } + +case class VCC(x: Int) extends AnyVal + +object Test extends App { + val c1 = C1(1) + val c2 = new C2(1) + val c3 = new C3(1) + assert(c1 == c2) + assert(c2 == c1) + assert(c2 == c3) + assert(c1.hashCode == c2.hashCode) + assert(c2.hashCode == c3.hashCode) + + assert(c1.hashCode == caseClassHash(c1)) + // `caseClassHash` mixes in the `productPrefix.hashCode`, while `hashCode` mixes in the case class name statically + assert(c2.hashCode != caseClassHash(c2)) + assert(c2.hashCode == caseClassHash(c2, c1.productPrefix)) + + val c4 = C4(1) + assert(c4.hashCode != caseClassHash(c4)) + assert(c4.hashCode == caseClassHash(c4, "C4")) + + assert((1, 2).hashCode == caseClassHash(1 -> 2)) + assert(("", "").hashCode == caseClassHash("" -> "")) + + assert(C5().hashCode == caseClassHash(C5())) + assert(C6.hashCode == caseClassHash(C6)) + assert(C6b.hashCode == caseClassHash(C6b, "C6b")) + + val c7 = C7("hi") + val c8 = new C8("hi") + assert(c7.hashCode == caseClassHash(c7)) + assert(c7 == c8) + assert(c7.hashCode == c8.hashCode) + assert(c8.hashCode != caseClassHash(c8)) + assert(c8.hashCode == caseClassHash(c8, "C7")) + + + // should be true -- scala/bug#13034 + assert(!VCC(1).canEqual(VCC(1))) + // also due to scala/bug#13034 + assert(VCC(1).canEqual(1)) +} diff --git a/test/files/run/t13038.check b/test/files/run/t13038.check new file mode 100644 index 000000000000..af7eaa38b4c6 --- /dev/null +++ b/test/files/run/t13038.check @@ -0,0 +1,9 @@ + +scala> import scala.util.chaining.given +import scala.util.chaining.given + +scala> 42.tap(println) +42 +val res0: Int = 42 + +scala> :quit diff --git a/test/files/run/t13038.scala b/test/files/run/t13038.scala new file mode 100644 index 000000000000..bcb6b743a745 --- /dev/null +++ b/test/files/run/t13038.scala @@ -0,0 +1,6 @@ + +import scala.tools.partest.SessionTest + +object Test extends SessionTest { + override def extraSettings = s"${super.extraSettings} -Xsource:3" +} diff --git a/test/files/run/t13043.scala b/test/files/run/t13043.scala new file mode 100644 index 000000000000..0889a6c34116 --- /dev/null +++ b/test/files/run/t13043.scala @@ -0,0 +1,30 @@ +class C(val x: String) extends AnyVal + +object TC { + def c(s: String): C = new C(s) + def p = 2 + def test(v: Int, w: Int): Any = + v match { + case 1 if p == w => c("a") + case _ => c("b") + } +} + +object TI { + def c(i: Int): Int = i + def p = 2 + def test(v: Int, w: Int): Any = + v match { + case 1 if p == w => c(42) + case _ => c(43) + } +} + +object Test extends App { + assert(TC.test(1, 2).asInstanceOf[C].x == "a") + assert(TC.test(1, 3).asInstanceOf[C].x == "b") + assert(TC.test(2, 2).asInstanceOf[C].x == "b") + assert(TI.test(1, 2) == 42) + assert(TI.test(1, 3) == 43) + assert(TI.test(2, 2) == 43) +} \ No newline at end of file diff --git a/test/files/run/t13050.check b/test/files/run/t13050.check new file mode 100644 index 000000000000..81b4b1ba6b6f --- /dev/null +++ b/test/files/run/t13050.check @@ -0,0 +1,8 @@ + +scala> import scala.tools.partest.async.OptionAwait._ +import scala.tools.partest.async.OptionAwait._ + +scala> println(optionally { value(Some(1)) + value(Some(2)) }) +Some(3) + +scala> :quit diff --git a/test/files/run/t13050.scala b/test/files/run/t13050.scala new file mode 100644 index 000000000000..16f1abcbe8d4 --- /dev/null +++ b/test/files/run/t13050.scala @@ -0,0 +1,9 @@ +import scala.tools.nsc._ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def extraSettings = "-Xasync" + def code = + """import scala.tools.partest.async.OptionAwait._ + |println(optionally { value(Some(1)) + value(Some(2)) })""".stripMargin +} diff --git a/test/files/run/t13087.check b/test/files/run/t13087.check new file mode 100644 index 000000000000..a7a0c5d0f1ca --- /dev/null +++ b/test/files/run/t13087.check @@ -0,0 +1,43 @@ + +scala> :power +Power mode enabled. :phase is at typer. +import scala.tools.nsc._, intp.global._, definitions._ +Try :help or completions for vals._ and power._ + +scala> @ann class K +class K + +scala> typeOf[K] +val res0: $r.intp.global.Type = K + +scala> val arg = typeOf[K].typeSymbol.annotations.head.args.head +val arg: $r.intp.global.Tree = kux.f.+(new O[Int]().a(1)) + +scala> val plusSel = arg.asInstanceOf[Apply].fun +val plusSel: $r.intp.global.Tree = kux.f.+ + +scala> plusSel.tpe +val res1: $r.intp.global.Type = (x: Int): Int + +scala> plusSel.symbol.tpe +val res2: $r.intp.global.Type = (x: Int): Int + +scala> val fSel = plusSel.asInstanceOf[Select].qualifier +val fSel: $r.intp.global.Tree = kux.f + +scala> fSel.tpe +val res3: $r.intp.global.Type = Int + +scala> fSel.symbol.tpe +val res4: $r.intp.global.Type = Int + +scala> val aSel = arg.asInstanceOf[Apply].args.head.asInstanceOf[Apply].fun +val aSel: $r.intp.global.Tree = new O[Int]().a + +scala> aSel.tpe +val res5: $r.intp.global.Type = (t: Int): Int + +scala> aSel.symbol.tpe +val res6: $r.intp.global.Type = (t: T): T + +scala> :quit diff --git a/test/files/run/t13087/A.scala b/test/files/run/t13087/A.scala new file mode 100644 index 000000000000..0b5435294571 --- /dev/null +++ b/test/files/run/t13087/A.scala @@ -0,0 +1,10 @@ +class ann(key: Int = kux.f + new O[Int].a(1)) extends annotation.StaticAnnotation + +object kux { + def f = 1 + def f(x: Int) = 2 +} +class O[T] { + def a(t: T): T = t + def a(s: String): String = s +} diff --git a/test/files/run/t13087/Test_1.scala b/test/files/run/t13087/Test_1.scala new file mode 100644 index 000000000000..cc1b62c762cf --- /dev/null +++ b/test/files/run/t13087/Test_1.scala @@ -0,0 +1,19 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def code = + """:power + |@ann class K + |typeOf[K] + |val arg = typeOf[K].typeSymbol.annotations.head.args.head + |val plusSel = arg.asInstanceOf[Apply].fun + |plusSel.tpe + |plusSel.symbol.tpe + |val fSel = plusSel.asInstanceOf[Select].qualifier + |fSel.tpe + |fSel.symbol.tpe + |val aSel = arg.asInstanceOf[Apply].args.head.asInstanceOf[Apply].fun + |aSel.tpe + |aSel.symbol.tpe + |""".stripMargin +} diff --git a/test/files/run/t13307b/J.java b/test/files/run/t13307b/J.java new file mode 100644 index 000000000000..da76473a48c0 --- /dev/null +++ b/test/files/run/t13307b/J.java @@ -0,0 +1,7 @@ +package j; + +public class J { + protected boolean i() { return false; } + protected boolean j() { return false; } + public boolean k() { return false; } +} diff --git a/test/files/run/t13307b/Test.scala b/test/files/run/t13307b/Test.scala new file mode 100644 index 000000000000..1af616cf5780 --- /dev/null +++ b/test/files/run/t13307b/Test.scala @@ -0,0 +1,27 @@ +package s { + + trait T extends j.J { + override def i(): Boolean = true + + def t1 = i() + def t2 = this.i() + + // def t4 = j() + // def t5 = this.j() + + def t7 = k() + def t8 = this.k() + } + + class C extends j.J with T +} + +object Test { + def main(args: Array[String]): Unit = { + val c = new s.C + assert(c.t1) + assert(c.t2) + assert(!c.t7) + assert(!c.t8) + } +} diff --git a/test/files/run/t1980.scala b/test/files/run/t1980.scala index 62375005b771..365918cef735 100644 --- a/test/files/run/t1980.scala +++ b/test/files/run/t1980.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // class LazyList[+A](expr: => LazyList.Evaluated[A]) { def #:: [B >: A](elem: => B): LazyList[B] = new LazyList(Some((elem, this))) diff --git a/test/files/run/t1987.scala b/test/files/run/t1987.scala index e826911b9388..e3531e579a8c 100644 --- a/test/files/run/t1987.scala +++ b/test/files/run/t1987.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // a.scala // Fri Jan 13 11:31:47 PST 2012 diff --git a/test/files/run/t2106.scala b/test/files/run/t2106.scala index 4699ef662796..43d660acde22 100644 --- a/test/files/run/t2106.scala +++ b/test/files/run/t2106.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt // class A extends Cloneable { @inline final def foo = clone() diff --git a/test/files/run/t2318.scala b/test/files/run/t2318.scala index c7592037842a..9f69d360a8f9 100644 --- a/test/files/run/t2318.scala +++ b/test/files/run/t2318.scala @@ -1,6 +1,6 @@ -// scalac: -Xlint:deprecation -// java: -Ddummy=fresh_jvm_needed_to_test_security_manager -// filter: WARNING.* +//> using options -Xlint:deprecation +//> using javaOpt -Ddummy=fresh_jvm_needed_to_test_security_manager +//> using filter WARNING.* // for now, ignore warnings due to reflective invocation import java.security._ diff --git a/test/files/run/t2509-1.scala b/test/files/run/t2509-1.scala index 7f834462c49e..ef9822fe7a3d 100644 --- a/test/files/run/t2509-1.scala +++ b/test/files/run/t2509-1.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution import scala.language.implicitConversions class A diff --git a/test/files/run/t2509-4.scala b/test/files/run/t2509-4.scala index 474fb22e11be..e385dcedd92f 100644 --- a/test/files/run/t2509-4.scala +++ b/test/files/run/t2509-4.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution import scala.language.implicitConversions class A diff --git a/test/files/run/t3038b.scala b/test/files/run/t3038b.scala index 6f1c055837a9..16a7ef86228a 100644 --- a/test/files/run/t3038b.scala +++ b/test/files/run/t3038b.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // class A { val a1 = 1 diff --git a/test/files/run/t3038d.scala b/test/files/run/t3038d.scala index fe2820d2542c..ac73e0b6f539 100644 --- a/test/files/run/t3038d.scala +++ b/test/files/run/t3038d.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // trait Foo { @transient protected var load = 1 diff --git a/test/files/run/t3194.scala b/test/files/run/t3194.scala index c6e0cd53f85d..982a9f40c1db 100644 --- a/test/files/run/t3194.scala +++ b/test/files/run/t3194.scala @@ -1,4 +1,4 @@ -// scalac: -language:_ +//> using options -language:_ import scala.util.chaining._ class A(var x: Int) diff --git a/test/files/run/t3220-213.scala b/test/files/run/t3220-213.scala index a33d94ffefc6..ba8380e8df05 100644 --- a/test/files/run/t3220-213.scala +++ b/test/files/run/t3220-213.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // object Literals { diff --git a/test/files/run/t3220-214.scala b/test/files/run/t3220-214.scala index 3ca0634a6d52..45f6376ca50c 100644 --- a/test/files/run/t3220-214.scala +++ b/test/files/run/t3220-214.scala @@ -1,4 +1,4 @@ -//> using options -Xmigration -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:unicode-escapes-raw object Literals214 { def inTripleQuoted = """\u000A""" diff --git a/test/files/run/t3235-minimal.scala b/test/files/run/t3235-minimal.scala index 9a95dad59d11..5154a126da66 100644 --- a/test/files/run/t3235-minimal.scala +++ b/test/files/run/t3235-minimal.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // object Test { def main(args: Array[String]): Unit = { diff --git a/test/files/run/t3326.scala b/test/files/run/t3326.scala index 2c9b3f40ac75..cbed2a4c4858 100644 --- a/test/files/run/t3326.scala +++ b/test/files/run/t3326.scala @@ -1,4 +1,4 @@ -// scalac: -Wopt +//> using options -Wopt import scala.math.Ordering /** The heart of the problem - we want to retain the ordering when diff --git a/test/files/run/t3488.check b/test/files/run/t3488.check deleted file mode 100644 index 7799c78d9769..000000000000 --- a/test/files/run/t3488.check +++ /dev/null @@ -1,14 +0,0 @@ -t3488.scala:4: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - println(foo { val List(_*)=List(0); 1 } ()) - ^ -t3488.scala:4: warning: a pure expression does nothing in statement position - println(foo { val List(_*)=List(0); 1 } ()) - ^ -t3488.scala:5: warning: multiline expressions might require enclosing parentheses; a value can be silently discarded when Unit is expected - println(foo { val List(_*)=List(0); 1 } (1)) - ^ -t3488.scala:5: warning: a pure expression does nothing in statement position - println(foo { val List(_*)=List(0); 1 } (1)) - ^ -0 -1 diff --git a/test/files/run/t3488.scala b/test/files/run/t3488.scala index a8cfa9b808d8..92295ca5a1db 100644 --- a/test/files/run/t3488.scala +++ b/test/files/run/t3488.scala @@ -1,6 +1,8 @@ +//> using options -Wconf:cat=other-pure-statement:silent + object Test extends App { - def foo(p: => Unit)(x:Int = 0) = x + def foo(p: => Unit)(x: Int = 0) = x - println(foo { val List(_*)=List(0); 1 } ()) - println(foo { val List(_*)=List(0); 1 } (1)) + assert(foo { val List(_*)=List(0); 42 } () == 0) + assert(foo { val List(_*)=List(0); 42 } (1) == 1) } diff --git a/test/files/run/t3509.scala b/test/files/run/t3509.scala index 1d89a838c580..dbd6a17b022f 100644 --- a/test/files/run/t3509.scala +++ b/test/files/run/t3509.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test { diff --git a/test/files/run/t3569.scala b/test/files/run/t3569.scala index b393e9dcf6a1..4e77df08e49f 100644 --- a/test/files/run/t3569.scala +++ b/test/files/run/t3569.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test { final val bippy1 = 1 diff --git a/test/files/run/t3664.scala b/test/files/run/t3664.scala index 4bb679d9c050..5d683b6127c7 100644 --- a/test/files/run/t3664.scala +++ b/test/files/run/t3664.scala @@ -1,7 +1,7 @@ -//> using options -Xlint -Xsource:3-cross +//> using options -Xsource:3 -Xsource-features:case-companion-function,eta-expand-always -deprecation // use -Xsource:3 to warn that implicitly extending Function is deprecated -// use -Xsource:3-cross for dotty behavior: no extend Function, yes adapt C.apply.tupled +// use -Xsource-features for dotty behavior: no extend Function, yes adapt C.apply.tupled case class B(i: Int) case class C(i: Int, j: Int) diff --git a/test/files/run/t3895.scala b/test/files/run/t3895.scala index d19100dfd0bf..b353aa7d24a3 100644 --- a/test/files/run/t3895.scala +++ b/test/files/run/t3895.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // class C extends A{ diff --git a/test/files/run/t3897/a_1.scala b/test/files/run/t3897/a_1.scala index ceabeb450427..9c31837bcef8 100644 --- a/test/files/run/t3897/a_1.scala +++ b/test/files/run/t3897/a_1.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline class One { private val messages = new collection.mutable.ListBuffer[String] List("a") foreach { messages += _ } diff --git a/test/files/run/t3897/a_2.scala b/test/files/run/t3897/a_2.scala index d9ef2e353dbf..59477c574055 100644 --- a/test/files/run/t3897/a_2.scala +++ b/test/files/run/t3897/a_2.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:inline +//> using options -Ydelambdafy:inline object Test { def f1(clazz: Class[_]) = ( clazz.getDeclaredFields.toList diff --git a/test/files/run/t4072.scala b/test/files/run/t4072.scala index 9cc12e130428..05cf85748914 100644 --- a/test/files/run/t4072.scala +++ b/test/files/run/t4072.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // import scala.tools.nsc._ diff --git a/test/files/run/t4225d.scala b/test/files/run/t4225d.scala index 4b506b911415..bc167c3f12a1 100644 --- a/test/files/run/t4225d.scala +++ b/test/files/run/t4225d.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // import scala.language.implicitConversions diff --git a/test/files/run/t4225e.scala b/test/files/run/t4225e.scala index 0b1455c1a0e0..a5889cfdce48 100644 --- a/test/files/run/t4225e.scala +++ b/test/files/run/t4225e.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // import scala.language.implicitConversions diff --git a/test/files/run/t4285.scala b/test/files/run/t4285.scala index 3a369235510d..3b8464c5a412 100644 --- a/test/files/run/t4285.scala +++ b/test/files/run/t4285.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // import scala.tools.partest.ReplTest object Test extends ReplTest { diff --git a/test/files/run/t4317/S_1.scala b/test/files/run/t4317/S_1.scala index af40b4f6f4e2..93cf4c053c88 100644 --- a/test/files/run/t4317/S_1.scala +++ b/test/files/run/t4317/S_1.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror import language.existentials object S_1 { diff --git a/test/files/run/t4317/S_3.scala b/test/files/run/t4317/S_3.scala index 8ddf3068e074..065ebaceb3f9 100644 --- a/test/files/run/t4317/S_3.scala +++ b/test/files/run/t4317/S_3.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +//> using options -Werror object Test { def main(args: Array[String]): Unit = { val j = new J_2() diff --git a/test/files/run/t4536.scala b/test/files/run/t4536.scala index 926037695f78..87b349e331b3 100644 --- a/test/files/run/t4536.scala +++ b/test/files/run/t4536.scala @@ -1,4 +1,4 @@ -// scalac: -language:dynamics +//> using options -language:dynamics // diff --git a/test/files/run/t4680.check b/test/files/run/t4680.check index f0ac8f491fb3..aaa0259a78d6 100644 --- a/test/files/run/t4680.check +++ b/test/files/run/t4680.check @@ -1,12 +1,9 @@ -t4680.scala:51: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +t4680.scala:53: warning: a pure expression does nothing in statement position new C { 5 } ^ -t4680.scala:69: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +t4680.scala:71: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses new { val x = 5 } with E() { 5 } ^ -warning: 1 deprecation (since 2.11.0) -warning: 4 deprecations (since 2.13.0) -warning: 5 deprecations in total; re-run with -deprecation for details // new C { } diff --git a/test/files/run/t4680.scala b/test/files/run/t4680.scala index aa1a42c52351..294cc6d40fb4 100644 --- a/test/files/run/t4680.scala +++ b/test/files/run/t4680.scala @@ -1,3 +1,5 @@ +//> using options -Wconf:cat=deprecation:s + trait A extends DelayedInit { print("-A ") diff --git a/test/files/run/t4742.scala b/test/files/run/t4742.scala index da407ace100c..258130df2dad 100644 --- a/test/files/run/t4742.scala +++ b/test/files/run/t4742.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // trait T { val x: Int = 0 } object O extends T { override final val x = 1 } diff --git a/test/files/run/t4935.scala b/test/files/run/t4935.scala index 0b3a9a72ad55..c18517cb62b5 100644 --- a/test/files/run/t4935.scala +++ b/test/files/run/t4935.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test extends App { for (i <- 0 to 1) { diff --git a/test/files/run/t5040.scala b/test/files/run/t5040.scala index 5ea3386f2387..507dfedd0915 100644 --- a/test/files/run/t5040.scala +++ b/test/files/run/t5040.scala @@ -1,4 +1,4 @@ -// scalac: -language:dynamics +//> using options -language:dynamics // abstract class Prova2 extends Dynamic { def applyDynamic(m: String)(): Unit diff --git a/test/files/run/t5064.scala b/test/files/run/t5064.scala index c7d0282bedbd..c85559ec6750 100644 --- a/test/files/run/t5064.scala +++ b/test/files/run/t5064.scala @@ -2,7 +2,7 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos" + override def sources = List( """|class T5064 { | List(1) diff --git a/test/files/run/t5385.scala b/test/files/run/t5385.scala index d6602cb69fda..d73f3771a4c1 100644 --- a/test/files/run/t5385.scala +++ b/test/files/run/t5385.scala @@ -2,7 +2,7 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos" + override def sources = List( "class Azz", "class Bzz ", "class Czz ", "class Dzz\n", "class Ezz{}", "class Fzz{} ", "class Gzz { }", "class Hzz { } " diff --git a/test/files/run/t5568.scala b/test/files/run/t5568.scala index 040db3b12975..3c086cde9eeb 100644 --- a/test/files/run/t5568.scala +++ b/test/files/run/t5568.scala @@ -1,4 +1,4 @@ -// scalac: -nowarn +//> using options -nowarn // object Test { def main(args: Array[String]): Unit = { diff --git a/test/files/run/t5603.check b/test/files/run/t5603.check index 14ee478343c4..970c6064c855 100644 --- a/test/files/run/t5603.check +++ b/test/files/run/t5603.check @@ -10,10 +10,10 @@ [87:209]class C extends [94:209][151:159]Greeting { [119:139]val nameElse = _; [95:101] private[this] val i: [98:101]Int = _; - <95:139>def (<95:101>i: [98]Int) = <95:139>{ + <94:139>def (<95:101>i: [98]Int) = <94:139>{ <119:139>val nameElse = <134:139>"Bob"; [NoPosition][NoPosition][NoPosition]super.(); - <95:139>() + <94:139>() }; [168:184]val name = [179:184]"avc"; [191:203][191:198]println([199:202]msg) diff --git a/test/files/run/t5603.scala b/test/files/run/t5603.scala index bc24e30564a4..b7a8403a8e6c 100644 --- a/test/files/run/t5603.scala +++ b/test/files/run/t5603.scala @@ -1,12 +1,8 @@ -import scala.tools.partest._ -import java.io._ -import scala.tools.nsc._ -import scala.tools.nsc.{Global, Settings, CompilerCommand} -import scala.tools.nsc.reporters.ConsoleReporter +import scala.tools.partest.DirectTest object Test extends DirectTest { - override def extraSettings: String = "-usejavacp -Vprint:parser -Ystop-after:parser" + override def extraSettings: String = "-usejavacp -Vprint:parser -Vprint-pos -Ystop-after:parser" override def code = """ trait Greeting { @@ -23,14 +19,5 @@ object Test extends DirectTest { object Test extends App {} """.trim - override def show(): Unit = compile() - - override def newCompiler(args: String*): Global = { - - val settings = new Settings() - settings.Xprintpos.value = true - settings.Yrangepos.value = true - val command = new CompilerCommand(tokenize(extraSettings) ++ args.toList, settings) - Global(command.settings, new ConsoleReporter(settings)) - } + override def show(): Unit = assert(compile()) } diff --git a/test/files/run/t5648.scala b/test/files/run/t5648.scala index 1c3cd6f2a17c..e87595b8d793 100644 --- a/test/files/run/t5648.scala +++ b/test/files/run/t5648.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // case class C(val s: Int*) diff --git a/test/files/run/t5704.scala b/test/files/run/t5704.scala index 6297fa97bac5..48fccf851a3d 100644 --- a/test/files/run/t5704.scala +++ b/test/files/run/t5704.scala @@ -1,4 +1,4 @@ -// scalac: -language:experimental.macros +//> using options -language:experimental.macros // import scala.reflect.runtime.universe._ import scala.reflect.runtime.{universe => ru} diff --git a/test/files/run/t5830.scala b/test/files/run/t5830.scala index 296651f439de..2d5523bf449f 100644 --- a/test/files/run/t5830.scala +++ b/test/files/run/t5830.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import scala.annotation.switch diff --git a/test/files/run/t5857.scala b/test/files/run/t5857.scala index 4812e494529a..6ea10db6362a 100644 --- a/test/files/run/t5857.scala +++ b/test/files/run/t5857.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // import scala.math.Ordering.Double.IeeeOrdering diff --git a/test/files/run/t5903a/Macros_1.scala b/test/files/run/t5903a/Macros_1.scala index 0b1380af89f9..2e66800e9630 100644 --- a/test/files/run/t5903a/Macros_1.scala +++ b/test/files/run/t5903a/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Vreflective-calls +//> using options -Vreflective-calls import scala.reflect.macros.whitebox.Context import language.experimental.macros diff --git a/test/files/run/t5903a/Test_2.scala b/test/files/run/t5903a/Test_2.scala index 74e8c6660552..5fc374c0f393 100644 --- a/test/files/run/t5903a/Test_2.scala +++ b/test/files/run/t5903a/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Vreflective-calls +//> using options -Vreflective-calls object Test extends App { import NewQuasiquotes._ SomeTree match { diff --git a/test/files/run/t5903c/Macros_1.scala b/test/files/run/t5903c/Macros_1.scala index 41b77eba18eb..474fcb2b723d 100644 --- a/test/files/run/t5903c/Macros_1.scala +++ b/test/files/run/t5903c/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Vreflective-calls +//> using options -Vreflective-calls import scala.reflect.macros.whitebox.Context import language.experimental.macros diff --git a/test/files/run/t5903c/Test_2.scala b/test/files/run/t5903c/Test_2.scala index 5a1e7c54e744..db705fcf352b 100644 --- a/test/files/run/t5903c/Test_2.scala +++ b/test/files/run/t5903c/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Vreflective-calls +//> using options -Vreflective-calls object Test extends App { import Interpolation._ 2 match { diff --git a/test/files/run/t5903d/Macros_1.scala b/test/files/run/t5903d/Macros_1.scala index f0fd4801296f..feedf6eccd69 100644 --- a/test/files/run/t5903d/Macros_1.scala +++ b/test/files/run/t5903d/Macros_1.scala @@ -1,4 +1,4 @@ -// scalac: -Vreflective-calls +//> using options -Vreflective-calls import scala.reflect.macros.whitebox.Context import language.experimental.macros diff --git a/test/files/run/t5903d/Test_2.scala b/test/files/run/t5903d/Test_2.scala index 1871197c1662..a64890fd8b58 100644 --- a/test/files/run/t5903d/Test_2.scala +++ b/test/files/run/t5903d/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -Vreflective-calls +//> using options -Vreflective-calls object Test extends App { import Interpolation._ 42 match { diff --git a/test/files/run/t5905-features.scala b/test/files/run/t5905-features.scala index d411f7d92148..a00d988a3a0b 100644 --- a/test/files/run/t5905-features.scala +++ b/test/files/run/t5905-features.scala @@ -1,4 +1,4 @@ -// scalac: -nowarn +//> using options -nowarn // import tools.partest.DirectTest diff --git a/test/files/run/t6102.scala b/test/files/run/t6102.scala index edcdf439b857..b5dbb970b22f 100644 --- a/test/files/run/t6102.scala +++ b/test/files/run/t6102.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Werror +//> using options -opt:inline:** -Werror // // scala/bug#6102 Wrong bytecode in lazyval + no-op finally clause diff --git a/test/files/run/t6146b.scala b/test/files/run/t6146b.scala index 62e9ebf50124..c28754be5031 100644 --- a/test/files/run/t6146b.scala +++ b/test/files/run/t6146b.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation +//> using options -Xlint:deprecation // import scala.tools.partest.ReplTest diff --git a/test/files/run/t6188.scala b/test/files/run/t6188.scala index 26dde6ea1d53..c1529b26cbc6 100644 --- a/test/files/run/t6188.scala +++ b/test/files/run/t6188.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // // scala/bug#6188 Optimizer incorrectly removes method invocations containing throw expressions diff --git a/test/files/run/t6240-universe-code-gen.scala b/test/files/run/t6240-universe-code-gen.scala index be9bdeb69749..81b5049926af 100644 --- a/test/files/run/t6240-universe-code-gen.scala +++ b/test/files/run/t6240-universe-code-gen.scala @@ -33,7 +33,7 @@ object Test extends App { s"""|/* | * Scala (https://www.scala-lang.org) | * - | * Copyright EPFL and Lightbend, Inc. + | * Copyright EPFL and Lightbend, Inc. dba Akka | * | * Licensed under Apache License 2.0 | * (http://www.apache.org/licenses/LICENSE-2.0). diff --git a/test/files/run/t6288.check b/test/files/run/t6288.check index a4ad1fd15e49..bb6c33d1a35f 100644 --- a/test/files/run/t6288.check +++ b/test/files/run/t6288.check @@ -12,7 +12,7 @@ [84:93]if ([89][89][89]"".ne([89]null)) [84:89]{ [84:89] val o7: [84]Option[Int] = [84:89][84:89]Case3.unapply([84]x1); - [97:99]if ([84]o7.isEmpty.unary_!) + [84:99]if ([84]o7.isEmpty.unary_!) [97:99][97]matchEnd4([97:99]()) else [84][84]case6() @@ -40,7 +40,7 @@ [241:250]if ([246][246][246]"".ne([246]null)) [241:246]{ [241:246] val o7: [241]Option[List[Int]] = [241:246][241:246]Case4.unapplySeq([241]x1); - [254:256]if ([241][241]o7.isEmpty.unary_!.&&([241][241][241][241]o7.get.!=([241]null).&&([241][241][241][241]o7.get.lengthCompare([241]1).==([241]0)))) + [241:256]if ([241][241]o7.isEmpty.unary_!.&&([241][241][241][241]o7.get.!=([241]null).&&([241][241][241][241]o7.get.lengthCompare([241]1).==([241]0)))) [254:256][254]matchEnd4([254:256]()) else [241][241]case6() @@ -68,7 +68,7 @@ [385:392]if ([390][390][390]"".ne([390]null)) [385:390]{ [385:390] val o7: [385]Option[List[Int]] = [385:390][385:390]Case4.unapplySeq([385]x1); - [396:398]if ([385][385]o7.isEmpty.unary_!.&&([385][385][385][385]o7.get.!=([385]null).&&([385][385][385][385]o7.get.lengthCompare([385]0).==([385]0)))) + [385:398]if ([385][385]o7.isEmpty.unary_!.&&([385][385][385][385]o7.get.!=([385]null).&&([385][385][385][385]o7.get.lengthCompare([385]0).==([385]0)))) [396:398][396]matchEnd4([396:398]()) else [385][385]case6() @@ -94,7 +94,7 @@ [513:514]case val x1: [513]Int(0) = [513:514]0; [513:514]case5()[532:537]{ [532:537] val o7: [532]Option[Int] = [532:537][532:537]Case6.unapply([532]x1); - [545:547]if ([532]o7.isEmpty.unary_!) + [532:547]if ([532]o7.isEmpty.unary_!) [545:547][545]matchEnd4([545:547]()) else [532][532]case6() diff --git a/test/files/run/t6327.scala b/test/files/run/t6327.scala index 7ebba247b871..698cc5fdf66d 100644 --- a/test/files/run/t6327.scala +++ b/test/files/run/t6327.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false // import language._ diff --git a/test/files/run/t6381.scala b/test/files/run/t6381.scala index 15a253c193cd..307aed5585f5 100644 --- a/test/files/run/t6381.scala +++ b/test/files/run/t6381.scala @@ -17,5 +17,5 @@ object Test extends ReplTest { |pos |""".stripMargin.trim - override def extraSettings: String = "-Yrangepos" + } diff --git a/test/files/run/t6387.scala b/test/files/run/t6387.scala new file mode 100644 index 000000000000..be792ca6899a --- /dev/null +++ b/test/files/run/t6387.scala @@ -0,0 +1,14 @@ +trait A { + def foo: Long +} + +object Test { + def a(): A = new A { + var foo: Long = 1024L + + val test = () => { + foo = 28 + } + } + def main(args: Array[String]) = assert(a().foo == 1024L) +} diff --git a/test/files/run/t6411a.scala b/test/files/run/t6411a.scala index bd2fdd37be52..a94d479c9073 100644 --- a/test/files/run/t6411a.scala +++ b/test/files/run/t6411a.scala @@ -1,5 +1,5 @@ -// java: -XX:CompileCommand=exclude,scala/runtime/BoxesRunTime.unboxToInt -// filter: scala.runtime.BoxesRunTime.{1,2}unboxToInt +//> using javaOpt -XX:CompileCommand=exclude,scala/runtime/BoxesRunTime.unboxToInt +//> using filter scala.runtime.BoxesRunTime.{1,2}unboxToInt // // noise from -XX:CompileCommand=exclude,scala/runtime/BoxesRunTime.unboxToInt // CompilerOracle: exclude scala/runtime/BoxesRunTime.unboxToInt diff --git a/test/files/run/t6488.scala b/test/files/run/t6488.scala index 90d29b264964..dfbfca761729 100644 --- a/test/files/run/t6488.scala +++ b/test/files/run/t6488.scala @@ -1,4 +1,4 @@ -// java: -Dforked.test=yes.please +//> using javaOpt -Dforked.test=yes.please import scala.sys.process._ import scala.util.Try diff --git a/test/files/run/t6541.scala b/test/files/run/t6541.scala index 4f193e3a15c3..c422e91b255e 100644 --- a/test/files/run/t6541.scala +++ b/test/files/run/t6541.scala @@ -1,4 +1,4 @@ -// scalac: -feature -Werror +//> using options -feature -Werror // class A class B[T](x: T) diff --git a/test/files/run/t657.scala b/test/files/run/t657.scala index 882c9bf3fb71..9c30c12adde8 100644 --- a/test/files/run/t657.scala +++ b/test/files/run/t657.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Xlint:deprecation +//> using options -Werror -Xlint:deprecation // import scala.language.{ implicitConversions } diff --git a/test/files/run/t6608.check b/test/files/run/t6608.check deleted file mode 100644 index 15628b322ea0..000000000000 --- a/test/files/run/t6608.check +++ /dev/null @@ -1 +0,0 @@ -(C$$yyy,true) diff --git a/test/files/run/t6608.scala b/test/files/run/t6608.scala index 2ba979649bc3..f1d502be7f09 100644 --- a/test/files/run/t6608.scala +++ b/test/files/run/t6608.scala @@ -11,6 +11,7 @@ object Test extends App { .toList .filter(_.name.toString.endsWith("yyy")) .map(x => (x.name, x.isPrivate)) - println(access.head) + val Expected = TermName("C$$yyy") + assert(access.head == (Expected, true)) } diff --git a/test/files/run/t6663.scala b/test/files/run/t6663.scala index e93dca2afdbd..a30a45c7a06b 100644 --- a/test/files/run/t6663.scala +++ b/test/files/run/t6663.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false +//> using options -Yrangepos:false // import language.dynamics diff --git a/test/files/run/t6677b.scala b/test/files/run/t6677b.scala index 764f5ac4a0cb..a68623ff3bdf 100644 --- a/test/files/run/t6677b.scala +++ b/test/files/run/t6677b.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation +//> using options -Xlint:deprecation // trait U { diff --git a/test/files/run/t6714.scala b/test/files/run/t6714.scala index f778ecaf17f9..3ca1f3084de9 100644 --- a/test/files/run/t6714.scala +++ b/test/files/run/t6714.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos +// // case class A(a: Int, index: Int) { diff --git a/test/files/run/t6731.scala b/test/files/run/t6731.scala index 8ea4962558dc..8fc224a75138 100644 --- a/test/files/run/t6731.scala +++ b/test/files/run/t6731.scala @@ -1,4 +1,4 @@ -// scalac: -Yrangepos:false -deprecation +//> using options -Yrangepos:false -deprecation // import scala.language.dynamics import scala.reflect.{ ClassTag, classTag } diff --git a/test/files/run/t7047.check b/test/files/run/t7047.check index 129ce3eeca22..da44c8ad4871 100644 --- a/test/files/run/t7047.check +++ b/test/files/run/t7047.check @@ -1,3 +1,3 @@ -Test_2.scala:2: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +Test_2.scala:2: warning: a pure expression does nothing in statement position Macros.foo ^ diff --git a/test/files/run/t7198.scala b/test/files/run/t7198.scala index e6aa21c17926..159c5d98c226 100644 --- a/test/files/run/t7198.scala +++ b/test/files/run/t7198.scala @@ -1,4 +1,4 @@ -// filter: Over the moon +//> using filter "Over the moon" /* spew a few lines */ object Test extends App { diff --git a/test/files/run/t7341.scala b/test/files/run/t7341.scala index a03e8e853462..d0b85377c256 100644 --- a/test/files/run/t7341.scala +++ b/test/files/run/t7341.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // object Obj { private var cache: Any = () diff --git a/test/files/run/t744.scala b/test/files/run/t744.scala index e5b4407284a1..549362c92dc6 100644 --- a/test/files/run/t744.scala +++ b/test/files/run/t744.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:deprecation +//> using options -Xlint:deprecation // trait Linked { diff --git a/test/files/run/t7448.scala b/test/files/run/t7448.scala index 5bf74ee85a77..ae8143413382 100644 --- a/test/files/run/t7448.scala +++ b/test/files/run/t7448.scala @@ -1,4 +1,4 @@ -// scalac: -nowarn +//> using options -nowarn import util.chaining._ object Test { diff --git a/test/files/run/t7459b-optimize.scala b/test/files/run/t7459b-optimize.scala index ececda96b499..225723b1dc11 100644 --- a/test/files/run/t7459b-optimize.scala +++ b/test/files/run/t7459b-optimize.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // class LM { class Node[B1] diff --git a/test/files/run/t7569.scala b/test/files/run/t7569.scala index 6e3df543ce86..7d99a72b7da0 100644 --- a/test/files/run/t7569.scala +++ b/test/files/run/t7569.scala @@ -1,7 +1,7 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - override def extraSettings = super.extraSettings + " -Yrangepos" + override def sources = List( """|import scala.language.postfixOps |class A { diff --git a/test/files/run/t7582/InlineHolder_2.scala b/test/files/run/t7582/InlineHolder_2.scala index 82eb737299e1..7fc43890bdd6 100644 --- a/test/files/run/t7582/InlineHolder_2.scala +++ b/test/files/run/t7582/InlineHolder_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt package p1 { object InlineHolder { @inline def inlinable = (p1.PackageProtectedJava_1.protectedMethod(): @noinline) + 1 diff --git a/test/files/run/t7582b/InlineHolder_2.scala b/test/files/run/t7582b/InlineHolder_2.scala index 82eb737299e1..7fc43890bdd6 100644 --- a/test/files/run/t7582b/InlineHolder_2.scala +++ b/test/files/run/t7582b/InlineHolder_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** -Wopt +//> using options -opt:inline:** -Wopt package p1 { object InlineHolder { @inline def inlinable = (p1.PackageProtectedJava_1.protectedMethod(): @noinline) + 1 diff --git a/test/files/run/t7584.scala b/test/files/run/t7584.scala index a830cbf735b7..9b7bf8f4abe3 100644 --- a/test/files/run/t7584.scala +++ b/test/files/run/t7584.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // // Test case added to show the behaviour of functions with // by-name parameters. The evaluation behaviour was already correct. diff --git a/test/files/run/t7634.scala b/test/files/run/t7634.scala index b55ae062553a..683242081dc3 100644 --- a/test/files/run/t7634.scala +++ b/test/files/run/t7634.scala @@ -1,6 +1,6 @@ -// java: -Dneeds.forked.jvm.for.windows +//> using javaOpt -Dneeds.forked.jvm.for.windows // filter out absolute path to java -// filter: hello.Hello +//> using filter hello.Hello import java.io.File import scala.tools.partest.ReplTest diff --git a/test/files/run/t7722.check b/test/files/run/t7722.check new file mode 100644 index 000000000000..bb5215281807 --- /dev/null +++ b/test/files/run/t7722.check @@ -0,0 +1,23 @@ + +scala> import concurrent.duration._ +import concurrent.duration._ + +scala> 60.seconds +val res0: scala.concurrent.duration.FiniteDuration = 60 seconds + +scala> class C +class C + +scala> implicit def cv(s: String): C = new C +warning: 1 feature warning; for details, enable `:setting -feature` or `:replay -feature` +def cv(s: String): C + +scala> "hello, world" +val res1: String = hello, world + +scala> { import concurrent.duration._; "adios, amigos" } + ^ + warning: Unused import +val res2: String = adios, amigos + +scala> :quit diff --git a/test/files/run/t7722.scala b/test/files/run/t7722.scala new file mode 100644 index 000000000000..f4d687778815 --- /dev/null +++ b/test/files/run/t7722.scala @@ -0,0 +1,6 @@ + +import scala.tools.partest.SessionTest + +object Test extends SessionTest { + override def extraSettings = "-usejavacp -Wunused:imports" +} diff --git a/test/files/run/t7768.scala b/test/files/run/t7768.scala index 05f07332f69d..a54125da670a 100644 --- a/test/files/run/t7768.scala +++ b/test/files/run/t7768.scala @@ -1,4 +1,4 @@ -// scalac: -Yscala3-implicit-resolution +//> using options -Xsource:3 -Xsource-features:implicit-resolution class A class B extends A class C extends B diff --git a/test/files/run/t7805-repl-i.check b/test/files/run/t7805-repl-i.check deleted file mode 100644 index b4485715de33..000000000000 --- a/test/files/run/t7805-repl-i.check +++ /dev/null @@ -1,5 +0,0 @@ - -scala> Console println Try(8) -Success(8) - -scala> :quit diff --git a/test/files/run/t7805-repl-i.scala b/test/files/run/t7805-repl-i.scala deleted file mode 100644 index 816926b7c38a..000000000000 --- a/test/files/run/t7805-repl-i.scala +++ /dev/null @@ -1,43 +0,0 @@ -// java: -Dneeds.forked.jvm - -import scala.tools.partest.ReplTest -import scala.tools.nsc.{ GenericRunnerSettings, Settings } -import scala.tools.nsc.settings.MutableSettings - -object Test extends ReplTest with HangingRepl { - def script = testPath changeExtension "script" - override def transformSettings(s: Settings) = s match { - case m: MutableSettings => - val t = new GenericRunnerSettings(s.errorFn) - m copyInto t - t processArgumentString s"-i $script" - t - case _ => s - } - def code = "Console println Try(8)" -} - -object Resulting { - import scala.concurrent._ - import scala.concurrent.duration._ - implicit class AwaitResult[A](val f: Future[A]) extends AnyVal { - def resultWithin(d: Duration): A = Await.result(f, d) - } -} - -/** Test that hangs the REPL. - * Usually that is the "before" case. - */ -trait HangingRepl extends ReplTest { - import scala.language.postfixOps - import scala.util._ - import scala.concurrent._ - import scala.concurrent.duration._ - import ExecutionContext.Implicits._ - import Resulting._ - def timeout = 120 seconds - def hanging[A](a: => A): A = Future(a) resultWithin timeout - override def show() = Try(hanging(super.show())) recover { - case e => e.printStackTrace() - } -} diff --git a/test/files/run/t7805-repl-i.script b/test/files/run/t7805-repl-i.script deleted file mode 100644 index eb2b8705f362..000000000000 --- a/test/files/run/t7805-repl-i.script +++ /dev/null @@ -1 +0,0 @@ -import util._ diff --git a/test/files/run/t7879.check b/test/files/run/t7879.check new file mode 100644 index 000000000000..d449c179a277 --- /dev/null +++ b/test/files/run/t7879.check @@ -0,0 +1,25 @@ + +scala> case class C(i: Int)(j: => Int) { def sum = i + j } +class C + +scala> def z = 27.tap(println) +def z: Int + +scala> val c = C(42)(z) +val c: C = C(42) + +scala> c.sum +27 +val res0: Int = 69 + +scala> def y = 28.tap(println) +def y: Int + +scala> c.copy()(y) +val res1: C = C(42) + +scala> c.copy()(y).sum +28 +val res2: Int = 70 + +scala> :quit diff --git a/test/files/run/t7879.scala b/test/files/run/t7879.scala new file mode 100644 index 000000000000..ae026b427ed7 --- /dev/null +++ b/test/files/run/t7879.scala @@ -0,0 +1,6 @@ + +import scala.tools.partest.SessionTest + +object Test extends SessionTest { + override def extraSettings = "-Yimports:java.lang,scala,scala.Predef,scala.util.chaining -Xsource:3 -Xsource-features:case-copy-by-name" +} diff --git a/test/files/run/t7974/Test.scala b/test/files/run/t7974/Test.scala index 879313f45fc5..675b9907bf16 100644 --- a/test/files/run/t7974/Test.scala +++ b/test/files/run/t7974/Test.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit:false +//> using options -Xcheckinit:false import java.io.PrintWriter import scala.tools.partest.BytecodeTest diff --git a/test/files/run/t8017/value-class-lambda.scala b/test/files/run/t8017/value-class-lambda.scala index 212a772c221b..a3b34b1ba93c 100644 --- a/test/files/run/t8017/value-class-lambda.scala +++ b/test/files/run/t8017/value-class-lambda.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method +//> using options -Ydelambdafy:method object Test { def testC: Unit = { val f1 = (c: C) => c.value diff --git a/test/files/run/t8442.check b/test/files/run/t8442.check deleted file mode 100644 index 8b137891791f..000000000000 --- a/test/files/run/t8442.check +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/files/run/t8442/Test.scala b/test/files/run/t8442/Test.scala index 11d422f1b27f..eb2698808523 100644 --- a/test/files/run/t8442/Test.scala +++ b/test/files/run/t8442/Test.scala @@ -22,8 +22,8 @@ object Test extends StoreReporterDirectTest { assert(tClass.exists) assert(tClass.delete()) - // Expecting stub symbol warning, but no stack trace! + // Expecting stub symbol warning only under -verbose, but definitely no stack trace! compileCode(app) - println(filteredInfos.mkString("\n")) + assert(filteredInfos.isEmpty, filteredInfos.mkString("; ")) } } diff --git a/test/files/run/t8570.scala b/test/files/run/t8570.scala index a7d6c449bcb6..9b9a1e3d0fe5 100644 --- a/test/files/run/t8570.scala +++ b/test/files/run/t8570.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // trait Trait40_1 { val value37_2 = () diff --git a/test/files/run/t8570a.scala b/test/files/run/t8570a.scala index cc0ea4012457..1b78ec0fcc0d 100644 --- a/test/files/run/t8570a.scala +++ b/test/files/run/t8570a.scala @@ -1,4 +1,4 @@ -// scalac: -Xcheckinit +//> using options -Xcheckinit // trait Trait40_1 { val value37_2 = () diff --git a/test/files/run/t8601-closure-elim.scala b/test/files/run/t8601-closure-elim.scala index d65a0876b11b..1f7f445f7098 100644 --- a/test/files/run/t8601-closure-elim.scala +++ b/test/files/run/t8601-closure-elim.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method -opt:inline:** +//> using options -Ydelambdafy:method -opt:inline:** // import scala.tools.partest.BytecodeTest import scala.tools.testkit.ASMConverters.instructionsFromMethod diff --git a/test/files/run/t8601.scala b/test/files/run/t8601.scala index 9858f6220094..1fc36c2f1255 100644 --- a/test/files/run/t8601.scala +++ b/test/files/run/t8601.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test { def idiv(x: Int): Unit = x / 0 diff --git a/test/files/run/t8601b.scala b/test/files/run/t8601b.scala index d8daece4e25f..8f0312a34324 100644 --- a/test/files/run/t8601b.scala +++ b/test/files/run/t8601b.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test { def len(x: Array[String]): Unit = x.length diff --git a/test/files/run/t8601c.scala b/test/files/run/t8601c.scala index 403e506ddf98..55566a8e8ffb 100644 --- a/test/files/run/t8601c.scala +++ b/test/files/run/t8601c.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test { def loadField(x: scala.runtime.IntRef): Unit = x.elem diff --git a/test/files/run/t8601d.scala b/test/files/run/t8601d.scala index c567abcd434a..46d35e60152a 100644 --- a/test/files/run/t8601d.scala +++ b/test/files/run/t8601d.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Test { def monitor(x: AnyRef): Unit = {x.synchronized(()); ()} diff --git a/test/files/run/t8601e/Test.scala b/test/files/run/t8601e/Test.scala index 44a8eb18b756..99667f24b8ff 100644 --- a/test/files/run/t8601e/Test.scala +++ b/test/files/run/t8601e/Test.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** class C { def foo: Unit = {StaticInit.fld} } diff --git a/test/files/run/t8610.scala b/test/files/run/t8610.scala index 932b7bab5dd5..0bcca528f2d0 100644 --- a/test/files/run/t8610.scala +++ b/test/files/run/t8610.scala @@ -1,4 +1,4 @@ -// scalac: -Xlint:adapted-args +//> using options -Xlint:adapted-args // // flags don't warn on u diff --git a/test/files/run/t8611a.scala b/test/files/run/t8611a.scala index b4895bbaf85d..69ae2ba167bf 100644 --- a/test/files/run/t8611a.scala +++ b/test/files/run/t8611a.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait K trait L diff --git a/test/files/run/t8611b.scala b/test/files/run/t8611b.scala index 3ababcdc9062..fd091be8a1dc 100644 --- a/test/files/run/t8611b.scala +++ b/test/files/run/t8611b.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // sealed trait KrafsDescription diff --git a/test/files/run/t8611c.scala b/test/files/run/t8611c.scala index c216d30c4a3f..44f6708a96c8 100644 --- a/test/files/run/t8611c.scala +++ b/test/files/run/t8611c.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // trait K trait L diff --git a/test/files/run/t8859.check b/test/files/run/t8859.check new file mode 100644 index 000000000000..c06b6ddab724 --- /dev/null +++ b/test/files/run/t8859.check @@ -0,0 +1,24 @@ + +x map f +[0:7][0:5]x.map([6:7]f) +x map f + +x map (f) +[0:9][0:5]x.map([7:8]f) +x map (f) + +x map ((f)) +[0:11][0:5]x.map([8:9]f) +x map ((f)) + +x map {f} +[0:9][0:5]x.map([7:8]f) +x map {f} + +x map {{f}} +[0:11][0:5]x.map([8:9]f) +x map {{f}} + +x map {({(f)})} +[0:15][0:5]x.map([10:11]f) +x map {({(f)})} diff --git a/test/files/run/t8859.scala b/test/files/run/t8859.scala new file mode 100644 index 000000000000..4c60bf3829de --- /dev/null +++ b/test/files/run/t8859.scala @@ -0,0 +1,19 @@ +object Test extends App { + import scala.reflect.runtime._ + import scala.reflect.runtime.universe._ + import scala.tools.reflect.ToolBox + + val mirror = universe.runtimeMirror(universe.getClass.getClassLoader) + val toolbox = mirror.mkToolBox() + def showParsed(code: String) = { + val parsed = toolbox.parse(code) + val recovered = code.substring(parsed.pos.start, parsed.pos.end) + println(s"\n$code\n${show(parsed, printPositions = true)}\n$recovered") + } + showParsed("x map f") + showParsed("x map (f)") + showParsed("x map ((f))") + showParsed("x map {f}") + showParsed("x map {{f}}") + showParsed("x map {({(f)})}") +} diff --git a/test/files/run/t8888.scala b/test/files/run/t8888.scala index 1ac421625fff..301af0e26801 100644 --- a/test/files/run/t8888.scala +++ b/test/files/run/t8888.scala @@ -1,4 +1,4 @@ -// scalac: -Ydelambdafy:method +//> using options -Ydelambdafy:method // class C { final def resume: Any = (this: Any) match { diff --git a/test/files/run/t8928/Test_1.scala b/test/files/run/t8928/Test_1.scala index bcf94ce41e52..e30aaced4ca3 100644 --- a/test/files/run/t8928/Test_1.scala +++ b/test/files/run/t8928/Test_1.scala @@ -1,4 +1,4 @@ -// java: -Dneeds.forked.jvm +//> using javaOpt -Dneeds.forked.jvm import test._ object Test extends App { diff --git a/test/files/run/t8935-object.scala b/test/files/run/t8935-object.scala index 67704ed028e2..7da7b58a5059 100644 --- a/test/files/run/t8935-object.scala +++ b/test/files/run/t8935-object.scala @@ -1,31 +1,3 @@ import scala.tools.partest.SessionTest -import scala.tools.nsc.Settings - -object Test extends SessionTest { - /* future - override def transformSettings(s: Settings): Settings = { - //s.YreplWrap.value = "object" - s - } - */ - override def session = -""" -scala> 41+1 -res0: Int = 42 - -scala> $intp.valueOfTerm($intp.mostRecentVar) -res1: Option[Any] = Some(42) - -scala> val i = 17 ; 64 -i: Int = 17 -res2: Int = 64 - -scala> $intp.valueOfTerm($intp.mostRecentVar) -res3: Option[Any] = Some(64) - -scala> $intp.valueOfTerm("i") -res4: Option[Any] = Some(17) - -scala> :quit""" -} +object Test extends SessionTest diff --git a/test/files/run/t9003.scala b/test/files/run/t9003.scala index b5dc21027476..f84137c75b5e 100644 --- a/test/files/run/t9003.scala +++ b/test/files/run/t9003.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** // object Single { var i = 0 diff --git a/test/files/run/t9029.scala b/test/files/run/t9029.scala index 52dbc58378e3..538b9b14c817 100644 --- a/test/files/run/t9029.scala +++ b/test/files/run/t9029.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // class Y(val _2: Int, val _1: String) diff --git a/test/files/run/t9102.scala b/test/files/run/t9102.scala index c46cf0e4b42a..b7f55d095c98 100644 --- a/test/files/run/t9102.scala +++ b/test/files/run/t9102.scala @@ -29,43 +29,6 @@ object Test extends App { } } -/* Session tests without special init code should reside in simple script files. - * Also, provide filters such as for `(bound to C@74f7d1d2)`. - -import scala.tools.partest.SessionTest - -object Test extends SessionTest { -//Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40). - def session = - s"""|Type in expressions to have them evaluated. - |Type :help for more information. - | - |scala> import reflect.runtime._, universe._ - |import reflect.runtime._ - |import universe._ - | - |scala> class C { def f(i: Int, j: => Int) = i + j } - |defined class C - | - |scala> typeOf[C].member(TermName("f")) - |res0: reflect.runtime.universe.Symbol = method f - | - |scala> .asMethod - |res1: reflect.runtime.universe.MethodSymbol = method f - | - |scala> currentMirror reflect (new C) - |res2: reflect.runtime.universe.InstanceMirror = instance mirror for C@74f7d1d2 - | - |scala> res2 reflectMethod res1 - |res3: reflect.runtime.universe.MethodMirror = method mirror for def f(i: scala.Int,j: => scala.Int): scala.Int (bound to C@74f7d1d2) - | - |scala> res3(2,3) - |res4: Any = 5 - | - |scala> :quit""" -} -*/ - /* was: scala> res3(2,3) java.lang.IllegalArgumentException @@ -78,4 +41,3 @@ java.lang.IllegalArgumentException at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaTransformingMethodMirror.apply(JavaMirrors.scala:436) ... 33 elided */ - diff --git a/test/files/run/t9395.scala b/test/files/run/t9395.scala new file mode 100644 index 000000000000..6f477c830aa9 --- /dev/null +++ b/test/files/run/t9395.scala @@ -0,0 +1,9 @@ +object Test extends App { + def f(s: String): String = "1" + val f: (String) => String = s => "2" + + val t: String => String = f + + // https://github.com/scala/bug/issues/9395#issuecomment-2440062208 + assert(t("") == "2") +} diff --git a/test/files/run/t9403/C_1.scala b/test/files/run/t9403/C_1.scala index e3b5c6d75b28..3ca2955ffa90 100644 --- a/test/files/run/t9403/C_1.scala +++ b/test/files/run/t9403/C_1.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** package p class C { @inline final def f(x: Int): Long = 10L / (if (x < 0) -2 else 2) diff --git a/test/files/run/t9403/Test_2.scala b/test/files/run/t9403/Test_2.scala index be56f42073b8..54bc0a805d93 100644 --- a/test/files/run/t9403/Test_2.scala +++ b/test/files/run/t9403/Test_2.scala @@ -1,4 +1,4 @@ -// scalac: -opt:inline:** +//> using options -opt:inline:** import p.C import scala.tools.asm.Opcodes import scala.tools.partest.BytecodeTest diff --git a/test/files/run/t9486/a_0.scala b/test/files/run/t9486/a_0.scala new file mode 100644 index 000000000000..941093310967 --- /dev/null +++ b/test/files/run/t9486/a_0.scala @@ -0,0 +1,8 @@ + +trait A[@specialized(Int) T] { + def f: T = ??? +} + +object B extends A[Int] { + override final val f = 0 +} diff --git a/test/files/run/t9486/test_1.scala b/test/files/run/t9486/test_1.scala new file mode 100644 index 000000000000..091a42490bb2 --- /dev/null +++ b/test/files/run/t9486/test_1.scala @@ -0,0 +1,6 @@ + +// java.lang.ClassFormatError: Duplicate method name "f" with signature "()I" in class file B$ + +object Test extends App { + assert(B != null) +} diff --git a/test/files/run/t9656.scala b/test/files/run/t9656.scala index 3b97bc72a3c6..28a8cc05638f 100644 --- a/test/files/run/t9656.scala +++ b/test/files/run/t9656.scala @@ -1,4 +1,4 @@ -// scalac: -deprecation +//> using options -deprecation // import scala.math.BigDecimal diff --git a/test/files/run/t9915/C_1.java b/test/files/run/t9915/C_1.java index 5ff246db142b..140e7ee4674a 100644 --- a/test/files/run/t9915/C_1.java +++ b/test/files/run/t9915/C_1.java @@ -1,4 +1,4 @@ -// javac: -encoding UTF-8 +//> using javacOpt -encoding UTF-8 public class C_1 { public static final String NULLED = "X\000ABC"; public static final String SUPPED = "𐒈𐒝𐒑𐒛𐒐𐒘𐒕𐒖"; diff --git a/test/files/run/type-tag-leak.scala b/test/files/run/type-tag-leak.scala index 277799f765eb..0fc9ca377774 100644 --- a/test/files/run/type-tag-leak.scala +++ b/test/files/run/type-tag-leak.scala @@ -1,4 +1,4 @@ -// java: -Xmx192M -XX:+ExitOnOutOfMemoryError +//> using javaOpt -Xmx192M -XX:+ExitOnOutOfMemoryError import scala.reflect.runtime.universe import scala.reflect.runtime.universe._ @@ -19,7 +19,7 @@ object Test extends Test { def main(args: Array[String]): Unit = { for (i <- 1 to 16) { val settings = new scala.tools.nsc.Settings - settings.Xjline.value = "off" + settings.Xnojline.value = true settings.usejavacp.value = true val intp = new IMain(settings, new shell.ReplReporterImpl(settings, new PrintWriter(new StringWriter))) diff --git a/test/files/run/verify-ctor.scala b/test/files/run/verify-ctor.scala index 528d038a8edc..597a82e282bb 100644 --- a/test/files/run/verify-ctor.scala +++ b/test/files/run/verify-ctor.scala @@ -1,11 +1,12 @@ class Foo(val str: String) { def this(arr: Array[Char]) = this({ - if (arr.length == 0) sys.exit(1) + if (arr.length == 0) Test.quit(1) new String(arr) }) } object Test { + def quit(s: Int): Nothing = ??? def main(args: Array[String]) = { val t = new Foo(Array('a', 'b', 'c')) println(t.str) diff --git a/test/files/run/virtpatmat_extends_product.scala b/test/files/run/virtpatmat_extends_product.scala index de1a4970483c..95fac8941796 100644 --- a/test/files/run/virtpatmat_extends_product.scala +++ b/test/files/run/virtpatmat_extends_product.scala @@ -1,4 +1,4 @@ -// scalac: +//> using options // object Test extends App { case class AnnotationInfo(a: String, b: Int) extends Product2[String, Int] { diff --git a/test/files/run/virtpatmat_nested_lists.scala b/test/files/run/virtpatmat_nested_lists.scala index 58f36b642303..73223d3b7b09 100644 --- a/test/files/run/virtpatmat_nested_lists.scala +++ b/test/files/run/virtpatmat_nested_lists.scala @@ -1,4 +1,4 @@ -// scalac: -Ypatmat-exhaust-depth off +//> using options -Ypatmat-exhaust-depth off object Test extends App { List(List(1), List(2)) match { case x :: (y :: Nil) :: Nil => println(y) } } diff --git a/test/files/run/virtpatmat_opt_sharing.scala b/test/files/run/virtpatmat_opt_sharing.scala index 988f963c8ec7..90afce4071d9 100644 --- a/test/files/run/virtpatmat_opt_sharing.scala +++ b/test/files/run/virtpatmat_opt_sharing.scala @@ -1,4 +1,4 @@ -// scalac: -Ypatmat-exhaust-depth off +//> using options -Ypatmat-exhaust-depth off object Test extends App { virtMatch() def virtMatch() = { diff --git a/test/files/run/virtpatmat_typetag.scala b/test/files/run/virtpatmat_typetag.scala index 0cf409fd3350..7af79a703ffe 100644 --- a/test/files/run/virtpatmat_typetag.scala +++ b/test/files/run/virtpatmat_typetag.scala @@ -1,4 +1,4 @@ -// scalac: -Xfatal-warnings +//> using options -Xfatal-warnings // import reflect.{ClassTag, classTag} diff --git a/test/files/run/wacky-value-classes.scala b/test/files/run/wacky-value-classes.scala index c62c70873aa0..74d5b3e52587 100644 --- a/test/files/run/wacky-value-classes.scala +++ b/test/files/run/wacky-value-classes.scala @@ -1,4 +1,4 @@ -// scalac: -Xverify +//> using options -Xverify // // scala/bug#10361 final class AnyValNothing(val self: Nothing) extends AnyVal diff --git a/test/junit/scala/SerializationStabilityTest.scala b/test/junit/scala/SerializationStabilityTest.scala index d55e02c2af12..7e37f7b0bb71 100644 --- a/test/junit/scala/SerializationStabilityTest.scala +++ b/test/junit/scala/SerializationStabilityTest.scala @@ -18,6 +18,7 @@ import collection.accessWrappers.Wrappers._ // Use this to re-establish a baseline for serialization compatibility. // based on run/t8549.scala partest +@annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") object SerializationStability { def parseBase64Binary(s: String): Array[Byte] = Base64.getDecoder.decode(s) diff --git a/test/junit/scala/collection/BuildFromTest.scala b/test/junit/scala/collection/BuildFromTest.scala index 12fe6d9595b2..40f6911cf6b7 100644 --- a/test/junit/scala/collection/BuildFromTest.scala +++ b/test/junit/scala/collection/BuildFromTest.scala @@ -1,11 +1,13 @@ package scala.collection import org.junit.Test +import org.junit.Assert.{assertEquals, assertTrue} -import scala.annotation.unused -import scala.collection.mutable.Builder import scala.math.Ordering +import mutable.{ArrayBuffer, Builder} + +@annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") class BuildFromTest { // You can either overload methods for IterableOps and Iterable with SortedOps (if you want to support constrained collection types) @@ -43,57 +45,68 @@ class BuildFromTest { @Test def optionSequence1Test(): Unit = { - val xs1 = immutable.List(Some(1), None, Some(2)) + val xs1 = List(Some(1), None, Some(2)) val o1 = optionSequence1(xs1) - @unused val o1t: Option[immutable.List[Int]] = o1 + val o1t: Option[List[Int]] = o1 + assertTrue(o1t.isEmpty) val xs2: immutable.TreeSet[Option[String]] = immutable.TreeSet(Some("foo"), Some("bar"), None) val o2 = optionSequence1(xs2) - @unused val o2t: Option[immutable.Set[String]] = o2 + val o2t: Option[immutable.Set[String]] = o2 + assertTrue(o2t.isEmpty) - val xs4 = immutable.List[Option[(Int, String)]](Some((1 -> "a")), Some((2 -> "b"))) + val xs4 = List[Option[(Int, String)]](Some((1 -> "a")), Some((2 -> "b"))) val o4 = optionSequence1(xs4) - @unused val o4t: Option[immutable.List[(Int, String)]] = o4 - @unused val o5: Option[immutable.TreeMap[Int, String]] = o4.map(_.to(immutable.TreeMap)) + val o4t: Option[List[(Int, String)]] = o4 + assertEquals(Some(List(1 -> "a", 2 -> "b")), o4t) + val o5: Option[immutable.TreeMap[Int, String]] = o4.map(_.to(immutable.TreeMap)) + assertEquals(Some(immutable.TreeMap(1 -> "a", 2 -> "b")), o5) } @Test def optionSequence2Test(): Unit = { - val xs1 = immutable.List(Some(1), None, Some(2)) + val xs1 = List(Some(1), None, Some(2)) val o1 = optionSequence2(xs1) - @unused val o1t: Option[immutable.List[Int]] = o1 + val o1t: Option[immutable.List[Int]] = o1 + assertTrue(o1t.isEmpty) val xs2 = immutable.TreeSet(Some("foo"), Some("bar"), None) val o2 = optionSequence2(xs2) - @unused val o2t: Option[immutable.TreeSet[String]] = o2 + val o2t: Option[immutable.TreeSet[String]] = o2 + assertTrue(o2t.isEmpty) // Breakout-like use case from https://github.com/scala/scala/pull/5233: - val xs4 = immutable.List[Option[(Int, String)]](Some((1 -> "a")), Some((2 -> "b"))) + val xs4 = List[Option[(Int, String)]](Some((1 -> "a")), Some((2 -> "b"))) val o4 = optionSequence2(xs4)(immutable.TreeMap) // same syntax as in `.to` - @unused val o4t: Option[immutable.TreeMap[Int, String]] = o4 + val o4t: Option[immutable.TreeMap[Int, String]] = o4 + assertEquals(Some(immutable.TreeMap(1 -> "a", 2 -> "b")), o4t) } @Test def optionSequence3Test(): Unit = { val xs1 = immutable.List(Some(1), None, Some(2)) val o1 = optionSequence3(xs1) - @unused val o1t: Option[immutable.List[Int]] = o1 + val o1t: Option[immutable.List[Int]] = o1 + assertTrue(o1t.isEmpty) val xs2 = immutable.TreeSet(Some("foo"), Some("bar"), None) val o2 = optionSequence3(xs2) - @unused val o2t: Option[immutable.TreeSet[String]] = o2 + val o2t: Option[immutable.TreeSet[String]] = o2 + assertTrue(o2t.isEmpty) // Breakout-like use case from https://github.com/scala/scala/pull/5233: val xs4 = immutable.List[Option[(Int, String)]](Some((1 -> "a")), Some((2 -> "b"))) val o4 = optionSequence3(xs4)(immutable.TreeMap) // same syntax as in `.to` - @unused val o4t: Option[immutable.TreeMap[Int, String]] = o4 + val o4t: Option[immutable.TreeMap[Int, String]] = o4 + assertEquals(Some(immutable.TreeMap(1 -> "a", 2 -> "b")), o4t) } @Test def eitherSequenceTest(): Unit = { val xs3 = mutable.ListBuffer(Right("foo"), Left(0), Right("bar")) val e1 = eitherSequence(xs3) - @unused val e1t: Either[Int, mutable.ListBuffer[String]] = e1 + val e1t: Either[Int, mutable.ListBuffer[String]] = e1 + assertTrue(e1t.isLeft) } // From https://github.com/scala/collection-strawman/issues/44 @@ -118,34 +131,42 @@ class BuildFromTest { @Test def flatCollectTest(): Unit = { - val xs1 = immutable.List(1, 2, 3) - val xs2 = flatCollect(xs1) { case 2 => mutable.ArrayBuffer("foo", "bar") } - @unused val xs3: immutable.List[String] = xs2 + val xs1 = List(1, 2, 3) + val xs2 = flatCollect(xs1) { case 2 => ArrayBuffer("foo", "bar") } + val xs3: List[String] = xs2 + assertEquals(List("foo", "bar"), xs3) val xs4 = immutable.TreeMap((1, "1"), (2, "2")) val xs5 = flatCollect(xs4) { case (2, v) => immutable.List((v, v)) } - @unused val xs6: immutable.TreeMap[String, String] = xs5 + val xs6: immutable.TreeMap[String, String] = xs5 + assertEquals(immutable.TreeMap("2" -> "2"), xs6) val xs7 = immutable.HashMap((1, "1"), (2, "2")) val xs8 = flatCollect(xs7) { case (2, v) => immutable.List((v, v)) } - @unused val xs9: immutable.HashMap[String, String] = xs8 + val xs9: immutable.HashMap[String, String] = xs8 + assertEquals(immutable.HashMap("2" -> "2"), xs9) val xs10 = immutable.TreeSet(1, 2, 3) val xs11 = flatCollect(xs10) { case 2 => immutable.List("foo", "bar") } - @unused val xs12: immutable.TreeSet[String] = xs11 + val xs12: immutable.TreeSet[String] = xs11 + assertEquals(immutable.TreeSet("foo", "bar"), xs12) } @Test def partitionMapTest(): Unit = { - val xs1 = immutable.List(1, 2, 3) + val xs1 = List(1, 2, 3) val (xs2, xs3) = partitionMap(xs1)(x => if (x % 2 == 0) Left(x) else Right(x.toString)) - @unused val xs4: immutable.List[Int] = xs2 - @unused val xs5: immutable.List[String] = xs3 + val xs4: List[Int] = xs2 + assertEquals(List(2), xs4) + val xs5: List[String] = xs3 + assertEquals(List("1", "3"), xs5) val xs6 = immutable.TreeMap((1, "1"), (2, "2")) val (xs7, xs8) = partitionMap(xs6) { case (k, v) => Left[(String, Int), (Int, Boolean)]((v, k)) } - @unused val xs9: immutable.TreeMap[String, Int] = xs7 - @unused val xs10: immutable.TreeMap[Int, Boolean] = xs8 + val xs9: immutable.TreeMap[String, Int] = xs7 + assertEquals(immutable.TreeMap(("1", 1), ("2", 2)), xs9) + val xs10: immutable.TreeMap[Int, Boolean] = xs8 + assertTrue(xs10.isEmpty) } @Test @@ -190,8 +211,8 @@ class BuildFromTest { implicitly[collection.BuildFrom[Seq[Any], (Int, HCons[ExtendsOrdered, HNil]), Seq[(Int, HCons[ExtendsOrdered, HNil])]]] // - // In Scala 2.12, buildFromSortedSetOps is not a candidate because if it is in the companion object of - // the SortedSet heirarchy, which is not part of the implicit scope for this search. + // In Scala 2.12, buildFromSortedSetOps is not a candidate because it is in the companion object of + // the SortedSet hierarchy, which is not part of the implicit scope for this search. // In 2.13, the implicit was moved to `object BuildFrom`, so _is_ considered // // The dependent implicit search: @@ -213,4 +234,10 @@ class BuildFromTest { // // } + // additional test for previous, via scala/bug#12104 + locally { + import scala.concurrent._, ExecutionContext.Implicits._ + Future.traverse(List(1))(_ => Future.failed(new NoSuchElementException)) + // diverging implicit expansion for type scala.collection.BuildFrom[List[Int],B,List[B] starting with method Tuple9 in object Ordering + } } diff --git a/test/junit/scala/collection/FactoriesTest.scala b/test/junit/scala/collection/FactoriesTest.scala index 3ddab2d37eba..2729c8790608 100644 --- a/test/junit/scala/collection/FactoriesTest.scala +++ b/test/junit/scala/collection/FactoriesTest.scala @@ -7,6 +7,7 @@ import scala.collection.mutable.ArrayBuffer import scala.collection.{immutable => im} +@annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") class FactoriesTest { val seq: Seq[Int] = ArrayBuffer(1, 2, 3) diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala index b1b33bd7ea03..9dcf2de48a5f 100644 --- a/test/junit/scala/collection/IteratorTest.scala +++ b/test/junit/scala/collection/IteratorTest.scala @@ -10,16 +10,18 @@ import scala.util.chaining._ import java.lang.ref.SoftReference +import mutable.ListBuffer + @RunWith(classOf[JUnit4]) class IteratorTest { private def from0 = Iterator.from(0) private class Counted(limit: Int) extends Iterator[Int] { - val max = limit - 1 + val Max = limit - 1 var probed, last, i = -1 - def hasNext = (i < max).tap(_ => probed = i) - def next() = { if (i >= max) Iterator.empty.next() else { i += 1 ; i } }.tap(last = _) + def hasNext = (i < Max).tap(_ => probed = i) + def next() = { if (i >= Max) Iterator.empty.next() else { i += 1 ; i } }.tap(last = _) } private def counted = new Counted(Int.MaxValue) private def limited(n: Int) = new Counted(n) @@ -221,6 +223,15 @@ class IteratorTest { assertSameElements(List(3) ++ List(1, 2, 3).reverseIterator.drop(1), List(3, 2, 1)) } + @Test def `drop does overflow t13052`: Unit = { + var counter = 0L + val it = Iterator.continually(counter.tap(_ => counter += 1)) + val n = 1_000_000_000 + val dropped = it.drop(n).drop(n).drop(n).drop(50) + assertEquals(3L * n + 50L, dropped.next()) + assertEquals(3L * n + 100L, dropped.drop(49).next()) + } + @Test def dropIsChainable(): Unit = { assertSameElements(1 to 4, Iterator from 0 take 5 drop 1) assertSameElements(3 to 4, Iterator from 0 take 5 drop 3) @@ -388,7 +399,7 @@ class IteratorTest { } @Test def lazyListIsLazy(): Unit = { - val results = mutable.ListBuffer.empty[Int] + val results = ListBuffer.empty[Int] def mkIterator = Range.inclusive(1, 5).iterator map (x => { results += x ; x }) def mkInfinite = Iterator continually { results += 1 ; 1 } @@ -402,7 +413,7 @@ class IteratorTest { // scala/bug#3516 @deprecated("Tests deprecated Stream", since="2.13") @Test def toStreamIsSufficientlyLazy(): Unit = { - val results = collection.mutable.ListBuffer.empty[Int] + val results = ListBuffer.empty[Int] def mkIterator = (1 to 5).iterator map (x => { results += x ; x }) def mkInfinite = Iterator continually { results += 1 ; 1 } @@ -416,9 +427,9 @@ class IteratorTest { // scala/bug#8552 @Test def indexOfShouldWorkForTwoParams(): Unit = { assertEquals(1, List(1, 2, 3).iterator.indexOf(2, 0)) - assertEquals(-1, List(5 -> 0).iterator.indexOf(5, 0)) + assertEquals(-1, List(5 -> 0).iterator.indexOf[Any](5, 0)) assertEquals(0, List(5 -> 0).iterator.indexOf((5, 0))) - assertEquals(-1, List(5 -> 0, 9 -> 2, 0 -> 3).iterator.indexOf(9, 2)) + assertEquals(-1, List(5 -> 0, 9 -> 2, 0 -> 3).iterator.indexOf[Any](9, 2)) assertEquals(1, List(5 -> 0, 9 -> 2, 0 -> 3).iterator.indexOf(9 -> 2)) } // scala/bug#9332 @@ -447,7 +458,7 @@ class IteratorTest { def hasNext: Boolean = { counter += 1; parent.hasNext } } // Iterate separately - val res = new mutable.ArrayBuffer[Int] + val res = mutable.ArrayBuffer.empty[Int] it.foreach(res += _) it.foreach(res += _) assertSameElements(exp, res) @@ -771,13 +782,13 @@ class IteratorTest { // scala/bug#10709 @Test def `scan is lazy enough`(): Unit = { - val results = collection.mutable.ListBuffer.empty[Int] + val results = ListBuffer.empty[Int] val it = new AbstractIterator[Int] { var cur = 1 - val max = 3 + val Max = 3 override def hasNext = { results += -cur - cur < max + cur < Max } override def next() = { val res = cur @@ -790,7 +801,7 @@ class IteratorTest { results += -(sum + x) sum + x }) - val scan = collection.mutable.ListBuffer.empty[Int] + val scan = ListBuffer.empty[Int] for (i <- xy) { scan += i results += i @@ -891,7 +902,7 @@ class IteratorTest { } @Test - def t11106(): Unit = { + def `t11106 still lazy after withFilter`: Unit = { var i = 0 Iterator.continually(0) .map(_ => {i += 1; i}) @@ -1049,4 +1060,27 @@ class IteratorTest { slid.next() } } + + // scala/bug#3516 + @Test def `iterator span followed by toSeq`(): Unit = { + def spanA(list: List[Int], x: Int) = + list.iterator.span(_ == x) match { + case (a,b) => (a.toList, b.toList) + } + + def spanB(list: List[Int], x: Int) = + list.iterator.span(_ == x) match { + case (a,b) => (a.toSeq, b.toSeq) match { + case (a,b) => (a.toList, b.toList) + } + } + + assert(spanA(List(1, 2, 1), 1) == (List(1), List(2, 1))) + assert(spanB(List(1, 2, 1), 1) == (List(1), List(2, 1))) + + val original = List(1, 2, 3).iterator + val (front, back) = original.span(_ != 2) + back.drop(1) + assert(front.toList == List(1)) + } } diff --git a/test/junit/scala/collection/MapTest.scala b/test/junit/scala/collection/MapTest.scala index 88fde257205d..76bb730a665c 100644 --- a/test/junit/scala/collection/MapTest.scala +++ b/test/junit/scala/collection/MapTest.scala @@ -53,7 +53,7 @@ class MapTest { val m1 = m ++: m assertEquals(m.toList.sorted, (m1: Map[Int, Int]).toList.sorted) val s1: Iterable[Any] = List(1) ++: m - assertEquals(1 :: m.toList.sorted, s1.toList.sortBy { case (x: Int, _) => x ; case x: Int => x }) + assertEquals(::[Any](1, m.toList.sorted), s1.toList.sortBy { case (x: Int, _) => x ; case x: Int => x }) } @Test diff --git a/test/junit/scala/collection/MinByMaxByTest.scala b/test/junit/scala/collection/MinByMaxByTest.scala index 033ffb163f15..83cd1aacdc7f 100644 --- a/test/junit/scala/collection/MinByMaxByTest.scala +++ b/test/junit/scala/collection/MinByMaxByTest.scala @@ -3,7 +3,6 @@ package scala.collection import org.junit.Assert._ import org.junit.Test -import scala.annotation.unused import scala.tools.testkit.AssertUtil.assertThrows import scala.util.Random @@ -35,8 +34,10 @@ class MinByMaxByTest { def testReturnTheFirstMatch() = { val d = List(1, 2, 3, 4, 5, 6, 7, 8) def f(x: Int) = x % 3; - assert(d.maxBy(f) == 2, "If multiple elements evaluated to the largest value, maxBy should return the first one.") - assert(d.minBy(f) == 3, "If multiple elements evaluated to the largest value, minBy should return the first one.") + assertEquals("If multiple elements evaluated to the largest value, maxBy should return the first one.", + 2, d.maxBy(f)) + assertEquals("If multiple elements evaluated to the largest value, minBy should return the first one.", + 3, d.minBy(f)) } // Make sure it evaluates f no more than list.length times. @@ -44,43 +45,49 @@ class MinByMaxByTest { def testOnlyEvaluateOnce() = { var evaluatedCountOfMaxBy = 0 - @unused val max = list.maxBy(x => { + val max = list.maxBy { x => evaluatedCountOfMaxBy += 1 x * 10 - }) - assert(evaluatedCountOfMaxBy == list.length, s"maxBy: should evaluate f only ${list.length} times, but it evaluated $evaluatedCountOfMaxBy times.") + } + assertTrue(!list.exists(_ > max)) + assertEquals(s"maxBy: should evaluate f only ${list.length} times, but it evaluated $evaluatedCountOfMaxBy times.", + list.length, + evaluatedCountOfMaxBy) var evaluatedCountOfMinBy = 0 - @unused val min = list.minBy(x => { + val min = list.minBy { x => evaluatedCountOfMinBy += 1 x * 10 - }) - assert(evaluatedCountOfMinBy == list.length, s"minBy: should evaluate f only ${list.length} times, but it evaluated $evaluatedCountOfMinBy times.") + } + assertTrue(!list.exists(_ < min)) + assertEquals(s"minBy: should evaluate f only ${list.length} times, but it evaluated $evaluatedCountOfMinBy times.", + list.length, + evaluatedCountOfMinBy) } @Test def checkEmptyOption(): Unit = { - assert(Seq.empty[Int].maxOption == None, "maxOption on a Empty Iterable is None") - assert(Seq.empty[Int].minOption == None, "minOption on a Empty Iterable is None") - assert(Seq.empty[Int].maxByOption(identity) == None, "maxByOption on a Empty Iterable is None") - assert(Seq.empty[Int].minByOption(identity) == None, "minByOption on a Empty Iterable is None") + assertTrue("maxOption on a Empty Iterable is None", Seq.empty[Int].maxOption.isEmpty) + assertTrue("minOption on a Empty Iterable is None", Seq.empty[Int].minOption.isEmpty) + assertTrue("maxByOption on a Empty Iterable is None", Seq.empty[Int].maxByOption(identity).isEmpty) + assertTrue("minByOption on a Empty Iterable is None", Seq.empty[Int].minByOption(identity).isEmpty) } @Test def checkNonEmptyOption(): Unit = { - assert(Seq(1).maxOption == Some(1), "maxOption on a Non Empty Iterable has value") - assert(Seq(1).minOption == Some(1), "minOption on a Non Empty Iterable has value") - assert(Seq(1).maxByOption(identity) == Some(1), "maxByOption on a Non Empty Iterable has value") - assert(Seq(1).minByOption(identity) == Some(1), "minByOption on a Non Empty Iterable has value") + assertEquals("maxOption on a Non Empty Iterable has value", Some(1), Seq(1).maxOption) + assertEquals("minOption on a Non Empty Iterable has value", Some(1), Seq(1).minOption) + assertEquals("maxByOption on a Non Empty Iterable has value", Some(1), Seq(1).maxByOption(identity)) + assertEquals("minByOption on a Non Empty Iterable has value", Some(1), Seq(1).minByOption(identity)) } @Test def testMinMaxCorrectness(): Unit = { import Ordering.Double.IeeeOrdering val seq = Seq(5.0, 3.0, Double.NaN, 4.0) - assert(seq.min.isNaN) - assert(seq.max.isNaN) + assertTrue(seq.min.isNaN) + assertTrue(seq.max.isNaN) } } diff --git a/test/junit/scala/collection/SeqTest.scala b/test/junit/scala/collection/SeqTest.scala index cf370f15574b..8faf8f3e3f02 100644 --- a/test/junit/scala/collection/SeqTest.scala +++ b/test/junit/scala/collection/SeqTest.scala @@ -1,9 +1,9 @@ package scala.collection -import org.junit.Assert._ +import org.junit.Assert.{assertThrows => _, _} import org.junit.Test -import scala.tools.testkit.{AllocationTest, CompileTime} +import scala.tools.testkit.{AllocationTest, AssertUtil, CompileTime}, AssertUtil.assertThrows class SeqTest extends AllocationTest { @@ -114,4 +114,24 @@ class SeqTest extends AllocationTest { exactAllocates(expected(20), "collection seq size 20")( Seq("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19")) } + + /** A sequence of no consequence. */ + class Inconsequential[+A](n: Int) extends AbstractSeq[A] { + def iterator: Iterator[A] = ??? + def apply(i: Int): A = ??? + def length: Int = knownSize + override def knownSize = n + } + object Inconsequential { + def apply(n: Int) = new Inconsequential(n) + } + type ??? = NotImplementedError + + @Test def `sameElements by size`: Unit = { + assertFalse(Inconsequential(0).sameElements(Inconsequential(1))) + assertFalse(Inconsequential(1).sameElements(Inconsequential(2))) + assertTrue(Inconsequential(0).sameElements(Inconsequential(0))) + assertThrows[???](Inconsequential(1).sameElements(Inconsequential(1))) + assertThrows[???](Inconsequential(-1).sameElements(Inconsequential(-1))) + } } diff --git a/test/junit/scala/collection/SetMapRulesTest.scala b/test/junit/scala/collection/SetMapRulesTest.scala index babf1505dc45..bc77a3cda1de 100644 --- a/test/junit/scala/collection/SetMapRulesTest.scala +++ b/test/junit/scala/collection/SetMapRulesTest.scala @@ -237,6 +237,7 @@ class SetMapRulesTest { @Test def testMutableOpenHashMap(): Unit = mapdata.foreach(d => checkMutableMap(() => mutable.OpenHashMap.from(d))) + @annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") @Test def testMutableAnyRefMap(): Unit = mapdata.foreach(d => checkMutableMap(() => mutable.AnyRefMap.from(d))) diff --git a/test/junit/scala/collection/Sizes.scala b/test/junit/scala/collection/Sizes.scala index f68d0ffb4ccd..8041a618d508 100644 --- a/test/junit/scala/collection/Sizes.scala +++ b/test/junit/scala/collection/Sizes.scala @@ -1,9 +1,12 @@ package scala.collection import org.junit._ + import scala.collection.mutable.ListBuffer import org.openjdk.jol.info.GraphLayout +import scala.annotation.nowarn + object Sizes { def list: Int = 24 def listBuffer: Int = 32 @@ -42,6 +45,27 @@ class Sizes { assertTotalSize(16, JOL.netLayout(mutable.ArraySeq.make[String](wrapped), wrapped)) assertTotalSize(16, JOL.netLayout(immutable.ArraySeq.unsafeWrapArray[String](wrapped), wrapped)) } + + @Test + def stream(): Unit = { + def next = new Object + @nowarn("cat=deprecation") + val st = Stream.continually(next).take(100) + locally(st.mkString) // force 100 elements + val l = JOL.netLayout(st) + // println(l.toFootprint) + assertTotalSize(4016, l) + } + + @Test + def lazyList(): Unit = { + def next = new Object + val ll = LazyList.continually(next).take(100) + locally(ll.mkString) // force 100 elements + val l = JOL.netLayout(ll) + // println(l.toFootprint) + assertTotalSize(4024, l) + } } // TODO move to test-kit diff --git a/test/junit/scala/collection/StringOpsTest.scala b/test/junit/scala/collection/StringOpsTest.scala index ad2debd0d69c..cbf5c2fafd61 100644 --- a/test/junit/scala/collection/StringOpsTest.scala +++ b/test/junit/scala/collection/StringOpsTest.scala @@ -102,4 +102,18 @@ class StringOpsTest { assertEquals("de", "abcdef".collect { case c @ ('b' | 'c') => (c+2).toChar }) assertEquals(Seq('d'.toInt, 'e'.toInt), "abcdef".collect { case c @ ('b' | 'c') => (c+2).toInt }) } + + @Test def init(): Unit = { + assertEquals("ab", "abc".init) + assertEquals("a", "ab".init) + assertEquals("", "a".init) + assertThrows[UnsupportedOperationException]("".init) + } + + @Test def tail(): Unit = { + assertEquals("bc", "abc".tail) + assertEquals("b", "ab".tail) + assertEquals("", "a".tail) + assertThrows[UnsupportedOperationException]("".tail) + } } diff --git a/test/junit/scala/collection/convert/MapWrapperTest.scala b/test/junit/scala/collection/convert/MapWrapperTest.scala index 521cec2410c4..d180828c1b93 100644 --- a/test/junit/scala/collection/convert/MapWrapperTest.scala +++ b/test/junit/scala/collection/convert/MapWrapperTest.scala @@ -3,7 +3,7 @@ package scala.collection.convert import java.{util => jutil} import org.junit.Assert.{assertEquals, assertFalse, assertTrue} -import org.junit.Test +import org.junit.{Ignore, Test} import org.junit.runner.RunWith import org.junit.runners.JUnit4 @@ -83,27 +83,33 @@ class MapWrapperTest { } // was: induce intermittent failure due to contention, where updater is called more than once - @Test def `t12586 updateWith should delegate to compute`: Unit = { + @Test @Ignore("busy work") def `t12586 updateWith should delegate to compute`: Unit = { + import jutil.concurrent.ConcurrentHashMap val limit = 100 // retries until trigger @volatile var count = 0 - val jmap = new jutil.concurrent.ConcurrentHashMap[String, String]() + val jmap = new ConcurrentHashMap[String, Int]() class Loki extends Runnable { @volatile var done = false def run(): Unit = { while (!done) { - jmap.put("KEY", "VALUE") + jmap.put("KEY", 1) //Thread.`yield`() } } } + val wrapped = jmap.asScala val loki = new Loki val runner = new Thread(loki).tap(_.start) - val wrapped = jmap.asScala - def updater(old: Option[String]) = { count += 1 ; old.map(_ * 2) } + def updater(old: Option[Int]) = { + count += 1 + old.map(_ + 1) + // .tap(res => println(s"count $count: res=$res")) + } for (i <- 1 to limit) { count = 0 wrapped.updateWith("KEY")(updater) assertEquals(s"index $i", 1, count) + //Thread.`yield`() } loki.done = true runner.join() diff --git a/test/junit/scala/collection/generic/DecoratorsTest.scala b/test/junit/scala/collection/generic/DecoratorsTest.scala index 20bb73129e47..aeb4e542f24b 100644 --- a/test/junit/scala/collection/generic/DecoratorsTest.scala +++ b/test/junit/scala/collection/generic/DecoratorsTest.scala @@ -1,13 +1,16 @@ package scala.collection.generic import org.junit.Test +import org.junit.Assert.{assertEquals, assertTrue} import scala.AdaptedArrowAssocWorkaround.Tx -import scala.annotation.unused import scala.collection.immutable.{BitSet, IntMap, LongMap, TreeMap, TreeSet} import scala.collection.{BuildFrom, View, mutable} import scala.language.implicitConversions +import scala.tools.testkit.AssertUtil.assertSameElements +@annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") + @annotation.nowarn("cat=deprecation&origin=scala.collection.generic.IsMap.anyRefMapIsMap") class DecoratorsTest { @Test @@ -26,11 +29,13 @@ class DecoratorsTest { val xs1 = Iterator(1, 2, 3, 4, 5) val xs2 = xs1.filterMap(f) - @unused val xs2T: Iterator[Int] = xs2 + val xs2T: Iterator[Int] = xs2 + assertSameElements(List(2, 4), xs2T) val xs3 = Array(1, 2, 3, 4, 5) val xs4 = xs3.filterMap(f) - @unused val xs4T: Array[Int] = xs4 + val xs4T: Array[Int] = xs4 + assertSameElements(List(2, 4), xs4T) } @Test @@ -50,47 +55,68 @@ class DecoratorsTest { val i: Int => Option[Int] = x => if (x % 2 == 0) Some(2 * x) else None val xs1 = List(1, 2, 3).filterMap(f) - @unused val xs1T: List[String] = xs1 + val xs1T: List[String] = xs1 + assertSameElements(List("2"), xs1T) val xs2 = List(1, 2, 3).view.filterMap(f) - @unused val xs2T: View[String] = xs2 + val xs2T: View[String] = xs2 + assertSameElements(List("2"), xs2T) val xs3 = Vector(1, 2, 3).filterMap(f) - @unused val xs3T: Vector[String] = xs3 + val xs3T: Vector[String] = xs3 + assertSameElements(List("2"), xs3T) val xs4 = Vector(1, 2, 3).view.filterMap(f) - @unused val xs4T: View[String] = xs4 + val xs4T: View[String] = xs4 + assertSameElements(List("2"), xs4T) val xs5 = (1 to 10).filterMap(f) - @unused val xs5T: IndexedSeq[String] = xs5 + val xs5T: IndexedSeq[String] = xs5 + assertSameElements(List(2,4,6,8,10).map(_.toString), xs5T) val xs6 = (1 to 10).view.filterMap(f) - @unused val xs6T: View[String] = xs6 + val xs6T: View[String] = xs6 + assertSameElements(List(2,4,6,8,10).map(_.toString), xs6T) val xs7 = Array(1, 2, 3).filterMap(f) - @unused val xs7T: Array[String] = xs7 + val xs7T: Array[String] = xs7 + assertSameElements(List("2"), xs7T) val xs8 = Array(1, 2, 3).view.filterMap(f) - @unused val xs8T: View[String] = xs8 + val xs8T: View[String] = xs8 + assertSameElements(List("2"), xs8T) val xs9 = "foo".filterMap(g) - @unused val xs9T: IndexedSeq[Int] = xs9 + val xs9T: IndexedSeq[Int] = xs9 + assertTrue(xs9T.isEmpty) val xs10 = "foo".view.filterMap(g) - @unused val xs10T: View[Int] = xs10 + val xs10T: View[Int] = xs10 + assertTrue(xs10T.isEmpty) val xs11 = Map(1 -> "foo").filterMap(h) - @unused val xs11T: Map[String, Int] = xs11 + val xs11T: Map[String, Int] = xs11 + assertTrue(xs11T.isEmpty) val xs12 = Map(1 -> "foo").view.filterMap(h) - @unused val xs12T: View[(String, Int)] = xs12 + val xs12T: View[(String, Int)] = xs12 + assertTrue(xs12T.isEmpty) val xs13 = TreeMap(1 -> "foo").filterMap(h) - @unused val xs13T: TreeMap[String, Int] = xs13 + val xs13T: TreeMap[String, Int] = xs13 + assertTrue(xs13T.isEmpty) val xs14 = TreeMap(1 -> "foo").view.filterMap(h) - @unused val xs14T: View[(String, Int)] = xs14 + val xs14T: View[(String, Int)] = xs14 + assertTrue(xs14T.isEmpty) val xs15 = BitSet(1, 2, 3).filterMap(i) - @unused val xs15T: BitSet = xs15 + val xs15T: BitSet = xs15 + assertSameElements(List(4), xs15T) val xs16 = BitSet(1, 2, 3).view.filterMap(i) - @unused val xs16T: View[Int] = xs16 + val xs16T: View[Int] = xs16 + assertSameElements(List(4), xs16T) val xs17 = Set(1, 2, 3).filterMap(f) - @unused val xs17T: Set[String] = xs17 + val xs17T: Set[String] = xs17 + assertSameElements(List("2"), xs17T) val xs18 = Set(1, 2, 3).view.filterMap(f) - @unused val xs18T: View[String] = xs18 + val xs18T: View[String] = xs18 + assertSameElements(List("2"), xs18T) val xs19 = TreeSet(1, 2, 3).filterMap(f) - @unused val xs19T: TreeSet[String] = xs19 + val xs19T: TreeSet[String] = xs19 + assertSameElements(List("2"), xs19T) val xs20 = TreeSet(1, 2, 3).view.filterMap(f) - @unused val xs20T: View[String] = xs20 + val xs20T: View[String] = xs20 + assertSameElements(List("2"), xs20T) val xs21 = TreeSet(1, 2, 3).filterMap(f) - @unused val xs21T: TreeSet[String] = xs21 + val xs21T: TreeSet[String] = xs21 + assertSameElements(List("2"), xs21T) } @Test @@ -118,7 +144,7 @@ class DecoratorsTest { lastTestResult match { case None => currentGroup.addOne(elem) - case Some(lastTest) if currentTest == lastTest => + case Some(`currentTest`) => currentGroup.addOne(elem) case Some(_) => groups.addOne(currentGroup.result()) @@ -134,25 +160,35 @@ class DecoratorsTest { val p: Int => Boolean = _ % 2 == 0 val xs = List(1, 2, 3).groupedWith(p) - @unused val xsT: List[List[Int]] = xs + val xsT: List[List[Int]] = xs + assertEquals(List(1, 2, 3).map(List(_)), xsT) val xs2 = List(1, 2, 3).view.groupedWith(p) - @unused val xs2T: View[View[Int]] = xs2 + val xs2T: View[View[Int]] = xs2 + assertSameElements(List(1, 2, 3).map(List(_)), xs2T.map(_.toList)) val xs3 = Vector(1, 2, 3).groupedWith(p) - @unused val xs3T: Vector[Vector[Int]] = xs3 + val xs3T: Vector[Vector[Int]] = xs3 + assertEquals(Vector(1, 2, 3).map(Vector(_)), xs3T) val xs4 = Vector(1, 2, 3).view.groupedWith(p) - @unused val xs4T: View[View[Int]] = xs4 + val xs4T: View[View[Int]] = xs4 + assertSameElements(Vector(1, 2, 3).map(Vector(_)), xs4T.map(_.toVector)) val xs5 = (1 to 10).groupedWith(p) - @unused val xs5T: IndexedSeq[IndexedSeq[Int]] = xs5 + val xs5T: IndexedSeq[IndexedSeq[Int]] = xs5 + assertSameElements((1 to 10).toVector.map(Vector(_)), xs5T.map(_.toVector)) val xs6 = (1 to 10).view.groupedWith(p) - @unused val xs6T: View[View[Int]] = xs6 + val xs6T: View[View[Int]] = xs6 + assertSameElements((1 to 10).toVector.map(Vector(_)), xs6T.map(_.toVector)) val xs7 = Array(1, 2, 3).groupedWith(p) - @unused val xs7T: Array[Array[Int]] = xs7 + val xs7T: Array[Array[Int]] = xs7 + assertSameElements(Vector(1, 2, 3).map(Vector(_)), xs7T.map(_.toVector)) val xs8 = Array(1, 2, 3).view.groupedWith(p) - @unused val xs8T: View[View[Int]] = xs8 + val xs8T: View[View[Int]] = xs8 + assertSameElements(Vector(1, 2, 3).map(Vector(_)), xs8T.map(_.toVector)) val xs9 = "foo".groupedWith(_.isLower) - @unused val xs9T: IndexedSeq[String] = xs9 + val xs9T: IndexedSeq[String] = xs9 + assertEquals(List("foo"), xs9T) val xs10 = "foo".view.groupedWith(_.isLower) - @unused val xs10T: View[View[Char]] = xs10 + val xs10T: View[View[Char]] = xs10 + assertEquals(Vector("foo".toVector), xs10T.toVector.map(_.toVector)) } @Test @@ -180,63 +216,83 @@ class DecoratorsTest { val map = Map(1 -> "foo") val mapLJoin = map.leftOuterJoin(Map(1 -> "bar")) - @unused val mapLJoinT: Map[Int, (String, Option[String])] = mapLJoin + val mapLJoinT: Map[Int, (String, Option[String])] = mapLJoin + assertEquals(Map(1 -> ("foo" -> Some("bar"))), mapLJoinT) val mapRJoin = map.rightOuterJoin(Map(1 -> "bar")) - @unused val mapRJoinT: Map[Int, (Option[String], String)] = mapRJoin + val mapRJoinT: Map[Int, (Option[String], String)] = mapRJoin + assertEquals(Map(1 -> (Some("foo") -> "bar")), mapRJoinT) val mapView = Map(1 -> "foo").view val mapViewLJoin = mapView.leftOuterJoin(Map(1 -> "bar")) - @unused val mapViewLJoinT: View[(Int, (String, Option[String]))] = mapViewLJoin + val mapViewLJoinT: View[(Int, (String, Option[String]))] = mapViewLJoin + assertSameElements(List(1 -> ("foo" -> Some("bar"))), mapViewLJoinT) val mapViewRJoin = mapView.rightOuterJoin(Map(1 -> "bar")) - @unused val mapViewRJoinT: View[(Int, (Option[String], String))] = mapViewRJoin + val mapViewRJoinT: View[(Int, (Option[String], String))] = mapViewRJoin + assertSameElements(List(1 -> (Some("foo") -> "bar")), mapViewRJoinT) val treemap = TreeMap(1 -> "foo") val treemapLJoin = treemap.leftOuterJoin(Map(1 -> "bar")) - @unused val treemapLJoinT: TreeMap[Int, (String, Option[String])] = treemapLJoin + val treemapLJoinT: TreeMap[Int, (String, Option[String])] = treemapLJoin + assertEquals(Map(1 -> ("foo" -> Some("bar"))), treemapLJoinT) val treemapRJoin = treemap.rightOuterJoin(Map(1 -> "bar")) - @unused val treemapRJoinT: TreeMap[Int, (Option[String], String)] = treemapRJoin + val treemapRJoinT: TreeMap[Int, (Option[String], String)] = treemapRJoin + assertEquals(Map(1 -> (Some("foo") -> "bar")), treemapRJoinT) val treemapView = TreeMap(1 -> "foo").view val treemapViewLJoin = treemapView.leftOuterJoin(Map(1 -> "bar")) - @unused val treemapViewLJoinT: View[(Int, (String, Option[String]))] = treemapViewLJoin + val treemapViewLJoinT: View[(Int, (String, Option[String]))] = treemapViewLJoin + assertSameElements(List(1 -> ("foo" -> Some("bar"))), treemapViewLJoinT) val treemapViewRJoin = treemapView.rightOuterJoin(Map(1 -> "bar")) - @unused val treemapViewRJoinT: View[(Int, (Option[String], String))] = treemapViewRJoin + val treemapViewRJoinT: View[(Int, (Option[String], String))] = treemapViewRJoin + assertSameElements(List(1 -> (Some("foo") -> "bar")), treemapViewRJoinT) val mmap = mutable.Map(1 -> "foo") val mmapLJoin = mmap.leftOuterJoin(Map(1 -> "bar")) - @unused val mmapLJoinT: mutable.Map[Int, (String, Option[String])] = mmapLJoin + val mmapLJoinT: mutable.Map[Int, (String, Option[String])] = mmapLJoin + assertEquals(Map(1 -> ("foo" -> Some("bar"))), mmapLJoinT) val mmapRJoin = mmap.rightOuterJoin(Map(1 -> "bar")) - @unused val mmapRJoinT: mutable.Map[Int, (Option[String], String)] = mmapRJoin + val mmapRJoinT: mutable.Map[Int, (Option[String], String)] = mmapRJoin + assertEquals(Map(1 -> (Some("foo") -> "bar")), mmapRJoinT) val mmapView = mutable.Map(1 -> "foo").view val mmapViewLJoin = mmapView.leftOuterJoin(Map(1 -> "bar")) - @unused val mmapViewLJoinT: View[(Int, (String, Option[String]))] = mmapViewLJoin + val mmapViewLJoinT: View[(Int, (String, Option[String]))] = mmapViewLJoin + assertSameElements(List(1 -> ("foo" -> Some("bar"))), mmapViewLJoinT) val mmapViewRJoin = mmapView.rightOuterJoin(Map(1 -> "bar")) - @unused val mmapViewRJoinT: View[(Int, (Option[String], String))] = mmapViewRJoin + val mmapViewRJoinT: View[(Int, (Option[String], String))] = mmapViewRJoin + assertSameElements(List(1 -> (Some("foo") -> "bar")), mmapViewRJoinT) val anyrefmap = mutable.AnyRefMap("foo" -> 1) val anyrefmapLJoin = anyrefmap.leftOuterJoin(Map("bar" -> true)) - @unused val anyrefmapLJoinT: mutable.AnyRefMap[String, (Int, Option[Boolean])] = anyrefmapLJoin + val anyrefmapLJoinT: mutable.AnyRefMap[String, (Int, Option[Boolean])] = anyrefmapLJoin + assertEquals(Map("foo" -> (1 -> None)), anyrefmapLJoinT) val anyrefmapRJoin = anyrefmap.rightOuterJoin(Map("bar" -> true)) - @unused val anyrefmapRJoinT: mutable.AnyRefMap[String, (Option[Int], Boolean)] = anyrefmapRJoin + val anyrefmapRJoinT: mutable.AnyRefMap[String, (Option[Int], Boolean)] = anyrefmapRJoin + assertEquals(Map("bar" -> (None -> true)), anyrefmapRJoinT) val intmap = IntMap(1 -> "foo") val intmapLJoin = intmap.leftOuterJoin(Map(1 -> "bar")) - @unused val intmapLJoinT: IntMap[(String, Option[String])] = intmapLJoin + val intmapLJoinT: IntMap[(String, Option[String])] = intmapLJoin + assertEquals(Map(1 -> ("foo" -> Some("bar"))), intmapLJoinT) val intmapRJoin = intmap.rightOuterJoin(Map(1 -> "bar")) - @unused val intmapRJoinT: IntMap[(Option[String], String)] = intmapRJoin + val intmapRJoinT: IntMap[(Option[String], String)] = intmapRJoin + assertEquals(Map(1 -> (Some("foo") -> "bar")), intmapRJoinT) val longmap = LongMap(1L -> "foo") val longmapLJoin = longmap.leftOuterJoin(Map(1L -> "bar")) - @unused val longmapLJoinT: LongMap[(String, Option[String])] = longmapLJoin + val longmapLJoinT: LongMap[(String, Option[String])] = longmapLJoin + assertEquals(Map(1L -> ("foo" -> Some("bar"))), longmapLJoinT) val longmapRJoin = longmap.rightOuterJoin(Map(1L -> "bar")) - @unused val longmapRJoinT: LongMap[(Option[String], String)] = longmapRJoin + val longmapRJoinT: LongMap[(Option[String], String)] = longmapRJoin + assertEquals(Map(1L -> (Some("foo") -> "bar")), longmapRJoinT) val mlongmap = mutable.LongMap(1L -> "foo") val mlongmapLJoin = mlongmap.leftOuterJoin(Map(1L -> "bar")) - @unused val mlongmapLJoinT: mutable.LongMap[(String, Option[String])] = mlongmapLJoin + val mlongmapLJoinT: mutable.LongMap[(String, Option[String])] = mlongmapLJoin + assertEquals(Map(1L -> ("foo" -> Some("bar"))), mlongmapLJoinT) val mlongmapRJoin = mlongmap.rightOuterJoin(Map(1L -> "bar")) - @unused val mlongmapRJoinT: mutable.LongMap[(Option[String], String)] = mlongmapRJoin + val mlongmapRJoinT: mutable.LongMap[(Option[String], String)] = mlongmapRJoin + assertEquals(Map(1L -> (Some("foo") -> "bar")), mlongmapRJoinT) } } diff --git a/test/junit/scala/collection/immutable/ArraySeqTest.scala b/test/junit/scala/collection/immutable/ArraySeqTest.scala index f8edc6024d28..c7b7eea460f3 100644 --- a/test/junit/scala/collection/immutable/ArraySeqTest.scala +++ b/test/junit/scala/collection/immutable/ArraySeqTest.scala @@ -143,15 +143,15 @@ class ArraySeqTest { @Test def foldAny(): Unit = { val a = ArraySeq[Any](1, "3") - assertEquals(a.foldLeft("")(_ + _), "13") - assertEquals(a.foldRight(List.empty[Any])(_ :: _), List(1, "3")) + assertEquals("13", a.foldLeft("")(_ + _)) + assertEquals(List[Any](1, "3"), a.foldRight(List.empty[Any])(_ :: _)) } @Test def from(): Unit = { val as = ArraySeq("foo", "bar", "baz") - assert(ArraySeq.from(as) eq as) - assert(ArraySeq(as: _*) eq as) + assertSame(as, ArraySeq.from(as)) + assertSame(as, ArraySeq(as: _*)) } private def assertConcat[A](lhs: ArraySeq[A], rhs: ArraySeq[A], expect: ArraySeq[A]): Array[_] = { diff --git a/test/junit/scala/collection/immutable/LazyListGCTest.scala b/test/junit/scala/collection/immutable/LazyListGCTest.scala index 3ebae3cad0ee..7da9550cf605 100644 --- a/test/junit/scala/collection/immutable/LazyListGCTest.scala +++ b/test/junit/scala/collection/immutable/LazyListGCTest.scala @@ -116,4 +116,10 @@ class LazyListGCTest { def tails_zipWithIndex_foreach_allowsGC(): Unit = { assertLazyListOpAllowsGC((ll, check) => ll.tails.zipWithIndex.foreach { case (_, i) => check(i) }, _ => ()) } + + @Test + def foldLeft(): Unit = { + // fails when using `/:` instead of `foldLeft` + assertLazyListOpAllowsGC((ll, check) => ll.foldLeft(0){ case (s, x) => check(x); s + x}, _ => ()) + } } diff --git a/test/junit/scala/collection/immutable/LazyListTest.scala b/test/junit/scala/collection/immutable/LazyListTest.scala index 8ff9ebb72361..7e69b64f9bf8 100644 --- a/test/junit/scala/collection/immutable/LazyListTest.scala +++ b/test/junit/scala/collection/immutable/LazyListTest.scala @@ -1,36 +1,86 @@ package scala.collection package immutable -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.Test import org.junit.Assert._ +import org.junit.Test +import java.io.NotSerializableException import scala.annotation.unused +import scala.collection.immutable.LazyListTest.sd import scala.collection.mutable.{Builder, ListBuffer} -import scala.tools.testkit.{AssertUtil, ReflectUtil} +import scala.tools.testkit.AssertUtil import scala.util.Try -@RunWith(classOf[JUnit4]) class LazyListTest { - @Test - def serialization(): Unit = { - import java.io._ + /* + def countAlloc[T](f: => T): Int = { + locally(LazyList.empty) // init + LazyList.k = 0 + f + LazyList.k + } - def serialize(obj: AnyRef): Array[Byte] = { - val buffer = new ByteArrayOutputStream - val out = new ObjectOutputStream(buffer) - out.writeObject(obj) - buffer.toByteArray - } + @Test def counts(): Unit = { + // N*3 + println(countAlloc((1 #:: 2 #:: 3 #:: 4 #:: LazyList.empty).toList)) - def deserialize(a: Array[Byte]): AnyRef = { - val in = new ObjectInputStream(new ByteArrayInputStream(a)) - in.readObject - } + // N*4 + println(countAlloc(LazyList.from(1).take(10).toList)) - def serializeDeserialize[T <: AnyRef](obj: T) = deserialize(serialize(obj)).asInstanceOf[T] + // N*6 + println(countAlloc(LazyList.from(1).take(20).take(10).toList)) + } + */ + + @Test def consNull(): Unit = { + val ll = LazyList.cons(1, LazyList.cons(2, null)) + assert(ll.head == 1) + assert(ll.tail.head == 2) + locally(ll.tail.tail) + AssertUtil.assertThrows[NullPointerException](ll.tail.tail.head) + + val ll1 = LazyList.cons[AnyRef](null, null) + assert(ll1.head == null) + locally(ll1.tail) + AssertUtil.assertThrows[NullPointerException](ll1.tail.head) + } + + @Test def throwEval(): Unit = { + var bad = true + val ll = 1 #:: { if (bad) { bad = false; throw new RuntimeException() }; 2} #:: LazyList.empty + try ll.toList catch { case _: RuntimeException => () } + assertTrue(ll.toList == List(1, 2)) + } + + @Test def racySerialization(): Unit = { + import sd._ + val ll = 1 #:: { Thread.sleep(500); 2} #:: LazyList.empty + new Thread(() => println(ll.toList)).start() + Thread.sleep(200) + AssertUtil.assertThrows[NotSerializableException](serialize(ll), _.contains("MidEvaluation")) + } + + @Test def storeNull(): Unit = { + val l = "1" #:: null #:: "2" #:: LazyList.empty + assert(l.toList == List("1", null, "2")) + assert(l.tail.head == null) + assert(!l.tail.isEmpty) + } + + @Test def nse(): Unit = { + val l = 1 #:: 2 #:: LazyList.empty + AssertUtil.assertThrows[NoSuchElementException](l.tail.tail.head) + AssertUtil.assertThrows[UnsupportedOperationException](l.tail.tail.tail) + } + + @Test + def serialization(): Unit = { + import sd._ + + val emptyD = serializeDeserialize(LazyList.empty) + assertNotSame(LazyList.empty, emptyD) // deserialization creates a new instance with both fields `null` + assertEquals(LazyList.empty, emptyD) val l = LazyList.from(10) @@ -41,40 +91,27 @@ class LazyListTest { val ld2 = serializeDeserialize(l) assertEquals(l.take(10).toList, ld2.take(10).toList) + // this used to be a test for scala/scala#10118 + // we used to have: `knownIsEmpty = stateEvaluated && (state eq State.Empty)` a forged stream could have + // `stateEvaluated = true` but a non-evaluated `state` lazy val, leading to lazyState evaluation. + // after scala/scala#10942, the test no longer makes sense, as the original attack path is no longer possible. + // we have `knownIsEmpty = stateDefined && isEmpty`, if `!stateDefined` then `isEmpty` can no longer trigger + // `lazyState` evaluation LazyListTest.serializationForceCount = 0 val u = LazyList.from(10).map(x => { LazyListTest.serializationForceCount += 1; x }) - @unused def printDiff(): Unit = { - val a = serialize(u) - ReflectUtil.getFieldAccessible[LazyList[_]]("scala$collection$immutable$LazyList$$stateEvaluated").setBoolean(u, true) - val b = serialize(u) - val i = a.zip(b).indexWhere(p => p._1 != p._2) - println("difference: ") - println(s"val from = ${a.slice(i - 10, i + 10).mkString("List[Byte](", ", ", ")")}") - println(s"val to = ${b.slice(i - 10, i + 10).mkString("List[Byte](", ", ", ")")}") - } - - // to update this test, comment-out `LazyList.writeReplace` and run `printDiff` - // printDiff() - - val from = List[Byte](83, 116, 97, 116, 101, 59, 120, 112, 0, 0, 0, 115, 114, 0, 33, 106, 97, 118, 97, 46) - val to = List[Byte](83, 116, 97, 116, 101, 59, 120, 112, 0, 0, 1, 115, 114, 0, 33, 106, 97, 118, 97, 46) - assertEquals(LazyListTest.serializationForceCount, 0) u.head assertEquals(LazyListTest.serializationForceCount, 1) val data = serialize(u) - var i = data.indexOfSlice(from) - to.foreach(x => {data(i) = x; i += 1}) - val ud1 = deserialize(data).asInstanceOf[LazyList[Int]] + val ud = deserialize(data).asInstanceOf[LazyList[Int]] - // this check failed before scala/scala#10118, deserialization triggered evaluation assertEquals(LazyListTest.serializationForceCount, 1) - ud1.tail.head + ud.tail.head assertEquals(LazyListTest.serializationForceCount, 2) u.tail.head @@ -217,6 +254,20 @@ class LazyListTest { assertEquals("LazyList(1)", l.toString) } + @Test def toStringTailCycle(): Unit = { + lazy val xs: LazyList[Int] = 1 #:: 2 #:: xs + xs.tail.tail.head + assertEquals("LazyList(1, 2, )", xs.toString) + assertEquals("LazyList(2, 1, )", xs.tail.toString) + assertEquals("LazyList(1, 2, )", xs.tail.tail.toString) + + val ys = 0 #:: xs + ys.tail.tail.tail.head + assertEquals("LazyList(0, 1, 2, )", ys.toString) + assertEquals("LazyList(1, 2, )", ys.tail.toString) + assertEquals("LazyList(2, 1, )", ys.tail.tail.toString) + } + @Test def testLazyListToStringWhenLazyListHasCyclicReference(): Unit = { lazy val cyc: LazyList[Int] = 1 #:: 2 #:: 3 #:: 4 #:: cyc @@ -233,6 +284,10 @@ class LazyListTest { assertEquals("LazyList(1, 2, 3, 4, )", cyc.toString) cyc.tail.tail.tail.tail.head assertEquals("LazyList(1, 2, 3, 4, )", cyc.toString) + + lazy val c1: LazyList[Int] = 1 #:: c1 + c1.tail.tail.tail + assertEquals("LazyList(1, )", c1.toString) } @Test @@ -257,10 +312,13 @@ class LazyListTest { assertEquals( "LazyList(1, 2, 3)", xs.toString()) } - val cycle1: LazyList[Int] = 1 #:: 2 #:: cycle1 - val cycle2: LazyList[Int] = 1 #:: 2 #:: 3 #:: cycle2 @Test(timeout=10000) def testSameElements(): Unit = { + object i { + val cycle1: LazyList[Int] = 1 #:: 2 #:: cycle1 + val cycle2: LazyList[Int] = 1 #:: 2 #:: 3 #:: cycle2 + } + import i._ assert(LazyList().sameElements(LazyList())) assert(!LazyList().sameElements(LazyList(1))) assert(LazyList(1,2).sameElements(LazyList(1,2))) @@ -425,7 +483,7 @@ class LazyListTest { def assertNoStackOverflow[A](lazyList: LazyList[A]): Unit = { // don't hang the test if we've made a programming error in this test val finite = lazyList.take(1000) - AssertUtil.assertThrows[RuntimeException](finite.force, _ contains "self-referential") + AssertUtil.assertThrows[RuntimeException](finite.force, _ contains "self-reference") } assertNoStackOverflow { class L { val ll: LazyList[Nothing] = LazyList.empty #::: ll }; (new L).ll } assertNoStackOverflow { class L { val ll: LazyList[Int] = 1 #:: ll.map(_ + 1).filter(_ % 2 == 0) }; (new L).ll } @@ -435,6 +493,8 @@ class LazyListTest { } assertNoStackOverflow((new L).a) assertNoStackOverflow((new L).b) + + assertNoStackOverflow { object t { val ll: LazyList[Int] = 1 #:: ll.drop(1) }; t.ll } } // scala/bug#11931 @@ -448,4 +508,22 @@ class LazyListTest { object LazyListTest { var serializationForceCount = 0 -} \ No newline at end of file + + object sd { + import java.io._ + + def serialize(obj: AnyRef): Array[Byte] = { + val buffer = new ByteArrayOutputStream + val out = new ObjectOutputStream(buffer) + out.writeObject(obj) + buffer.toByteArray + } + + def deserialize(a: Array[Byte]): AnyRef = { + val in = new ObjectInputStream(new ByteArrayInputStream(a)) + in.readObject + } + + def serializeDeserialize[T <: AnyRef](obj: T) = deserialize(serialize(obj)).asInstanceOf[T] + } +} diff --git a/test/junit/scala/collection/immutable/NumericRangeTest.scala b/test/junit/scala/collection/immutable/NumericRangeTest.scala index 88fca75313b0..8264cb3791ab 100644 --- a/test/junit/scala/collection/immutable/NumericRangeTest.scala +++ b/test/junit/scala/collection/immutable/NumericRangeTest.scala @@ -395,8 +395,8 @@ class NumericRangeTest { assertEquals(300 / 5, NumericRange(BigInt(0), BigInt(Int.MaxValue), BigInt(5)).lastIndexOf(BigInt(300))) // indexOf different type returns -1 - assertEquals(-1, NumericRange(0L, Int.MaxValue.toLong, 5L).indexOf(300)) - assertEquals(-1, NumericRange(0L, Int.MaxValue.toLong, 5L).lastIndexOf(300)) + assertEquals(-1, NumericRange(0L, Int.MaxValue.toLong, 5L).indexOf[AnyVal](300)) + assertEquals(-1, NumericRange(0L, Int.MaxValue.toLong, 5L).lastIndexOf[AnyVal](300)) /* Attempting an indexOf of a Range with more than Int.MaxValue elements always throws an error. Not ideal, but this tests whether backwards compatibility is conserved. */ @@ -453,4 +453,4 @@ object NumericRangeTest { override def compare(x: NumericWrapper[T], y: NumericWrapper[T]): Int = tNum.compare(x.value, y.value) } } -} \ No newline at end of file +} diff --git a/test/junit/scala/collection/immutable/TreeSeqMapTest.scala b/test/junit/scala/collection/immutable/TreeSeqMapTest.scala index bf46f8d0cb57..cdf214774070 100644 --- a/test/junit/scala/collection/immutable/TreeSeqMapTest.scala +++ b/test/junit/scala/collection/immutable/TreeSeqMapTest.scala @@ -174,6 +174,12 @@ class TreeSeqMapTest { assertEquals(s"modification empty from instance keeps modification order", List(1 -> 3, 3 -> 4), e3.toList) } } + @Test + def `t13019 empty.iterator is idempotent`: Unit = { + val m = util.Try(TreeSeqMap.empty.iterator.next()) + assertTrue(m.isFailure) + assertFalse("empty iterator does not have next", TreeSeqMap.empty.iterator.hasNext) + } } object TreeSeqMapTest extends App { import TreeSeqMap.Ordering._ diff --git a/test/junit/scala/collection/immutable/VectorTest.scala b/test/junit/scala/collection/immutable/VectorTest.scala index 268addbc1f1d..64d839d8c966 100644 --- a/test/junit/scala/collection/immutable/VectorTest.scala +++ b/test/junit/scala/collection/immutable/VectorTest.scala @@ -391,7 +391,7 @@ class VectorTest { assertEquals(Vector(1,2,3), v) - val f: Any => Unit = println + val f: Any => Unit = _ => () // test that type info is not lost @unused val x: Vector[Char] = Vector[Char]().tapEach(f) @@ -465,7 +465,7 @@ class VectorTest { assertEquals(1 to 5, vector) assertEquals(vector.updated(0, 20), Vector(20,2,3,4,5)) - assertEquals(vector.updated(0, ""), Vector("",2,3,4,5)) + assertEquals(vector.updated[Any](0, ""), Vector[Any]("",2,3,4,5)) assertEquals(1 to 5, arraySeq) // ensure arraySeq is not mutated } locally { @@ -474,7 +474,7 @@ class VectorTest { val vector = Vector.from(arr) assertEquals(arr.toList, vector) assertEquals(List(20), vector.updated(0, 20)) - assertEquals(List(""), vector.updated(0, "")) + assertEquals(List(""), vector.updated[Any](0, "")) } } diff --git a/test/junit/scala/collection/immutable/WrappedStringTest.scala b/test/junit/scala/collection/immutable/WrappedStringTest.scala index ad8e26dcfe88..2627aac763e2 100644 --- a/test/junit/scala/collection/immutable/WrappedStringTest.scala +++ b/test/junit/scala/collection/immutable/WrappedStringTest.scala @@ -10,6 +10,6 @@ class WrappedStringTest { @Test // scala/bug#11518 def indexOf_nonChar(): Unit = { - assertEquals(-1, new WrappedString("test").indexOf("not a Char")) // doesn't overflow + assertEquals(-1, new WrappedString("test").indexOf[Any]("not a Char")) // doesn't overflow } } diff --git a/test/junit/scala/collection/mutable/AnyRefMapTest.scala b/test/junit/scala/collection/mutable/AnyRefMapTest.scala index d0fb6d4c3473..0d2e410de677 100644 --- a/test/junit/scala/collection/mutable/AnyRefMapTest.scala +++ b/test/junit/scala/collection/mutable/AnyRefMapTest.scala @@ -5,9 +5,29 @@ import org.junit.runners.JUnit4 import org.junit.Test import org.junit.Assert._ +import scala.collection.immutable + + /* Test for scala/bug#10540 */ @RunWith(classOf[JUnit4]) +@annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") class AnyRefMapTest { + @Test def t13048(): Unit = { + def t(x: AnyRef, y: AnyRef): Unit = { + val m = AnyRefMap.empty[AnyRef, Unit] + m.getOrElseUpdate(x, m.getOrElseUpdate(y, ())) + assert(m.keys.toSet == immutable.Set(x, y)) + } + val o1 = new AnyRef { + override val hashCode = 4422 + } + val o2 = new AnyRef { + override val hashCode = 4422 + } + t(o1, o2) + t(o2, o1) + t(o1, o1) + } @Test def testAnyRefMapCopy(): Unit = { val m1 = AnyRefMap("a" -> "b") diff --git a/test/junit/scala/collection/mutable/ArrayBufferTest.scala b/test/junit/scala/collection/mutable/ArrayBufferTest.scala index 13b5d536f9d3..1ea1d73ea438 100644 --- a/test/junit/scala/collection/mutable/ArrayBufferTest.scala +++ b/test/junit/scala/collection/mutable/ArrayBufferTest.scala @@ -392,6 +392,9 @@ class ArrayBufferTest { // check termination and correctness assertTrue(7 < ArrayBuffer.DefaultInitialSize) // condition of test + assertEquals(-1, resizeUp(7, 0)) + assertEquals(-1, resizeUp(Int.MaxValue, 0)) + assertEquals(ArrayBuffer.DefaultInitialSize, resizeUp(-1, 0)) // no check of arrayLen assertEquals(ArrayBuffer.DefaultInitialSize, resizeUp(7, 10)) assertEquals(VM_MaxArraySize, resizeUp(Int.MaxValue / 2, Int.MaxValue / 2 + 1)) // `MaxValue / 2` cannot be doubled assertEquals(VM_MaxArraySize / 2 * 2, resizeUp(VM_MaxArraySize / 2, VM_MaxArraySize / 2 + 1)) // `VM_MaxArraySize / 2` can be doubled @@ -406,12 +409,13 @@ class ArrayBufferTest { try op catch { case e: InvocationTargetException => throw e.getCause } def checkExceedsMaxInt(targetLen: Int): Unit = { assertThrows[Exception](rethrow(resizeUp(0, targetLen)), - _ == s"Overflow while resizing array of array-backed collection. Requested length: $targetLen; current length: 0; increase: $targetLen") + _ == s"Overflow while resizing array of array-backed collection. Requested length: $targetLen; current length: 0; increase: $targetLen") } def checkExceedsVMArrayLimit(targetLen: Int): Unit = assertThrows[Exception](rethrow(resizeUp(0, targetLen)), - _ == s"Array of array-backed collection exceeds VM length limit of $VM_MaxArraySize. Requested length: $targetLen; current length: 0") + _ == s"Array of array-backed collection exceeds VM length limit of $VM_MaxArraySize. Requested length: $targetLen; current length: 0") + checkExceedsMaxInt(-1) checkExceedsMaxInt(Int.MaxValue + 1: @nowarn) checkExceedsVMArrayLimit(Int.MaxValue) checkExceedsVMArrayLimit(Int.MaxValue - 1) @@ -519,4 +523,13 @@ class ArrayBufferTest { bld.addOne("hello, world") assertTrue(bld.result().contains("hello, world")) } + + @Test def `sliding throws on mutation`: Unit = { + val b = ArrayBuffer.from(1 to 10) + val it = b.sliding(size = 2, step = 1) + assertTrue(it.hasNext) + assertEquals(2, it.next().size) + b(2) = 42 + assertThrows[java.util.ConcurrentModificationException](it.hasNext) + } } diff --git a/test/junit/scala/collection/mutable/ArrayBuilderTest.scala b/test/junit/scala/collection/mutable/ArrayBuilderTest.scala index 567f3167fa8b..a472aaee13d6 100644 --- a/test/junit/scala/collection/mutable/ArrayBuilderTest.scala +++ b/test/junit/scala/collection/mutable/ArrayBuilderTest.scala @@ -1,8 +1,9 @@ package scala.collection.mutable -import org.junit.Assert.assertEquals +import org.junit.Assert.{assertEquals, assertTrue} import org.junit.Test +import scala.annotation._ import scala.runtime.PStatics.VM_MaxArraySize import scala.tools.testkit.AssertUtil.assertThrows @@ -30,6 +31,21 @@ class ArrayBuilderTest { assertThrows[Exception](ab.addAll(arr.iterator), _.endsWith("Requested length: -2147483645; current length: 2147483639; increase: 12")) // expect an exception when trying to grow larger than maximum size by addAll(array) - assertThrows[Exception](ab.addAll(arr)) + assertThrows[Exception](ab.addAll(arr), _.startsWith("Overflow while resizing")) + } + + // avoid allocating "default size" for empty, and especially avoid doubling capacity for empty + @Test def `addAll allocates elems more lazily`: Unit = { + val builder = ArrayBuilder.make[String] + (1 to 100).foreach(_ => builder.addAll(Array.empty[String])) + assertEquals(0, builder.knownSize) + } + + @Test def `t13068 addAll of array`: Unit = { + val ab: ArrayBuilder[Unit] = ArrayBuilder.make[Unit] + val arr = Array[Unit]((), (), (), (), (), (), (), (), (), (), (), ()) + ab.addAll(arr) + assertEquals(arr.length, ab.result().length) + assertTrue(ab.result().forall(_ == ())): @nowarn } } diff --git a/test/junit/scala/collection/mutable/ArrayDequeTest.scala b/test/junit/scala/collection/mutable/ArrayDequeTest.scala index 71d963cf643f..7e6176225fb8 100644 --- a/test/junit/scala/collection/mutable/ArrayDequeTest.scala +++ b/test/junit/scala/collection/mutable/ArrayDequeTest.scala @@ -1,25 +1,26 @@ package scala.collection.mutable -import scala.collection.immutable.List import org.junit.Test import org.junit.Assert._ import scala.annotation.nowarn import scala.collection.SeqFactory +import scala.collection.immutable.List +import scala.tools.nsc.`strip margin` import scala.tools.testkit.AssertUtil.assertThrows class ArrayDequeTest { @Test - def apply() = { + def apply: Unit = { val buffer = ArrayDeque.empty[Int] - val buffer2 = ArrayBuffer.empty[Int] + val standard = ArrayBuffer.empty[Int] def apply[U](f: Buffer[Int] => U) = { //println(s"Before: [buffer1=${buffer}; buffer2=${buffer2}]") - assertEquals(f(buffer), f(buffer2)) - assertEquals(buffer, buffer2) - assertEquals(buffer.reverse, buffer2.reverse) + assertEquals(f(standard), f(buffer)) + assertEquals(standard, buffer) + assertEquals(standard.reverse, buffer.reverse) } apply(_.+=(1, 2, 3, 4, 5)): @nowarn("cat=deprecation") @@ -43,15 +44,15 @@ class ArrayDequeTest { apply(_.addAll(collection.immutable.Vector.tabulate(10)(identity))) (-100 to 100) foreach {i => - assertEquals(buffer.splitAt(i), buffer2.splitAt(i)) + assertEquals(standard.splitAt(i), buffer.splitAt(i)) } for { i <- -100 to 100 j <- -100 to 100 } { - assertEquals(buffer.slice(i, j), buffer2.slice(i, j)) - if (i > 0 && j > 0) assertEquals(List.from(buffer.sliding(i, j)), List.from(buffer2.sliding(i, j))) + assertEquals(standard.slice(i, j), buffer.slice(i, j)) + if (i > 0 && j > 0) assertEquals(List.from(standard.sliding(i, j)), List.from(buffer.sliding(i, j))) } } @@ -123,32 +124,53 @@ class ArrayDequeTest { @Test def `last of empty throws NoSuchElement`: Unit = assertThrows[NoSuchElementException](ArrayDeque.empty[Int].last, _.endsWith("last of empty ArrayDeque")) + + @Test def `sliding throws on shrink`: Unit = { + val sut = ArrayDeque.from(1 to 10) + val it = sut.sliding(size = 2, step = 1) + assertTrue(it.hasNext) + assertEquals(2, it.next().size) + sut.clear() + assertThrows[java.util.ConcurrentModificationException](it.hasNext) + } + + @Test def `sliding throws on grow`: Unit = { + val sut = ArrayDeque.from(1 to 10) + val it = sut.sliding(size = 2, step = 1) + assertTrue(it.hasNext) + assertEquals(2, it.next().size) + sut.addOne(100) + assertThrows[java.util.ConcurrentModificationException](it.hasNext) + } } object ArrayDequeTest { // tests scala/bug#11047 def genericSlidingTest(factory: SeqFactory[ArrayDeque], collectionName: String): Unit = { - for { - i <- 0 to 40 - - range = 0 until i - other = factory.from(range) - - j <- 1 to 40 - k <- 1 to 40 - - iterableSliding = range.sliding(j, k).to(Seq) - otherSliding = other.sliding(j, k).to(Seq) - } + for (i <- 0 to 40; j <- 1 to 40; k <- 1 to 40) { + val range = 0 until i + val other = factory.from(range) + val iterableSliding = range.sliding(j, k).to(Seq) + val otherSliding = other.sliding(j, k).to(Seq) assert(iterableSliding == otherSliding, - s"""Iterable.from($range)).sliding($j,$k) differs from $collectionName.from($range)).sliding($j,$k) - |Iterable yielded: $iterableSliding - |$collectionName yielded: $otherSliding - """.stripMargin + sm"""Iterable.from($range)).sliding($j,$k) differs from $collectionName.from($range)).sliding($j,$k) + |Iterable yielded: $iterableSliding + |$collectionName yielded: $otherSliding + |""" ) + } // scala/bug#11440 assertEquals(0, factory.empty[Int].sliding(1).size) + + // no general mutation check + locally { + val sut = factory.from(1 to 2) + val it = sut.sliding(size = 2, step = 1) + sut(1) = 100 + assertTrue(it.hasNext) + assertEquals(1, it.size) + } } } diff --git a/test/junit/scala/collection/mutable/HashMapTest.scala b/test/junit/scala/collection/mutable/HashMapTest.scala index 7979ff6151cf..682e137cceda 100644 --- a/test/junit/scala/collection/mutable/HashMapTest.scala +++ b/test/junit/scala/collection/mutable/HashMapTest.scala @@ -194,7 +194,7 @@ class HashMapTest { val hashMapCollide2 = mutable.HashMap(0 -> "a", (null: Any) -> "b", "" -> "c") assertEquals(hashMapCollide2.updateWith((null: Any))(noneAnytime), None) - assertEquals(hashMapCollide2, mutable.HashMap(0 -> "a", "" -> "c")) + assertEquals(hashMapCollide2, mutable.HashMap[Any, String](0 -> "a", "" -> "c")) val hashMapCollide3 = mutable.HashMap(0 -> "a", (null: Any) -> "b", "" -> "c") assertEquals(hashMapCollide3.updateWith("")(noneAnytime), None) diff --git a/test/junit/scala/collection/mutable/LinkedHashMapTest.scala b/test/junit/scala/collection/mutable/LinkedHashMapTest.scala index 6467bd299459..09a47b572575 100644 --- a/test/junit/scala/collection/mutable/LinkedHashMapTest.scala +++ b/test/junit/scala/collection/mutable/LinkedHashMapTest.scala @@ -108,7 +108,7 @@ class LinkedHashMapTest { val hashMapCollide2 = mutable.LinkedHashMap(0 -> "a", (null: Any) -> "b", "" -> "c") assertEquals(hashMapCollide2.updateWith((null: Any))(noneAnytime), None) - assertEquals(hashMapCollide2, mutable.LinkedHashMap(0 -> "a", "" -> "c")) + assertEquals(hashMapCollide2, mutable.LinkedHashMap[Any, String](0 -> "a", "" -> "c")) val hashMapCollide3 = mutable.LinkedHashMap(0 -> "a", (null: Any) -> "b", "" -> "c") assertEquals(hashMapCollide3.updateWith("")(noneAnytime), None) diff --git a/test/junit/scala/collection/mutable/ListBufferTest.scala b/test/junit/scala/collection/mutable/ListBufferTest.scala index c5f434986d9f..6322ab14ff04 100644 --- a/test/junit/scala/collection/mutable/ListBufferTest.scala +++ b/test/junit/scala/collection/mutable/ListBufferTest.scala @@ -338,4 +338,13 @@ class ListBufferTest { assertEquals(3, b.last) assertEquals(List(1, 2, 3), b.toList) } + + @Test def `sliding throws on mutation`: Unit = { + val b = ListBuffer.from(1 to 10) + val it = b.sliding(size = 2, step = 1) + assertTrue(it.hasNext) + assertEquals(2, it.next().size) + b(2) = 42 + assertThrows[java.util.ConcurrentModificationException](it.hasNext) + } } diff --git a/test/junit/scala/collection/mutable/LongMapTest.scala b/test/junit/scala/collection/mutable/LongMapTest.scala new file mode 100644 index 000000000000..d31b0a5d652a --- /dev/null +++ b/test/junit/scala/collection/mutable/LongMapTest.scala @@ -0,0 +1,33 @@ +package scala.collection +package mutable + +import org.junit.Assert._ +import org.junit.Test + +import scala.tools.testkit.ReflectUtil.getMethodAccessible + +class LongMapTest { + @Test def t13048(): Unit = { + def t(x: Int, y: Int): Unit = { + val m = LongMap.empty[Unit] + m.getOrElseUpdate(x, m.getOrElseUpdate(y, ())) + assert(m.keys.toSet == immutable.Set(x, y), m.keys.toSet) + } + t(4, 28) + t(28, 4) + t(4, 4) + } + + @Test + def `repack calculation must complete`: Unit = { + val vacant: Int = 10256777 + val mask: Int = 1073741823 + val size: Int = 603979777 + //LongMap.repackMask + val name = "scala$collection$mutable$LongMap$$repackMask" + val sut = getMethodAccessible[LongMap.type](name) + val res = sut.invoke(LongMap, mask, size, vacant) + assertEquals(1073741823, res) + } + +} diff --git a/test/junit/scala/collection/mutable/SerializationTest.scala b/test/junit/scala/collection/mutable/SerializationTest.scala index ef894df33569..30f9168d63f1 100644 --- a/test/junit/scala/collection/mutable/SerializationTest.scala +++ b/test/junit/scala/collection/mutable/SerializationTest.scala @@ -7,6 +7,7 @@ import org.junit.runners.JUnit4 import scala.collection.mutable @RunWith(classOf[JUnit4]) +@annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") class SerializationTest { @Test diff --git a/test/junit/scala/concurrent/FutureTest.scala b/test/junit/scala/concurrent/FutureTest.scala index a331e504911d..81a6878e1600 100644 --- a/test/junit/scala/concurrent/FutureTest.scala +++ b/test/junit/scala/concurrent/FutureTest.scala @@ -7,6 +7,9 @@ import org.junit.Test import scala.tools.testkit.AssertUtil._ import scala.util.{Success, Try} import duration.Duration.Inf +import scala.collection.mutable.ListBuffer +import scala.concurrent.impl.Promise.DefaultPromise +import scala.util.chaining._ class FutureTest { @Test @@ -112,4 +115,87 @@ class FutureTest { assertTrue(f.isCompleted) assertEquals(Some(Success(1)), f.value) } + + @Test def t13058(): Unit = { + implicit val directExecutionContext: ExecutionContext = ExecutionContext.fromExecutor(_.run()) + val Noop = impl.Promise.getClass.getDeclaredFields.find(_.getName.contains("Noop")).get.tap(_.setAccessible(true)).get(impl.Promise) + + def numTransforms(p: Promise[_]) = { + def count(cs: impl.Promise.Callbacks[_]): Int = cs match { + case Noop => 0 + case m: impl.Promise.ManyCallbacks[_] => 1 + count(m.rest) + case _ => 1 + } + val cs = p.asInstanceOf[DefaultPromise[_]].get().asInstanceOf[impl.Promise.Callbacks[_]] + count(cs) + } + + locally { + val p1 = Promise[Int]() + val p2 = Promise[Int]() + val p3 = Promise[Int]() + + p3.future.onComplete(_ => ()) + p3.future.onComplete(_ => ()) + + assert(p2.asInstanceOf[DefaultPromise[_]].get() eq Noop) + assert(numTransforms(p3) == 2) + val ops3 = p3.asInstanceOf[DefaultPromise[_]].get() + + val first = Future.firstCompletedOf(List(p1.future, p2.future, p3.future)) + + assert(numTransforms(p1) == 1) + assert(numTransforms(p2) == 1) + assert(numTransforms(p3) == 3) + + val succ = Success(42) + p1.complete(succ) + assert(Await.result(first, Inf) == 42) + + assert(p1.asInstanceOf[DefaultPromise[_]].get() eq succ) + assert(p2.asInstanceOf[DefaultPromise[_]].get() eq Noop) + assert(p3.asInstanceOf[DefaultPromise[_]].get() eq ops3) + + assert(numTransforms(p2) == 0) + assert(numTransforms(p3) == 2) + } + + locally { + val b = ListBuffer.empty[String] + var p = Promise[Int]().asInstanceOf[DefaultPromise[Int]] + assert(p.get() eq Noop) + val a1 = p.onCompleteWithUnregister(_ => ()) + a1() + assert(p.get() eq Noop) + + val a2 = p.onCompleteWithUnregister(_ => b += "a2") + p.onCompleteWithUnregister(_ => b += "b2") + a2() + assert(numTransforms(p) == 1) + p.complete(Success(41)) + assert(b.mkString == "b2") + + p = Promise[Int]().asInstanceOf[DefaultPromise[Int]] + b.clear() + p.onCompleteWithUnregister(_ => b += "a3") + val b3 = p.onCompleteWithUnregister(_ => b += "b3") + p.onCompleteWithUnregister(_ => b += "c3") + b3() + assert(numTransforms(p) == 2) + p.complete(Success(41)) + assert(b.mkString == "a3c3") + + + p = Promise[Int]().asInstanceOf[DefaultPromise[Int]] + b.clear() + p.onCompleteWithUnregister(_ => b += "a4") + p.onCompleteWithUnregister(_ => b += "b4") + val c4 = p.onCompleteWithUnregister(_ => b += "c4") + c4() + assert(numTransforms(p) == 2) + p.complete(Success(41)) + println(b.mkString) + assert(b.mkString == "b4a4") + } + } } diff --git a/test/junit/scala/jdk/StepperTest.scala b/test/junit/scala/jdk/StepperTest.scala index 942bc1161e34..a21b4a6b3daa 100644 --- a/test/junit/scala/jdk/StepperTest.scala +++ b/test/junit/scala/jdk/StepperTest.scala @@ -260,6 +260,7 @@ class StepperTest { } @Test + @annotation.nowarn("cat=deprecation&origin=scala.collection.mutable.AnyRefMap") def anyRefMapSteppers(): Unit = for (size <- sizes) { val l = List.fill(size)(r.nextInt().toString -> r.nextInt()).distinctBy(_._1) diff --git a/test/junit/scala/lang/stringinterpol/StringContextTest.scala b/test/junit/scala/lang/stringinterpol/StringContextTest.scala index 77bd1cc68e61..f2db2e7b0918 100644 --- a/test/junit/scala/lang/stringinterpol/StringContextTest.scala +++ b/test/junit/scala/lang/stringinterpol/StringContextTest.scala @@ -114,13 +114,9 @@ class StringContextTest { @Test def `f interpolator baseline`(): Unit = { - // ignore spurious warning scala/bug#11946 - type ignore = annotation.unused - @ignore def ignore: ignore = ??? // ignore that ignore looks unused - - @ignore implicit def stringToBoolean(s: String): Boolean = java.lang.Boolean.parseBoolean(s) - @ignore implicit def stringToChar(s: String): Char = s(0) - @ignore implicit def str2fmt(s: String): java.util.Formattable = new java.util.Formattable { + implicit def stringToBoolean(s: String): Boolean = java.lang.Boolean.parseBoolean(s) + implicit def stringToChar(s: String): Char = s(0) + implicit def str2fmt(s: String): java.util.Formattable = new java.util.Formattable { def formatTo(f: java.util.Formatter, g: Int, w: Int, p: Int) = f.format("%s", s) } @@ -140,7 +136,7 @@ class StringContextTest { import java.util.{Calendar, Locale} val c = Calendar.getInstance(Locale.US) c.set(2012, Calendar.MAY, 26) - @ignore implicit def strToDate(x: String): Calendar = c + implicit def strToDate(x: String): Calendar = c val ss = List[(String, String)] ( // 'b' / 'B' (category: general) @@ -225,8 +221,8 @@ class StringContextTest { f"Just want to say ${"hello, world"}%#s..." -> "Just want to say hello, world...", - { @ignore implicit val strToShort = (s: String) => java.lang.Short.parseShort(s) ; f"${"120"}%d" } -> "120", - { @ignore implicit val strToInt = (s: String) => 42 ; f"${"120"}%d" } -> "42", + { implicit val strToShort = (s: String) => java.lang.Short.parseShort(s) ; f"${"120"}%d" } -> "120", + { implicit val strToInt = (s: String) => 42 ; f"${"120"}%d" } -> "42", // 'e' | 'E' | 'g' | 'G' | 'f' | 'a' | 'A' (category: floating point) // ------------------------------------------------------------------ diff --git a/test/junit/scala/lang/traits/BytecodeTest.scala b/test/junit/scala/lang/traits/BytecodeTest.scala index 213e61f2a442..25635859e8e0 100644 --- a/test/junit/scala/lang/traits/BytecodeTest.scala +++ b/test/junit/scala/lang/traits/BytecodeTest.scala @@ -277,6 +277,22 @@ class BytecodeTest extends BytecodeTesting { assert(cls.isEmpty, cls.map(_.name)) } + @Test + def sd143a(): Unit = { + val code = + """trait A { def m = 1 } + |class B extends A { override def m = 2 } + |trait T extends A + |class C extends B with T { + | override def m = super[T].m + |} + """.stripMargin + + val List(a, b, c, t) = compileClasses(code) + val ins = getInstructions(c, "m") + assert(ins contains Invoke(INVOKESTATIC, "A", "m$", "(LA;)I", itf = true), ins.stringLines) + } + @Test def sd143b(): Unit = { val jCode = List("interface A { default int m() { return 1; } }" -> "A.java") diff --git a/test/junit/scala/math/BigIntTest.scala b/test/junit/scala/math/BigIntTest.scala index 10e2eb880466..56d12f975336 100644 --- a/test/junit/scala/math/BigIntTest.scala +++ b/test/junit/scala/math/BigIntTest.scala @@ -1,14 +1,17 @@ package scala.math +import java.util.concurrent.atomic.AtomicLong import org.junit.Test import org.junit.Assert.{assertFalse, assertNull, assertTrue} import scala.tools.testkit.AssertUtil.assertThrows class BigIntTest { - private val bigint = BigInt(42) + private val counter = new AtomicLong(Int.MaxValue) + private def bigint = BigInt(counter.getAndIncrement) + private def even = BigInt(42) - @Test def testIsComparable: Unit = assertTrue(BigInt(42).isInstanceOf[java.lang.Comparable[_]]) + @Test def testIsComparable: Unit = assertTrue(bigint.isInstanceOf[java.lang.Comparable[_]]) @Test def `mod respects BigInteger`: Unit = assertThrows[ArithmeticException](bigint mod BigInt(-3), _.contains("modulus not positive")) @@ -32,7 +35,7 @@ class BigIntTest { @Test def `testBit respects BigInteger`: Unit = assertThrows[ArithmeticException](bigint.testBit(-3), _.contains("Negative bit address")) - @Test def `testBit 0`: Unit = assertFalse(bigint.testBit(0)) + @Test def `testBit 0`: Unit = assertFalse(even.testBit(0)) @Test def `BitInteger to BitInt respects null`: Unit = assertNull(null.asInstanceOf[java.math.BigInteger]: BigInt) } diff --git a/test/junit/scala/reflect/internal/PositionsTest.scala b/test/junit/scala/reflect/internal/PositionsTest.scala index 41f53901abea..94113d1f0e5a 100644 --- a/test/junit/scala/reflect/internal/PositionsTest.scala +++ b/test/junit/scala/reflect/internal/PositionsTest.scala @@ -3,56 +3,72 @@ package scala.reflect.internal import org.junit.Test import org.junit.Assert.assertFalse -import scala.reflect.internal.util.NoSourceFile +import scala.reflect.internal.util.{NoSourceFile, Position} import scala.tools.nsc.reporters.StoreReporter import scala.tools.nsc.symtab.SymbolTableForUnitTesting import scala.tools.testkit.AssertUtil.assertThrows class PositionsTest { - private object symbolTable extends SymbolTableForUnitTesting { + object symbolTable extends SymbolTableForUnitTesting { override def useOffsetPositions: Boolean = false override val reporter = new StoreReporter(settings) } + import symbolTable._ - @Test def positionValidation(): Unit = { - import symbolTable._ - def checkInvalid(tree: Tree): Unit = { - reporter.reset() - assertThrows[ValidateException](validatePositions(tree)) - } - - def checkValid(tree: Tree): Unit = { - reporter.reset() - validatePositions(tree) - assertFalse(reporter.hasErrors) - } - def rangePos(start: Int, end: Int): util.Position = util.Position.range(NoSourceFile, start, start, end) - def offsetPos(point: Int): util.Position = util.Position.offset(NoSourceFile, point) - def tree: Tree = Ident(TermName("x")) - def rangePositioned(start: Int, end: Int): Tree = { - Ident(TermName("x")).setPos(rangePos(start, end)) - } + def sentinel = Literal(Constant(())).setPos(offsetPos(100)) + + def checkInvalid(tree: Tree): Unit = { + reporter.reset() + assertThrows[ValidateException](validatePositions(tree)) + } + + def checkValid(tree: Tree): Unit = { + reporter.reset() + try validatePositions(tree) + finally reporter.infos.foreach(println) + assertFalse(reporter.hasErrors) + } + + def checkInvalid(pos: Position)(trees: Tree*): Unit = + if (trees.length == 1) checkInvalid(Block(stats = Nil, expr = trees.head).setPos(pos)) + else checkInvalid(Block(stats = trees.toList, expr = sentinel).setPos(pos)) + + def checkValid(pos: Position)(trees: Tree*): Unit = + if (trees.length == 1) checkValid(Block(stats = Nil, expr = trees.head).setPos(pos)) + else checkValid(Block(stats = trees.toList, expr = sentinel).setPos(pos)) + + def rangePos(start: Int, end: Int): Position = Position.range(NoSourceFile, start, start, end) + def offsetPos(point: Int): Position = Position.offset(NoSourceFile, point) + def x: Tree = Ident(TermName("x")) + def rangePositioned(start: Int, end: Int): Tree = x.setPos(rangePos(start, end)) + + //@Test + def positionValidation: Unit = { // overlapping ranges - checkInvalid(Block(rangePositioned(0, 2), rangePositioned(1, 2), EmptyTree).setPos(rangePos(0, 2))) - checkInvalid(Block(rangePositioned(1, 2), rangePositioned(0, 2), EmptyTree).setPos(rangePos(0, 2))) + checkInvalid(rangePos(0, 2))(rangePositioned(0, 2), rangePositioned(1, 2)) + checkInvalid(rangePos(0, 2))(rangePositioned(1, 2), rangePositioned(0, 2)) // transparent position not deemed to overlap itself - checkValid(Block(rangePositioned(0, 2), tree.setPos(rangePos(1, 2).makeTransparent), EmptyTree).setPos(rangePos(0, 2))) + checkValid(rangePos(0, 2))(rangePositioned(0, 2), x.setPos(rangePos(1, 2).makeTransparent)) // children of transparent position overlapping with sibling of transparent position. - checkInvalid(Block(rangePositioned(0, 2), Block(Nil, rangePositioned(1, 2)).setPos(rangePos(1, 2).makeTransparent), EmptyTree).setPos(rangePos(0, 2))) + checkInvalid(rangePos(0, 2))(rangePositioned(0, 2), Block(Nil, rangePositioned(1, 2)).setPos(rangePos(1, 2).makeTransparent)) // adjacent ranges are allowed to touch - checkValid(Block(rangePositioned(0, 1), rangePositioned(1, 2), EmptyTree).setPos(rangePos(0, 2))) + checkValid(rangePos(0, 2))(rangePositioned(0, 1), rangePositioned(1, 2)) // offset position between overlapping ranges - checkInvalid(Block(rangePositioned(0, 2), tree.setPos(offsetPos(0)), rangePositioned(1, 2), EmptyTree).setPos(rangePos(0, 2))) + checkInvalid(rangePos(0, 2))(rangePositioned(0, 2), x.setPos(offsetPos(0)), rangePositioned(1, 2)) // child range position larger than parent - checkInvalid(Block(Nil, rangePositioned(0, 3)).setPos(rangePos(0, 2))) + checkInvalid(rangePos(0, 2))(rangePositioned(0, 3)) // child offset position outside of parent - checkInvalid(Block(Nil, tree.setPos(offsetPos(3)).setPos(rangePos(0, 2)))) + checkInvalid(rangePos(0, 2))(x.setPos(offsetPos(3))) + } + + @Test def `focused position is synthetic`: Unit = checkValid(rangePos(27, 42)) { + x.setPos(offsetPos(3)) } } diff --git a/test/junit/scala/reflect/internal/PrintersTest.scala b/test/junit/scala/reflect/internal/PrintersTest.scala index 9d2597aae740..57f4d5c83902 100644 --- a/test/junit/scala/reflect/internal/PrintersTest.scala +++ b/test/junit/scala/reflect/internal/PrintersTest.scala @@ -79,6 +79,8 @@ class BasePrintTest { @Test def testConstantLong(): Unit = assertTreeCode(Literal(Constant(42L)))("42L") + @Test def testConstantNull(): Unit = assertTreeCode(Literal(Constant(null)))("null") + val sq = "\"" val tq = "\"" * 3 val teq = "\"\"\\\"" @@ -89,6 +91,9 @@ class BasePrintTest { @Test def testConstantControl(): Unit = assertTreeCode(Literal(Constant("hello\u0003world")))(s"${sq}hello\\u0003world${sq}") + // ISOControl is 0-1F, 7F-9F + @Test def testConstantABControl(): Unit = assertTreeCode(Literal(Constant("hello\u009fworld")))(s"${sq}hello\\u009Fworld${sq}") + @Test def testConstantFormfeedChar(): Unit = assertTreeCode(Literal(Constant('\f')))("'\\f'") @Test def testConstantControlChar(): Unit = assertTreeCode(Literal(Constant(3.toChar)))("'\\u0003'") diff --git a/test/junit/scala/reflect/macros/AttachmentsTest.scala b/test/junit/scala/reflect/macros/AttachmentsTest.scala index 020007ea874d..a46e246be7d1 100644 --- a/test/junit/scala/reflect/macros/AttachmentsTest.scala +++ b/test/junit/scala/reflect/macros/AttachmentsTest.scala @@ -1,5 +1,6 @@ package scala.reflect.macros +import org.junit.Assert._ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 @@ -30,8 +31,8 @@ class AttachmentsTest { object theBar extends Bar atts = atts.update(theBar) - assert(!atts.isEmpty) - assert(atts.all == Set(Foo(0), theBar)) + assertFalse(atts.isEmpty) + assertEquals(Set[Any](Foo(0), theBar), atts.all) assert(atts.get[Foo] == Some(Foo(0))) assert(atts.get[Bar] == Some(theBar)) assert(atts.get[theBar.type] == Some(theBar)) diff --git a/test/junit/scala/runtime/ScalaRunTimeTest.scala b/test/junit/scala/runtime/ScalaRunTimeTest.scala index eb148c16c7ca..64e44936f6a4 100644 --- a/test/junit/scala/runtime/ScalaRunTimeTest.scala +++ b/test/junit/scala/runtime/ScalaRunTimeTest.scala @@ -25,7 +25,7 @@ class ScalaRunTimeTest { assertEquals("""Array(1, 2, 3)""", stringOf(Array(1, 2, 3))) assertEquals("""Array(a, "", " c", null)""", stringOf(Array("a", "", " c", null))) assertEquals("""Array(Array("", 1, Array(5)), Array(1))""", - stringOf(Array(Array("", 1, Array(5)), Array(1)))) + stringOf(Array[Any](Array[Any]("", 1, Array(5)), Array(1)))) val map = Map(1->"", 2->"a", 3->" a", 4->null) assertEquals(s"""Map(1 -> "", 2 -> a, 3 -> " a", 4 -> null)""", stringOf(map)) diff --git a/test/junit/scala/sys/process/ProcessTest.scala b/test/junit/scala/sys/process/ProcessTest.scala index 8b23449f95b8..75febac7f99e 100644 --- a/test/junit/scala/sys/process/ProcessTest.scala +++ b/test/junit/scala/sys/process/ProcessTest.scala @@ -13,7 +13,6 @@ import scala.sys.process._ // test from outside the package to ensure implicits import scala.tools.testkit.AssertUtil._ import scala.tools.testkit.ReleasablePath._ import scala.util.Try -import scala.util.Properties._ import scala.util.Using import scala.util.chaining._ @@ -21,7 +20,6 @@ import org.junit.Test import org.junit.Assert._ class ProcessTest { - private def testily(body: => Unit) = if (!isWin) body private def withIn[A](in: InputStream)(body: => A): A = { val saved = System.in @@ -34,7 +32,7 @@ class ProcessTest { // until after the latch, which is after the innocuous process exited, // and then attempt to close the process.getOutputStream, which is known // to be closed already (because that is how process exit was detected). - @Test def t7963(): Unit = testily { + @Test def t7963(): Unit = noWin() { var exception: Exception = null val latch: CountDownLatch = new CountDownLatch(1) val inputStream = new ByteArrayInputStream("a".getBytes) { @@ -54,12 +52,12 @@ class ProcessTest { assertNull(exception) } - @Test def t10007(): Unit = testily { + @Test def t10007(): Unit = noWin() { val res = ("cat" #< new ByteArrayInputStream("lol".getBytes)).!! assertEquals("lol\n", res) } // test non-hanging - @Test def t10055(): Unit = testily { + @Test def t10055(): Unit = noWin() { val res = ("cat" #< ( () => -1 ) ).! assertEquals(0, res) } @@ -69,13 +67,13 @@ class ProcessTest { (foo, bar) => assertEquals(0, Process.cat(Seq(foo, bar)).!) } - @Test def processApply(): Unit = testily { + @Test def processApply(): Unit = noWin() { Using.resources(File.createTempFile("foo", "tmp"), File.createTempFile("bar", "tmp")) { (foo, bar) => assertEquals(0, Process("cat", Seq(foo, bar).map(_.getAbsolutePath)).!) } } - @Test def t10696(): Unit = testily { + @Test def t10696(): Unit = noWin() { val res1 = Process("false").lazyLines assertEquals("LazyList()", res1.toString()) val ex = Try(res1.head).failed.get @@ -88,7 +86,7 @@ class ProcessTest { private def createFile(prefix: String) = createTempFile(prefix, "tmp").tap(f => Files.write(f, List(prefix).asJava, UTF_8)) - @Test def t10823(): Unit = testily { + @Test def t10823(): Unit = noWin() { Using.resources(createFile("hello"), createFile("world"), createTempFile("out", "tmp")) { (file1, file2, out) => val cat = Process.cat(List(file1, file2).map(_.toFile)) val p = cat #> out.toFile @@ -99,7 +97,7 @@ class ProcessTest { } // a test for A && B where A fails and B is not started - @Test def t10823_short_circuit(): Unit = testily { + @Test def t10823_short_circuit(): Unit = noWin() { val noFile = Paths.get("total", "junk") val p2 = new ProcessMock(error = false) diff --git a/test/junit/scala/tools/nsc/PhaseAssemblyTest.scala b/test/junit/scala/tools/nsc/PhaseAssemblyTest.scala index e91a02e9a73d..180097f3ede2 100644 --- a/test/junit/scala/tools/nsc/PhaseAssemblyTest.scala +++ b/test/junit/scala/tools/nsc/PhaseAssemblyTest.scala @@ -15,27 +15,210 @@ package scala.tools.nsc import org.junit.Assert.assertEquals import org.junit.Test +import scala.reflect.internal.FatalError +import scala.tools.testkit.AssertUtil.assertThrows + class PhaseAssemblyTest { - @Test - def multipleRunsRightAfter(): Unit = { - val global = new Global(new Settings) - case class component[G <: Global with Singleton](global: G, phaseName: String, override val runsRightAfter: Option[String], override val runsAfter: List[String], override val runsBefore: List[String]) extends SubComponent { - override def newPhase(prev: Phase): Phase = ??? - } - val N = 16 + case class component[G <: Global with Singleton]( + global: G, + phaseName: String, + override val runsRightAfter: Option[String], + override val runsAfter: List[String], + override val runsBefore: List[String] = List("terminal"), + ) extends SubComponent { + override val initial: Boolean = phaseName == "parser" + override val terminal: Boolean = phaseName == "terminal" + override def newPhase(prev: Phase): Phase = ??? + } + def parserAndTerminal[G <: Global with Singleton](global: G) = List( + component(global, "parser", None, Nil, Nil), + component(global,"terminal", None, Nil, Nil), + ) + case class Komponent(phaseName: String, runsRightAfter: String = null, runsAfter: String = "", runsBefore: String = "") + def komponents[G <: Global with Singleton](global: G)(ks: Komponent*): List[component[global.type]] = + ks.iterator.map(k => component(global, k.phaseName, Option(k.runsRightAfter), List(k.runsAfter).filter(_.nonEmpty), List(k.runsBefore).filter(_.nonEmpty))).toList + + @Test def multipleRunsRightAfter: Unit = { + val settings = new Settings + //settings.verbose.tryToSet(Nil) + val global = new Global(settings) + val N = 64 * 4096 // 262'144 ~ 1.6sec val random = new scala.util.Random(123502L) - val names = Array.fill(N)("phase_" + random.nextInt(1024)) - val parserAndTerminal = List( - component(global, "parser", None, Nil, Nil), - component(global,"terminal", None, Nil, List(N.toString)) + val names = Array.tabulate(N)(n => s"phase_${n+1}_${random.nextInt(1024)}") + val beforeTerminal = List("terminal") + val components = names.foldLeft(parserAndTerminal(global)) { (comps, nm) => + component(global, nm, runsRightAfter = comps.headOption.map(_.phaseName), runsAfter = Nil, runsBefore = beforeTerminal) :: comps + } + val inputs = random.shuffle(components) + val graph = DependencyGraph(inputs) + val phases: List[SubComponent] = graph.compilerPhaseList() + val result: List[String] = phases.map(_.phaseName).filter(_.startsWith("phase_")) + assertEquals("parser", phases.head.phaseName) + assertEquals("terminal", phases.last.phaseName) + assertEquals(names.toList, result) + } + @Test def trivial: Unit = { + val settings = new Settings + val global = new Global(settings) + val beforeTerminal = List("terminal") + val names = Array("phooey", "kerfuffle") + val components = names.foldLeft(parserAndTerminal(global)) { (comps, nm) => + component(global, nm, runsRightAfter = None, runsAfter = comps.headOption.map(_.phaseName).toList, runsBefore = beforeTerminal) :: comps + } + val inputs = components + val graph = DependencyGraph(inputs) + val result: List[SubComponent] = graph.compilerPhaseList() + assertEquals("parser", result.head.phaseName) + assertEquals("terminal", result.last.phaseName) + assertEquals(names.toList, result.init.tail.map(_.phaseName)) + } + @Test def `trivial conflict`: Unit = { + val settings = new Settings + val global = new Global(settings) + val beforeTerminal = List("terminal") + val names = Array("phooey", "kerfuffle", "konflikt") + def rra(nm: String) = nm match { case "kerfuffle"|"konflikt" => Some("phooey") case _ => None } + def ra(comps: List[component[global.type]], nm: String) = nm match { case "kerfuffle"|"konflikt" => Nil case _ => comps.headOption.map(_.phaseName).toList } + val components = names.foldLeft(parserAndTerminal(global)) { (comps, nm) => + component(global, nm, rra(nm), ra(comps, nm), runsBefore = beforeTerminal) :: comps + } + assertThrows[FatalError](DependencyGraph(components), _ == "Phases kerfuffle and konflikt both immediately follow phooey") + } + @Test def `trivial cycle`: Unit = { + val settings = new Settings + val global = new Global(settings) + val beforeTerminal = List("terminal") + val names = Array("phooey", "kerfuffle", "konflikt") + def rra(nm: String) = None + def ra(comps: List[component[global.type]], nm: String) = nm match { + case "phooey" => List("parser", "konflikt") + case "konflikt" => List("kerfuffle") + case "kerfuffle" => List("phooey") + case _ => comps.headOption.map(_.phaseName).toList + } + val components = names.foldLeft(parserAndTerminal(global)) { (comps, nm) => + component(global, nm, rra(nm), ra(comps, nm), runsBefore = beforeTerminal) :: comps + } + assertThrows[FatalError](DependencyGraph(components), _ == "Phases form a cycle: phooey -> kerfuffle -> konflikt -> phooey") + } + @Test def `run before tightly bound phases`: Unit = { + val settings = new Settings + val global = new Global(settings) + val components = + component(global, "phooey", None, List("parser"), List("terminal")) :: + component(global, "kerfuffle", None, List("phooey"), List("erasure")) :: + component(global, "konflikt", None, List("phooey"), List("terminal")) :: + component(global, "erasure", Some("konflikt"), Nil, List("terminal")) :: + component(global, "posterasure", Some("erasure"), Nil, List("terminal")) :: + parserAndTerminal(global) + val graph = DependencyGraph(components) + val result: List[SubComponent] = graph.compilerPhaseList() + assertEquals(List("parser", "phooey", "kerfuffle", "konflikt", "erasure", "posterasure", "terminal"), result.map(_.phaseName)) + } + + @Test def `strict chains`: Unit = { + val settings = new Settings + val global = new Global(settings) + val components = + component(global, "p1", None, List("parser")) :: + component(global, "p2", Some("p1"), Nil) :: + component(global, "p3", Some("p2"), Nil) :: + component(global, "u1", None, List("parser")) :: + component(global, "u2", Some("u1"), Nil) :: + component(global, "u3", Some("u2"), Nil) :: + parserAndTerminal(global) + val graph = DependencyGraph(components) + val result: List[SubComponent] = graph.compilerPhaseList() + assertEquals(List("parser", "p1", "p2", "p3", "u1", "u2", "u3", "terminal"), result.map(_.phaseName)) + } + //phaseList: List(parser, namer, packageobjects, typer, superaccessors, extmethods, + //pickler, xsbt-api, xsbt-dependency, refchecks, patmat, uncurry, fields, tailcalls, + //specialize, explicitouter, erasure, posterasure, lambdalift, constructors, flatten, + //mixin, cleanup, delambdafy, jvm, xsbt-analyzer, terminal) + // phasesSet is a hash set, so order of inputs should not matter. + // this test was to debug ths initial CI failure, a bug in handling runsRightAfter. + @Test def `constraints under sbt`: Unit = { + val settings = new Settings + val global = new Global(settings) + val components = komponents(global)( + Komponent("parser"), + Komponent("namer", runsAfter = "parser"), + Komponent("packageobjects", runsRightAfter = "namer"), + Komponent("typer", runsRightAfter = "packageobjects"), + Komponent("superaccessors", runsAfter = "typer"), + Komponent("extmethods", runsAfter = "superaccessors"), + Komponent("pickler", runsAfter = "extmethods"), + Komponent("refchecks", runsAfter = "pickler"), + Komponent("patmat", runsAfter = "refchecks"), + Komponent("uncurry", runsAfter = "patmat"), + Komponent("fields", runsAfter = "uncurry"), + Komponent("tailcalls", runsAfter = "fields"), + Komponent("specialize", runsAfter = "tailcalls"), + Komponent("explicitouter", runsAfter = "specialize"), + Komponent("erasure", runsAfter = "explicitouter"), + Komponent("posterasure", runsRightAfter = "erasure"), + Komponent("async", runsAfter = "posterasure"), + Komponent("lambdalift", runsAfter = "async"), + Komponent("constructors", runsAfter = "lambdalift"), + Komponent("flatten", runsAfter = "constructors"), + Komponent("mixin", runsAfter = "flatten"), + Komponent("cleanup", runsAfter = "mixin"), + Komponent("delambdafy", runsAfter = "cleanup"), + Komponent("jvm", runsAfter = "delambdafy"), + Komponent("terminal", runsAfter = "jvm"), + Komponent("xsbt-api", runsRightAfter = "pickler", runsAfter = "typer", runsBefore = "erasure"), + Komponent("xsbt-dependency", runsRightAfter = "xsbt-api", runsBefore = "refchecks"), + Komponent("xsbt-analyzer", runsAfter = "jvm", runsBefore = "terminal"), ) - val components = List.tabulate(N)(i => component(global, names(i), Some(if (i == 0) "parser" else names(i - 1)), Nil, List("terminal"))) ::: parserAndTerminal + val graph = DependencyGraph(components) + val result: List[SubComponent] = graph.compilerPhaseList() + assertEquals(List( + "parser", + "namer", + "packageobjects", + "typer", + "superaccessors", + "extmethods", + "pickler", + "xsbt-api", + "xsbt-dependency", + "refchecks", + "patmat", + "uncurry", + "fields", + "tailcalls", + "specialize", + "explicitouter", + "erasure", + "posterasure", + "async", + "lambdalift", + "constructors", + "flatten", + "mixin", + "cleanup", + "delambdafy", + "jvm", + "xsbt-analyzer", + "terminal", + ), + result.map(_.phaseName)) + } +} - val graph = global.phasesSetToDepGraph(components.reverse) - graph.removeDanglingNodes() - graph.validateAndEnforceHardlinks() - graph.collapseHardLinksAndLevels(graph.getNodeByPhase("parser"), 1) - val result: List[String] = graph.compilerPhaseList().map(_.phaseName).filter(_.startsWith("phase_")) - assertEquals(names.toList, result) +class SubComponentTest { + @Test def `SubComponent has consistent hashCode and equals`: Unit = { + var counter = 0 + def next() = { counter += 1; counter } + case class MyComponent(id: Int) extends SubComponent { + val global: scala.tools.nsc.Global = null + def newPhase(prev: scala.tools.nsc.Phase): scala.tools.nsc.Phase = ??? + val phaseName: String = s"c${next()}" + val runsAfter: List[String] = Nil + val runsRightAfter: Option[String] = None + } + val c0 = MyComponent(0) // inadvertently equal + val c1 = MyComponent(0) + assert(c0 != c1 || c0.hashCode == c1.hashCode) } } diff --git a/test/junit/scala/tools/nsc/QuickfixTest.scala b/test/junit/scala/tools/nsc/QuickfixTest.scala index e25164226d88..48e189f3f9da 100644 --- a/test/junit/scala/tools/nsc/QuickfixTest.scala +++ b/test/junit/scala/tools/nsc/QuickfixTest.scala @@ -4,32 +4,40 @@ import org.junit.Assert._ import org.junit.Test import java.nio.file.Files +import scala.jdk.CollectionConverters._ import scala.reflect.internal.util.BatchSourceFile import scala.reflect.io.AbstractFile import scala.tools.nsc.reporters.StoreReporter +import scala.tools.testkit.AssertUtil._ import scala.tools.testkit.BytecodeTesting import scala.tools.testkit.ReleasablePath._ import scala.util.Using +import scala.util.chaining._ class QuickfixTest extends BytecodeTesting { - def testQuickfixs(as: List[String], b: String, args: String, checkInfo: StoreReporter.Info => Boolean = _ => true): Unit = - if (!scala.util.Properties.isWin) { + private val allGood: StoreReporter.Info => Boolean = _ => true + + // expected result b is lines (of resulting files) with NL termination (i.e., trailing empty line) + def testQuickfixes(as: List[String], b: String, args: String, checkInfo: StoreReporter.Info => Boolean = allGood): Unit = + noWin() { Using.resource(Files.createTempDirectory("quickfixTest")) { tmpDir => - val srcs = as.indices.map(i => tmpDir.resolve(s"unitSource$i.scala")).toList - as.lazyZip(srcs).foreach { case (a, src) => Files.write(src, a.getBytes) } + val srcs = as.zipWithIndex.map { + case (a, i) => tmpDir.resolve(s"unitSource$i.scala").tap(Files.write(_, a.getBytes)) + } val c = BytecodeTesting.newCompiler(extraArgs = args) val r = c.newRun() val fs = srcs.map(src => AbstractFile.getFile(src.toFile.getAbsolutePath)) r.compileSources(fs.map(new BatchSourceFile(_))) - assertEquals(b.replaceAll("\n+", "\n"), srcs.map(src => new String(Files.readAllBytes(src))).mkString("\n").replaceAll("\n+", "\n")) - for (info <- c.global.reporter.asInstanceOf[StoreReporter].infos) - assert(checkInfo(info), info) + assertEquals(b, srcs.flatMap(src => Files.readAllLines(src).asScala).mkString("", "\n", "\n")) + if (checkInfo ne allGood) + for (info <- c.global.reporter.asInstanceOf[StoreReporter].infos) + assert(checkInfo(info), info) } } def testQuickfix(a: String, b: String, args: String, checkInfo: StoreReporter.Info => Boolean = _ => true): Unit = - testQuickfixs(List(a), b, args, checkInfo) + testQuickfixes(List(a), b, args, checkInfo) def comp(args: String) = BytecodeTesting.newCompiler(extraArgs = args) @@ -92,8 +100,8 @@ class QuickfixTest extends BytecodeTesting { } @Test def `do not lie about fixing`: Unit = { - val a = "import foo.bar" - testQuickfix(a, a, "-quickfix:any", !_.msg.contains("[rewritten by -quickfix]")) + val a = "import foo.bar" // not found: object foo (not quickfixable; no -Wunused:imports) + testQuickfix(a, a+"\n", "-quickfix:any", !_.msg.contains("[rewritten by -quickfix]")) } // https://github.com/scala/bug/issues/12941 @@ -121,7 +129,7 @@ class QuickfixTest extends BytecodeTesting { | def one = Test1.foo |} |""".stripMargin - testQuickfixs(a1s, b1, "-Xsource:3 -quickfix:any") + testQuickfixes(a1s, b1, "-Xsource:3 -quickfix:any") val a2s = List( """object Test2 { @@ -146,6 +154,171 @@ class QuickfixTest extends BytecodeTesting { | def foo: None.type = None |} |""".stripMargin - testQuickfixs(a2s, b2, "-Xsource:3 -quickfix:any") + testQuickfixes(a2s, b2, "-Xsource:3 -quickfix:any") + } + + @Test def `named boolean literal lint has a fix`: Unit = { + val a = + sm"""|class C { + | def f(hasState: Boolean, isMutable: Boolean): Boolean = hasState && isMutable + | def test = f(true, false) + |} + |""" + val b = + sm"""|class C { + | def f(hasState: Boolean, isMutable: Boolean): Boolean = hasState && isMutable + | def test = f(hasState = true, isMutable = false) + |} + |""" + testQuickfix(a, b, "-Wunnamed-boolean-literal -quickfix:any") + } + + @Test def `synthetic case companion used as a function error has a fix`: Unit = { + val a = + sm"""|case class C(i: Int) + |object Test { + | def test = List(1, 2, 3).map(C) + |} + |""" + val b = + sm"""|case class C(i: Int) + |object Test { + | def test = List(1, 2, 3).map(C.apply) + |} + |""" + testQuickfix(a, b, "-Xsource:3 -quickfix:any") + } + + @Test def `unused import is quickfixable`: Unit = { + val precedingNL = + sm"""|import java.lang.Runnable + |import java.lang.Thread + |class C extends Runnable { def run() = () } + |""" + val resPrecedingNL = + sm"""|import java.lang.Runnable + |class C extends Runnable { def run() = () } + |""" + val noPrecedingNL = + sm"""|import java.lang.Thread + |class C + |""" + val resNoPrecedingNL = + sm"""|class C + |""" + val multiplePrefix = + sm"""|import java.lang.Runnable + |import java.lang.Thread + |class C + |""" + val multipleSuffix = // competing edits to delete line separator, was AIOOB in insertEdits + sm"""|class C + |import java.lang.Runnable + |import java.lang.Thread""" + testQuickfix(precedingNL, resPrecedingNL, "-Wunused:imports -quickfix:any") + testQuickfix(noPrecedingNL, resNoPrecedingNL, "-Wunused:imports -quickfix:any") + testQuickfix(multiplePrefix, resNoPrecedingNL, "-Wunused:imports -quickfix:any") + testQuickfix(multipleSuffix, resNoPrecedingNL, "-Wunused:imports -quickfix:any") + } + + @Test def `unused imports are selectively quickfixable`: Unit = { + val keepEither = + sm"""|import java.lang.{Runnable, Thread} + |class C extends Runnable { def run() = () } + |""" + val keptEither = + sm"""|import java.lang.Runnable + |class C extends Runnable { def run() = () } + |""" + val keepOne = + sm"""|import java.lang.Runnable, java.lang.Thread + |class C extends Runnable { def run() = () } + |""" + val keptOne = + sm"""|import java.lang.Runnable + |class C extends Runnable { def run() = () } + |""" + val keepOther = + sm"""|import java.lang.Thread, java.lang.Runnable + |class C extends Runnable { def run() = () } + |""" + val keepOtherSpacey = + sm"""|import java.lang.Thread , java.lang.Runnable + |class C extends Runnable { def run() = () } + |""" + val keepNeither = + sm"""|import java.lang.Thread, java.lang.Runnable + |class C + |""" + val keepNothing = + sm"""|import java.lang.{Runnable, Thread} + |class C + |""" + val keptNothing = + sm"""|class C + |""" + val keepTwo = + sm"""|import java.lang.{Runnable, System, Thread}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val keptTwo = + sm"""|import java.lang.{Runnable, System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val keepTwoDropHead = + sm"""|import java.lang.{Thread, Runnable, System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val keepTwoDropMiddle = + sm"""|import java.lang.{Runnable, Thread, System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + testQuickfix(keepEither, keptEither, "-Wunused:imports -quickfix:any") + testQuickfix(keepOne, keptOne, "-Wunused:imports -quickfix:any") + testQuickfix(keepOther, keptOne, "-Wunused:imports -quickfix:any") + testQuickfix(keepOtherSpacey, keptOne, "-Wunused:imports -quickfix:any") + testQuickfix(keepNeither, keptNothing, "-Wunused:imports -quickfix:any") + testQuickfix(keepNothing, keptNothing, "-Wunused:imports -quickfix:any") + testQuickfix(keepTwo, keptTwo, "-Wunused:imports -quickfix:any") + testQuickfix(keepTwoDropHead, keptTwo, "-Wunused:imports -quickfix:any") + testQuickfix(keepTwoDropMiddle, keptTwo, "-Wunused:imports -quickfix:any") + } + + @Test def `unused imports respects your weird formatting`: Unit = { + val keepColumns = + sm"""|import java.lang.{Runnable, + | Thread, + | System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val keptColumns = + sm"""|import java.lang.{Runnable, + | System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val overlapping = + sm"""|import java.lang.{AutoCloseable, + | Thread, + | Runnable, + | System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val lapped = + sm"""|import java.lang.{Runnable, + | System}, System.out + |class C extends Runnable { def run() = out.println() } + |""" + val keepRename = + sm"""|import java.lang.{Runnable => R, System, + | Thread}, System.out + |class C extends R { def run() = out.println() } + |""" + val keptRename = + sm"""|import java.lang.{Runnable => R, System}, System.out + |class C extends R { def run() = out.println() } + |""" + testQuickfix(keepColumns, keptColumns, "-Wunused:imports -quickfix:any") + testQuickfix(overlapping, lapped, "-Wunused:imports -quickfix:any") + testQuickfix(keepRename, keptRename, "-Wunused:imports -quickfix:any") } } diff --git a/test/junit/scala/tools/nsc/async/AnnotationDrivenAsyncTest.scala b/test/junit/scala/tools/nsc/async/AnnotationDrivenAsyncTest.scala index 0cf7f8b07dc1..5c0f4df53c4e 100644 --- a/test/junit/scala/tools/nsc/async/AnnotationDrivenAsyncTest.scala +++ b/test/junit/scala/tools/nsc/async/AnnotationDrivenAsyncTest.scala @@ -9,7 +9,7 @@ import org.junit.Assert.assertEquals import org.junit.{Assert, Ignore, Test} import scala.annotation.{StaticAnnotation, nowarn, unused} -import scala.collection.mutable +import scala.collection.mutable, mutable.{Buffer, LinkedHashMap, ListBuffer} import scala.concurrent.duration.Duration import scala.reflect.internal.util.{CodeAction, Position} import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader @@ -391,11 +391,11 @@ class AnnotationDrivenAsyncTest { case DefDef(_, _, _, _, _, Block(stats, expr)) => // collect the two stats and expr from L1 L2 L3 val parseTreeStats: List[Tree] = stats ++ List(expr) - val fsmTree = result.fsmTree - val posMap = mutable.LinkedHashMap[Tree, mutable.Buffer[Tree]]() + val fsmTree = result.fsmTree + val posMap = LinkedHashMap.empty[Tree, Buffer[Tree]] // Traverse the tree and record parent-child relationship - val parentMap = mutable.LinkedHashMap[Tree, Tree]() + val parentMap = LinkedHashMap.empty[Tree, Tree] def collectParents(t: Tree): Unit = { for (child <- t.children) { parentMap(child) = t @@ -414,25 +414,20 @@ class AnnotationDrivenAsyncTest { // of the user-written stats/expr. for { parseTreeStat <- parseTreeStats - pos = parseTreeStat.pos tree <- fsmTree.get - } { - if (pos.includes(tree.pos)) { - posMap.get(parseTreeStat) match { - case Some(existing) => - // Produce minimal output by discarding sub-trees that are contained by larger trees in the - // value of posMap. - if (!existing.exists(t => isAncestor(tree, t))) { - val (retained, discarded) = existing.toList.partition(t => isAncestor(t, tree) || !isAncestor(tree, t)) - existing.clear() - existing ++= retained - existing += tree - } - case None => - posMap(parseTreeStat) = mutable.ListBuffer(tree) - } - } + if parseTreeStat.pos.includes(tree.pos) } + posMap.get(parseTreeStat) match { + case Some(existing) if !existing.exists(isAncestor(tree, _)) => + // Produce minimal output by discarding subtrees that are contained by larger trees in the value of posMap + val (retained, discarded) = existing.toList.partition(t => isAncestor(t, tree) || !isAncestor(tree, t)) + existing.clear() + existing ++= retained + existing += tree + case Some(_) => + case None => + posMap(parseTreeStat) = ListBuffer(tree) + } // The synthetic exception handler and state machine loop should not be positioned within // the position of L1, L2, or L3, as this would trigger a breakpoint at the line on each @@ -443,11 +438,18 @@ class AnnotationDrivenAsyncTest { // Some synthetic code _will_ be at L1 L2 and L3, but this is only directly related to // the save and restore of the variables used/produced by this state. def oneliner(s: String) = s.replace(System.lineSeparator(), "\\n") - val actual = posMap.toList.map { case (orig, corresponding) => s"${oneliner(orig.toString)}\n${"-" * 80}\n${corresponding.map(t => oneliner(t.toString)).mkString("\n")}"}.mkString("\n" * 3) + val actual = posMap.toList.map { + case (orig, corresponding) => + val corr = corresponding.map(t => oneliner(t.toString)).mkString("\n") + s"${oneliner(orig.toString)}\n${"-" * 80}\n${corr}" + }.mkString("\n" * 3) val expected = """val x = id(1) |-------------------------------------------------------------------------------- - |case 0 => {\n val awaitable$async: scala.tools.nsc.async.CustomFuture = scala.tools.nsc.async.CustomFuture._successful(scala.Int.box(Test.this.id(1)));\n tr = self.getCompleted(awaitable$async);\n self.state_=(1);\n if (null.!=(tr))\n while$()\n else\n {\n self.onComplete(awaitable$async);\n return ()\n }\n} + |val awaitable$async: scala.tools.nsc.async.CustomFuture = scala.tools.nsc.async.CustomFuture._successful(scala.Int.box(Test.this.id(1))) + |tr = self.getCompleted(awaitable$async) + |self.state_=(1) + |if (null.!=(tr))\n while$()\nelse\n {\n self.onComplete(awaitable$async);\n return ()\n } | val await$1: Object = {\n val tryGetResult$async: Object = self.tryGet(tr);\n if (self.eq(tryGetResult$async))\n return ()\n else\n tryGetResult$async.$asInstanceOf[Object]()\n} |self.x = scala.Int.unbox(await$1) | @@ -504,26 +506,23 @@ class AnnotationDrivenAsyncTest { def run(code: String, compileOnly: Boolean = false): Any = { val compileResult = compile(code, compileOnly) - try - if (!compileOnly) compileResult.run() - finally { - compileResult.close() - } + try if (!compileOnly) compileResult.run() + finally compileResult.close() } def compile(code: String, compileOnly: Boolean = false): CompileResult = { val out = createTempDir() - val reporter = new StoreReporter(new Settings) { - override def doReport(pos: Position, msg: String, severity: Severity, actions: List[CodeAction]): Unit = - if (severity == INFO) println(msg) - else super.doReport(pos, msg, severity, actions) - } - val settings = new Settings(println(_)) - settings.async.value = true - settings.outdir.value = out.getAbsolutePath - settings.Yrangepos.value = true - settings.embeddedDefaults(getClass.getClassLoader) + val reporter = new StoreReporter(new Settings) { + override def doReport(pos: Position, msg: String, severity: Severity, actions: List[CodeAction]): Unit = + if (severity == INFO) println(msg) + else super.doReport(pos, msg, severity, actions) + } + val settings = new Settings(println(_)) + settings.async.value = true + settings.outdir.value = out.getAbsolutePath + settings.Yrangepos.value = true + settings.embeddedDefaults(getClass.getClassLoader) // settings.debug.value = true // settings.uniqid.value = true @@ -682,7 +681,8 @@ abstract class AnnotationDrivenAsyncPlugin extends Plugin { } } - override val runsAfter: List[String] = "refchecks" :: "patmat" :: Nil + override val runsAfter: List[String] = "refchecks" :: Nil + override val runsRightAfter: Option[String] = Some("patmat") override val phaseName: String = "postpatmat" }) diff --git a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala index ee152eefec13..6d79fd3b54e4 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala @@ -420,7 +420,7 @@ class BytecodeTest extends BytecodeTesting { | } |}""".stripMargin val List(_, cAnon, _) = compileClasses(code) - // field for caputred param is not final + // field for captured param is not final assertEquals(Opcodes.ACC_PRIVATE, cAnon.fields.asScala.find(_.name.startsWith("param")).get.access) assertInvoke(getMethod(cAnon, ""), "scala/runtime/Statics", "releaseFence") } @@ -1003,4 +1003,78 @@ class BytecodeTest extends BytecodeTesting { val lines = compileMethod(c1).instructions.collect { case l: LineNumber => l } assertSameCode(List(LineNumber(2, Label(0))), lines) } + + + @Test + def t12990(): Unit = { + val komp = BytecodeTesting.newCompiler(extraArgs = "-Xasync") + val code = + """import scala.tools.nsc.OptionAwait._ + | + |class C { + | def sw1(i: Int) = optionally { + | i match { + | case 11 if value(Some(430)) > 42 => 22 + | case p => p + | } + | } + | def sw2(i: Int) = optionally { + | i match { + | case 11 => if (value(Some(430)) > 42) 22 else i + | case p => p + | } + | } + | def sw3(i: Int) = optionally { + | i match { + | case 11 => if (value(Some(430)) > 42) 22 else i + | case 22 | 33 => 44 + | case p => p + | } + | } + |} + |""".stripMargin + val cs = komp.compileClasses(code) + + val sm1 = getMethod(cs.find(_.name == "C$stateMachine$async$1").get, "apply") + assertSame(1, sm1.instructions.count(_.opcode == TABLESWITCH)) + + val sm2 = getMethod(cs.find(_.name == "C$stateMachine$async$2").get, "apply") + assertSame(2, sm2.instructions.count(_.opcode == TABLESWITCH)) + + val sm3 = getMethod(cs.find(_.name == "C$stateMachine$async$3").get, "apply") + assertSame(1, sm3.instructions.count(_.opcode == TABLESWITCH)) + assertSame(1, sm3.instructions.count(_.opcode == LOOKUPSWITCH)) + } + + @Test def t13007(): Unit = { + val jc = + """package j; + |public class J { + | protected boolean i() { return false; } + | public boolean k() { return false; } + |} + |""".stripMargin + + val code = + """package s + |trait T { self: j.J => + | override def i(): Boolean = true + | def t1 = i() + | def t2 = this.i() + | def t3 = self.i() + | + | def t4 = k() + | def t5 = this.k() + | def t6 = self.k() + |} + |""".stripMargin + + val List(t) = compileClasses(code, List((jc, "J.java"))) + assertInvoke(getMethod(t, "t1"), "s/T", "i") + assertInvoke(getMethod(t, "t2"), "s/T", "i") + assertInvoke(getMethod(t, "t3"), "s/T", "i") + assertInvoke(getMethod(t, "t4"), "j/J", "k") + assertInvoke(getMethod(t, "t5"), "j/J", "k") + assertInvoke(getMethod(t, "t6"), "j/J", "k") + } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala index 55eddf84341c..ed0019589223 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala @@ -12,6 +12,7 @@ import scala.reflect.internal.util.JavaClearable import scala.tools.asm.tree._ import scala.tools.nsc.backend.jvm.BackendReporting._ import scala.tools.nsc.reporters.StoreReporter +import scala.tools.testkit.ASMConverters.convertMethod import scala.tools.testkit.BytecodeTesting import scala.tools.testkit.BytecodeTesting._ @@ -42,9 +43,9 @@ class CallGraphTest extends BytecodeTesting { val callsite = callGraph.callsites(callsiteMethod)(call) try { assert(callsite.callsiteInstruction == call) - assert(callsite.callsiteMethod == callsiteMethod) + assert(convertMethod(callsite.callsiteMethod) == convertMethod(callsiteMethod)) val callee = callsite.callee.get - assert(callee.callee == target) + assert(convertMethod(callee.callee) == convertMethod(target)) assert(callee.calleeDeclarationClass == calleeDeclClass) assertEquals("safeToInline", safeToInline, callee.safeToInline) assert(callee.annotatedInline == atInline) diff --git a/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala b/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala index d4bd2102a6b2..6feff8c7bfd1 100644 --- a/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala +++ b/test/junit/scala/tools/nsc/classpath/JrtClassPathTest.scala @@ -27,7 +27,7 @@ class JrtClassPathTest { val elements = new ClassPathFactory(settings, closeableRegistry).classesInPath(resolver.Calculated.javaBootClassPath) AggregateClassPath(elements) } - else JrtClassPath(None, None, closeableRegistry).head + else JrtClassPath(None, None, None, closeableRegistry).head assertEquals(Nil, cp.classes("")) assertTrue(cp.packages("java").toString, cp.packages("java").exists(_.name == "java.lang")) diff --git a/test/junit/scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala b/test/junit/scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala index dee4611ed227..58a706f37ce9 100644 --- a/test/junit/scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala +++ b/test/junit/scala/tools/nsc/classpath/ZipAndJarFileLookupFactoryTest.scala @@ -7,14 +7,14 @@ import java.net.{URI, URL} import java.nio.file._ import java.nio.file.attribute.FileTime import scala.reflect.io.AbstractFile +import scala.tools.testkit.AssertUtil._ import scala.tools.testkit.ForDeletion import scala.tools.testkit.Releasables._ import scala.util.chaining._ import scala.util.Using class ZipAndJarFileLookupFactoryTest { - @Test def cacheInvalidation(): Unit = { - if (scala.util.Properties.isWin) return // can't overwrite an open file on windows. + @Test def cacheInvalidation(): Unit = noWin() { // can't overwrite an open file on windows. val f = Files.createTempFile("test-", ".jar") Files.delete(f) diff --git a/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala b/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala index 8889a6553f63..e063f6e81b96 100644 --- a/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala +++ b/test/junit/scala/tools/nsc/interpreter/CompletionTest.scala @@ -13,7 +13,7 @@ class CompletionTest { def newIMain(classBased: Boolean = false): IMain = { val settings = new Settings() - settings.Xjline.value = "off" + settings.Xnojline.value = true settings.usejavacp.value = true settings.Yreplclassbased.value = classBased @@ -94,6 +94,9 @@ class CompletionTest { checkExact(completer, "object O { private def x_y_z = 1; x_y", "}")("x_y_z") checkExact(completer, "object x_y_z; import x_y")("x_y_z") + checkExact(completer, "object O { def `1 thing` = 1 }; O.")("1 thing") + checkExact(completer, "object O { def `` = 1 }; O.")("") + checkExact(completer, "object x_y_z { def a_b_c }; import x_y_z.a_b")("a_b_c") checkExact(completer, "object X { private[this] def definition = 0; def")("definition") @@ -116,6 +119,19 @@ class CompletionTest { checkExact(new ReplCompletion(intp), """object O2 { val x = O.""")("x_y_x", "x_y_z", "getFooBarZot") } + @Test + def backticks(): Unit = { + val intp = newIMain() + val completer = new ReplCompletion(intp) + + checkExact(completer, "object X { def `Foo Bar` = 0; this.`Foo ", after = "` }")("Foo Bar") + checkExact(completer, "val `Foo Bar` = 0; `Foo ", after = "`")("Foo Bar") + checkExact(completer, "def foo(`Foo Bar`: Int) { `Foo ", after = "` }")("Foo Bar") + checkExact(completer, "def foo(`Foo Bar!`: Int) { `Foo ", after = "` }")("Foo Bar!") + checkExact(completer, "def foo(`Foo Bar$`: Int) { `Foo ", after = "` }")("Foo Bar$") + checkExact(completer, "def foo(`$Foo$Bar$`: Int) { `$Foo ", after = "` }")("$Foo$Bar$") + } + @Test def annotations(): Unit = { val completer = setup() diff --git a/test/junit/scala/tools/nsc/parser/ParserTest.scala b/test/junit/scala/tools/nsc/parser/ParserTest.scala index 4a8a312baeb5..8e452dad39e8 100644 --- a/test/junit/scala/tools/nsc/parser/ParserTest.scala +++ b/test/junit/scala/tools/nsc/parser/ParserTest.scala @@ -8,7 +8,7 @@ import org.junit.Assert._ import scala.tools.testkit.BytecodeTesting @RunWith(classOf[JUnit4]) -class ParserTest extends BytecodeTesting{ +class ParserTest extends BytecodeTesting { override def compilerArgs: String = "-Ystop-after:parser -Yvalidate-pos:parser -Yrangepos" @Test def crlfRangePositionXml_t10321(): Unit = { diff --git a/test/junit/scala/tools/nsc/reporters/WConfTest.scala b/test/junit/scala/tools/nsc/reporters/WConfTest.scala index 7a5547e85f82..f7109a17978a 100644 --- a/test/junit/scala/tools/nsc/reporters/WConfTest.scala +++ b/test/junit/scala/tools/nsc/reporters/WConfTest.scala @@ -43,8 +43,7 @@ class WConfTest extends BytecodeTesting { reports(code, extraWconf, lint).filter(_.severity == InternalReporter.INFO) def reports(code: String, extraWconf: String = "", lint: Boolean = false): List[Info] = { - // lint has a postSetHook to enable `deprecated`, which in turn adds to `Wconf`, - // but since we clear and initialize Wconf after enabling lint, that effect is cancelled. + global.settings.deprecation.reset() if (lint) { global.settings.warnUnused.clear() global.settings.lint.tryToSet(List("_")) @@ -215,8 +214,8 @@ class WConfTest extends BytecodeTesting { def lint(): Unit = { check(infos(code, "cat=lint:i"), Nil) check(infos(code, "cat=lint:i", lint = true), List(l2, l23)) - check(reports(code, "any:s,cat=lint:ws", lint = true), Nil) - check(reports(code, "cat=lint:ws,any:s", lint = true), List((-1, "2 lint warnings"))) + check(reports(code, "any:s,cat=lint:ws", lint = true), List((-1, "2 lint warnings"))) + check(reports(code, "cat=lint:ws,any:s", lint = true), Nil) check(infos(code, "cat=lint-deprecation:i", lint = true), List(l2)) check(infos(code, "cat=lint-adapted-args:i", lint = true), List(l23)) } diff --git a/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala b/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala index 37ff8f373766..fdaf53ff9ffd 100644 --- a/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala +++ b/test/junit/scala/tools/nsc/settings/ScalaVersionTest.scala @@ -39,8 +39,6 @@ class ScalaVersionTest { // oh really assertEquals(NoScalaVersion, ScalaVersion("none")) assertSame(NoScalaVersion, ScalaVersion("none")) - assertEquals(Scala3Cross, ScalaVersion("3-cross")) - assertSame(Scala3Cross, ScalaVersion("3-cross")) assertEquals(AnyScalaVersion, ScalaVersion("any")) assertSame(AnyScalaVersion, ScalaVersion("any")) diff --git a/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala b/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala index 898755263a66..2115ffab798d 100644 --- a/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala +++ b/test/junit/scala/tools/nsc/typechecker/InferencerTest.scala @@ -2,7 +2,7 @@ package scala.tools.nsc package typechecker import org.junit.Assert.assertTrue -import org.junit.{After, Before, Test} +import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 @@ -23,21 +23,14 @@ trait ZwC[-T] extends Z[T] with C @RunWith(classOf[JUnit4]) class InferencerTests extends BytecodeTesting { - import compiler.global._, analyzer._ + import compiler.global._ + import analyzer._ - var storedYscala3ImplicitResolution: Boolean = false - @Before - def storeYscala3ImplicitResolution(): Unit = { - storedYscala3ImplicitResolution = settings.Yscala3ImplicitResolution.value - } - @After - def restoreYscala3ImplicitResolution(): Unit = { - settings.Yscala3ImplicitResolution.value = storedYscala3ImplicitResolution - } + override def compilerArgs: String = "-Xsource:3" @Test def isAsSpecificScala2(): Unit = { - settings.Yscala3ImplicitResolution.value = false + settings.XsourceFeatures.clear() val run = new global.Run enteringPhase(run.typerPhase) { @@ -60,7 +53,7 @@ class InferencerTests extends BytecodeTesting { val ZBwC = typeOf[ZwC[B]] // https://github.com/scala/bug/issues/2509 - // See discussion at https://github.com/lampepfl/dotty/blob/89540268e6c49fb92b9ca61249e46bb59981bf5a/src/dotty/tools/dotc/typer/Applications.scala#L925-L951 + // See discussion at https://github.com/scala/scala3/blob/89540268e6c49fb92b9ca61249e46bb59981bf5a/src/dotty/tools/dotc/typer/Applications.scala#L925-L951 // Covariant assertTrue(!typer.infer.isAsSpecific(XA, XB)) @@ -103,7 +96,8 @@ class InferencerTests extends BytecodeTesting { @Test def isAsSpecificScala3(): Unit = { - settings.Yscala3ImplicitResolution.value = true + settings.XsourceFeatures.clear() + settings.XsourceFeatures.tryToSet(List("implicit-resolution")) val run = new global.Run @@ -127,7 +121,7 @@ class InferencerTests extends BytecodeTesting { val ZBwC = typeOf[ZwC[B]] // https://github.com/scala/bug/issues/2509 - // See discussion at https://github.com/lampepfl/dotty/blob/89540268e6c49fb92b9ca61249e46bb59981bf5a/src/dotty/tools/dotc/typer/Applications.scala#L925-L951 + // See discussion at https://github.com/scala/scala3/blob/89540268e6c49fb92b9ca61249e46bb59981bf5a/src/dotty/tools/dotc/typer/Applications.scala#L925-L951 // Covariant assertTrue(!typer.infer.isAsSpecific(XA, XB)) diff --git a/test/junit/scala/tools/nsc/typechecker/TypedTreeTest.scala b/test/junit/scala/tools/nsc/typechecker/TypedTreeTest.scala index 307b9f1378a6..7055fa407e61 100644 --- a/test/junit/scala/tools/nsc/typechecker/TypedTreeTest.scala +++ b/test/junit/scala/tools/nsc/typechecker/TypedTreeTest.scala @@ -60,19 +60,22 @@ class TypedTreeTest extends BytecodeTesting { import compiler.global._ val code = """object O { - | final val x = 42 + | final val x = 42 // accessor gets inlined constant | def f(x: Int) = x | def f(x: Boolean) = x - | f(O.x) + | f(O.x) // arg is inlined constant |} """.stripMargin val run = compiler.newRun() run.compileSources(List(BytecodeTesting.makeSourceFile(code, "UnitTestSource.scala"))) val tree = run.units.next().body - val attached = tree.filter(_.hasAttachment[analyzer.OriginalTreeAttachment]).toList - assertEquals(1, attached.length) - val List(t) = attached - assertEquals("42:Set(OriginalTreeAttachment(O.x))", s"$t:${t.attachments.all}") + tree.filter(_.hasAttachment[analyzer.OriginalTreeAttachment]) + .sortBy(_.pos.start) + .toList + .map(t => s"$t:${t.attachments.all}") match { + case "42:Set(OriginalTreeAttachment(O.this.x))" :: "42:Set(OriginalTreeAttachment(O.x))" :: Nil => + case wrong => throw new MatchError(wrong) + } } diff --git a/test/junit/scala/tools/nsc/typechecker/XMLTest.scala b/test/junit/scala/tools/nsc/typechecker/XMLTest.scala new file mode 100644 index 000000000000..460626dd6b2d --- /dev/null +++ b/test/junit/scala/tools/nsc/typechecker/XMLTest.scala @@ -0,0 +1,43 @@ + +package scala.tools.nsc.typechecker + +import org.junit.Test +import org.junit.Assert._ + +import scala.tools.nsc.reporters.StoreReporter +import scala.tools.testkit.{BytecodeTesting, XMLTesting}, BytecodeTesting.SourceFile, XMLTesting.xml + +class XMLTest extends BytecodeTesting { + override def compilerArgs: String = "-Ystop-after:refchecks -Wnonunit-statement" + + @Test def `building elements does not warn nonunit-statement`: Unit = { + val code = + """ + |object Test { + | val xml = + |} + """.stripMargin + val reporter = compiler.global.reporter.asInstanceOf[StoreReporter] + val run = compiler.newRun() + run.compileSources(SourceFile(xml.code, code)) + assertFalse(reporter.hasWarnings) + assertFalse(reporter.hasErrors) + } +} +class XMLLessTest extends BytecodeTesting { + override def compilerArgs: String = "-Ystop-after:refchecks" + + @Test def `detect XML lib is absent`: Unit = { + val code = + """ + |object Test { + | val xml = + |} + """.stripMargin + val reporter = compiler.global.reporter.asInstanceOf[StoreReporter] + val run = compiler.newRun() + run.compileSources(SourceFile(code)) + assertTrue(reporter.hasErrors) + assertTrue(reporter.infos.forall(_.msg.contains("scala.xml"))) + } +} diff --git a/test/junit/scala/tools/testkit/AssertUtilTest.scala b/test/junit/scala/tools/testkit/AssertUtilTest.scala index 9afa8d7e5618..0b6e6e860cbe 100644 --- a/test/junit/scala/tools/testkit/AssertUtilTest.scala +++ b/test/junit/scala/tools/testkit/AssertUtilTest.scala @@ -21,6 +21,7 @@ import AssertUtil._ import java.lang.ref._ import scala.annotation.unused +import scala.util.Properties.isWin @RunWith(classOf[JUnit4]) class AssertUtilTest { @@ -143,4 +144,7 @@ class AssertUtilTest { assertSameElements(Array(17), Array(42)) } } + @Test def `noWin skips test`: Unit = noWin() { + assertEquals(false, isWin) + } } diff --git a/test/junit/scala/tools/xsbt/TestCallback.scala b/test/junit/scala/tools/xsbt/TestCallback.scala index 4a33ab1583cb..35a434a6821f 100644 --- a/test/junit/scala/tools/xsbt/TestCallback.scala +++ b/test/junit/scala/tools/xsbt/TestCallback.scala @@ -1,7 +1,7 @@ package scala.tools.xsbt import xsbti.api.{ClassLike, DependencyContext} -import xsbti.{Action, AnalysisCallback2, DiagnosticCode, DiagnosticRelatedInformation, Position, Severity, UseScope, VirtualFile, VirtualFileRef} +import xsbti.{Action, AnalysisCallback3, DiagnosticCode, DiagnosticRelatedInformation, Position, Severity, UseScope, VirtualFile, VirtualFileRef} import java.io.File import java.nio.file.Path @@ -9,7 +9,7 @@ import java.util import java.util.Optional import scala.collection.mutable.ArrayBuffer -class TestCallback extends AnalysisCallback2 { +class TestCallback extends AnalysisCallback3 { case class TestUsedName(name: String, scopes: util.EnumSet[UseScope]) val classDependencies = new ArrayBuffer[(String, String, DependencyContext)] @@ -140,6 +140,12 @@ class TestCallback extends AnalysisCallback2 { override def isPickleJava: Boolean = false override def getPickleJarPair = Optional.empty() + + override def getSourceInfos = + throw new UnsupportedOperationException("not expected to be called in tests") + + override def toVirtualFile(path: Path) = + throw new UnsupportedOperationException("not expected to be called in tests") } object TestCallback { diff --git a/test/junit/scala/util/TryTest.scala b/test/junit/scala/util/TryTest.scala index dc681a7b2843..486e936c2d26 100644 --- a/test/junit/scala/util/TryTest.scala +++ b/test/junit/scala/util/TryTest.scala @@ -1,10 +1,9 @@ package scala.util import org.junit.Test -import org.junit.Assert._ +import org.junit.Assert.{assertEquals, assertSame, assertTrue} -import scala.annotation.unused -import scala.tools.testkit.AssertUtil.assertThrows +import scala.tools.testkit.AssertUtil.{assertThrows, fail} class TryTest { /* Test Try's withFilter method, which was added along with the fix for scala/bug#6455 */ @@ -140,7 +139,7 @@ class TryTest { @Test def testForeachFailure(): Unit = { val t = Failure(new Exception("foo")) - t.foreach(x => fail()) + t.foreach(x => fail(t.toString)) } @Test def testFlatMapSuccess(): Unit = { @@ -151,7 +150,8 @@ class TryTest { @Test def testFlatMapFailure(): Unit = { val t = Failure(new Exception("foo")) - @unused val n = t.flatMap{ x => fail(); Try(()) } + val n = t.flatMap { x => fail(t.toString); Try(()) } + assertTrue(n.isFailure) } @Test def testMapSuccess(): Unit = { @@ -162,7 +162,7 @@ class TryTest { @Test def testMapFailure(): Unit = { val t = Failure(new Exception("foo")) - t.map(x => fail()): Unit + t.map(x => fail(t.toString)): Unit } @Test def testFilterSuccessTrue(): Unit = { @@ -175,59 +175,60 @@ class TryTest { val t = Success(1) val n = t.filter(x => x < 0) n match { - case Success(_) => fail() + case Success(_) => fail(n.toString) case Failure(_: NoSuchElementException) => () - case _ => fail() + case _ => fail(n.toString) } } @Test def testFilterFailure(): Unit = { val t = Failure(new Exception("foo")) - @unused val n = t.filter{ x => fail() ; true } + val n = t.filter { x => fail(t.toString) ; true } + assertTrue(n.isFailure) } @Test def testRescueSuccess(): Unit = { val t = Success(1) - t.recoverWith{ case x => fail() ; Try(-1) } + t.recoverWith { case x => fail(t.toString) ; Try(-1) } } @Test def testRescueFailure(): Unit = { val t = Failure(new Exception("foo")) - val n = t.recoverWith{ case x => Try(1) } + val n = t.recoverWith { case x => Try(1) } assertEquals(1, n.get) } @Test def testRecoverSuccess(): Unit = { val t = Success(1) - val n = t.recover{ case x => assert(false); 99 } + val n = t.recover { case x => fail(t.toString); 99 } assertEquals(1, n.get) } @Test def testRecoverWithSuccess(): Unit = { val t = Success(1) - val n = t recoverWith { case _ => assert(false); Success(99) } + val n = t recoverWith { case _ => fail(t.toString); Success(99) } assertEquals(1, n.get) } @Test def testRecoverFailure(): Unit = { val t = Failure(new Exception("foo")) - val n = t.recover{ case x => 1 } + val n = t.recover { case x => 1 } assertEquals(1, n.get) } @Test def testRecoverWithFailure(): Unit = { val t = Failure(new Exception("foo")) val recovered = Failure(new Exception("bar")) - val n = t.recoverWith{ case _ => Success(1) } + val n = t.recoverWith { case _ => Success(1) } assertEquals(1, n.get) - val Failure(f) = t.recoverWith{ case _ => recovered}: @unchecked + val Failure(f) = t.recoverWith { case _ => recovered}: @unchecked assertSame(recovered.exception, f) } @Test def testFlattenSuccess(): Unit = { val f = Failure(new Exception("foo")) val t = Success(f) - assertEquals(t.flatten, f) + assertEquals(f, t.flatten) } @Test def testFailedSuccess(): Unit = { @@ -235,7 +236,7 @@ class TryTest { val n = t.failed n match { case Failure(_: UnsupportedOperationException) => - case _ => fail() + case _ => fail(n.toString) } } @@ -244,7 +245,7 @@ class TryTest { val n = t.failed n match { case Success(_: Exception) => - case _ => fail() + case _ => fail(n.toString) } } diff --git a/test/junit/scala/util/UsingTest.scala b/test/junit/scala/util/UsingTest.scala index eb7350159cdc..cba73c15a42d 100644 --- a/test/junit/scala/util/UsingTest.scala +++ b/test/junit/scala/util/UsingTest.scala @@ -15,29 +15,29 @@ class UsingTest { private def genericResourceThrowing[CloseT <: Throwable: ClassTag]( resource: => CustomResource[CloseT], - onLinkage: SuppressionBehavior, - onInterruption: SuppressionBehavior, - onControl: SuppressionBehavior, - onException: SuppressionBehavior + onLinkage: ThrowBehavior, + onInterruption: ThrowBehavior, + onControl: ThrowBehavior, + onException: ThrowBehavior ): Unit = { def check[UseT <: Throwable: ClassTag]( t: String => UseT, - behavior: SuppressionBehavior, + behavior: ThrowBehavior, allowsSuppression: Boolean ): Unit = { val ex = use(resource, t) - if (behavior == IsSuppressed) { + if (behavior == UseIsThrown) { assertThrowableClass[UseT](ex) if (allowsSuppression) assertSingleSuppressed[CloseT](ex) else assertNoSuppressed(ex) } else { assertThrowableClass[CloseT](ex) - if (behavior == AcceptsSuppressed) assertSingleSuppressed[UseT](ex) + if (behavior == CloseIsThrown) assertSingleSuppressed[UseT](ex) else assertNoSuppressed(ex) } } - check(new UsingVMError(_), behavior = IsSuppressed, allowsSuppression = true) + check(new UsingVMError(_), behavior = UseIsThrown, allowsSuppression = true) check(new UsingLinkageError(_), onLinkage, allowsSuppression = true) check(_ => new UsingInterruption, onInterruption, allowsSuppression = true) check(new UsingControl(_), onControl, allowsSuppression = false) @@ -49,250 +49,248 @@ class UsingTest { def resourceThrowingVMError(): Unit = { genericResourceThrowing( new VMErrorResource, - onLinkage = AcceptsSuppressed, - onInterruption = AcceptsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = CloseIsThrown, + onInterruption = CloseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def resourceThrowingLinkageError(): Unit = { genericResourceThrowing( new LinkageResource, - onLinkage = IsSuppressed, - onInterruption = AcceptsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = UseIsThrown, + onInterruption = CloseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def resourceThrowingInterruption(): Unit = { genericResourceThrowing( new InterruptionResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def resourceThrowingControl(): Unit = { genericResourceThrowing( new ControlResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IgnoresSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = UseIsThrown, + onException = UseIsThrown) } @Test def resourceThrowingError(): Unit = { genericResourceThrowing( new ErrorResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = UseIsThrown) } @Test def resourceThrowingException(): Unit = { genericResourceThrowing( new ExceptionResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = UseIsThrown) } /* `Using.apply` exception preference */ private def genericUsingThrowing[CloseT <: Throwable: ClassTag]( resource: => CustomResource[CloseT], - onLinkage: SuppressionBehavior, - onInterruption: SuppressionBehavior, - onControl: SuppressionBehavior, - onException: SuppressionBehavior + onLinkage: ThrowBehavior, + onInterruption: ThrowBehavior, + onControl: ThrowBehavior, + onException: ThrowBehavior ): Unit = { def check[UseT <: Throwable: ClassTag]( t: String => UseT, - behavior: SuppressionBehavior, + behavior: ThrowBehavior, allowsSuppression: Boolean, - yieldsTry: Boolean ): Unit = { - val ex = if (yieldsTry) UseWrapped(resource, t) else UseWrapped.catching(resource, t) - if (behavior == IsSuppressed) { + val ex = useWrapped(resource, t) + if (behavior == UseIsThrown) { assertThrowableClass[UseT](ex) if (allowsSuppression) assertSingleSuppressed[CloseT](ex) else assertNoSuppressed(ex) } else { assertThrowableClass[CloseT](ex) - if (behavior == AcceptsSuppressed) assertSingleSuppressed[UseT](ex) + if (behavior == CloseIsThrown) assertSingleSuppressed[UseT](ex) else assertNoSuppressed(ex) } } - check(new UsingVMError(_), behavior = IsSuppressed, allowsSuppression = true, yieldsTry = false) - check(new UsingLinkageError(_), onLinkage, allowsSuppression = true, yieldsTry = false) - check(_ => new UsingInterruption, onInterruption, allowsSuppression = true, yieldsTry = false) - check(new UsingControl(_), onControl, allowsSuppression = false, yieldsTry = false) - check(new UsingError(_), onException, allowsSuppression = true, yieldsTry = onException == IsSuppressed) - check(new UsingException(_), onException, allowsSuppression = true, yieldsTry = onException == IsSuppressed) + check(new UsingVMError(_), behavior = UseIsThrown, allowsSuppression = true) + check(new UsingLinkageError(_), onLinkage, allowsSuppression = true) + check(_ => new UsingInterruption, onInterruption, allowsSuppression = true) + check(new UsingControl(_), onControl, allowsSuppression = false) + check(new UsingError(_), onException, allowsSuppression = true) + check(new UsingException(_), onException, allowsSuppression = true) } @Test def usingThrowingVMError(): Unit = { genericUsingThrowing( new VMErrorResource, - onLinkage = AcceptsSuppressed, - onInterruption = AcceptsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = CloseIsThrown, + onInterruption = CloseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def usingThrowingLinkageError(): Unit = { genericUsingThrowing( new LinkageResource, - onLinkage = IsSuppressed, - onInterruption = AcceptsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = UseIsThrown, + onInterruption = CloseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def usingThrowingInterruption(): Unit = { genericUsingThrowing( new InterruptionResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def usingThrowingControl(): Unit = { genericUsingThrowing( new ControlResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IgnoresSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = UseIsThrown, + onException = UseIsThrown) } @Test def usingThrowingError(): Unit = { genericUsingThrowing( new ErrorResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = UseIsThrown) } @Test def usingThrowingException(): Unit = { genericUsingThrowing( new ExceptionResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = UseIsThrown) } /* `Using.Manager.apply` exception preference */ private def genericManagerThrowing[CloseT <: Throwable: ClassTag]( resource: => CustomResource[CloseT], - onLinkage: SuppressionBehavior, - onInterruption: SuppressionBehavior, - onControl: SuppressionBehavior, - onException: SuppressionBehavior + onLinkage: ThrowBehavior, + onInterruption: ThrowBehavior, + onControl: ThrowBehavior, + onException: ThrowBehavior ): Unit = { def check[UseT <: Throwable: ClassTag]( t: String => UseT, - behavior: SuppressionBehavior, + behavior: ThrowBehavior, allowsSuppression: Boolean, - yieldsTry: Boolean ): Unit = { - val ex = if (yieldsTry) UseManager(resource, t) else UseManager.catching(resource, t) - if (behavior == IsSuppressed) { + val ex = useManager(resource, t) + if (behavior == UseIsThrown) { assertThrowableClass[UseT](ex) if (allowsSuppression) assertSingleSuppressed[CloseT](ex) else assertNoSuppressed(ex) } else { assertThrowableClass[CloseT](ex) - if (behavior == AcceptsSuppressed) assertSingleSuppressed[UseT](ex) + if (behavior == CloseIsThrown) assertSingleSuppressed[UseT](ex) else assertNoSuppressed(ex) } } - check(new UsingVMError(_), behavior = IsSuppressed, allowsSuppression = true, yieldsTry = false) - check(new UsingLinkageError(_), onLinkage, allowsSuppression = true, yieldsTry = false) - check(_ => new UsingInterruption, onInterruption, allowsSuppression = true, yieldsTry = false) - check(new UsingControl(_), onControl, allowsSuppression = false, yieldsTry = false) - check(new UsingError(_), onException, allowsSuppression = true, yieldsTry = onException == IsSuppressed) - check(new UsingException(_), onException, allowsSuppression = true, yieldsTry = onException == IsSuppressed) + check(new UsingVMError(_), behavior = UseIsThrown, allowsSuppression = true) + check(new UsingLinkageError(_), onLinkage, allowsSuppression = true) + check(_ => new UsingInterruption, onInterruption, allowsSuppression = true) + check(new UsingControl(_), onControl, allowsSuppression = false) + check(new UsingError(_), onException, allowsSuppression = true) + check(new UsingException(_), onException, allowsSuppression = true) } @Test def managerThrowingVMError(): Unit = { genericManagerThrowing( new VMErrorResource, - onLinkage = AcceptsSuppressed, - onInterruption = AcceptsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = CloseIsThrown, + onInterruption = CloseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def managerThrowingLinkageError(): Unit = { genericManagerThrowing( new LinkageResource, - onLinkage = IsSuppressed, - onInterruption = AcceptsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = UseIsThrown, + onInterruption = CloseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def managerThrowingInterruption(): Unit = { genericManagerThrowing( new InterruptionResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = AcceptsSuppressed, - onException = AcceptsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = CloseIsThrown) } @Test def managerThrowingControl(): Unit = { genericManagerThrowing( new ControlResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IgnoresSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = UseIsThrown, + onException = UseIsThrown) } @Test def managerThrowingError(): Unit = { genericManagerThrowing( new ErrorResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = UseIsThrown) } @Test def managerThrowingException(): Unit = { genericManagerThrowing( new ExceptionResource, - onLinkage = IsSuppressed, - onInterruption = IsSuppressed, - onControl = IsSuppressed, - onException = IsSuppressed) + onLinkage = UseIsThrown, + onInterruption = UseIsThrown, + onControl = CloseIsThrown, + onException = UseIsThrown) } /* nested resource usage returns the correct exception */ @@ -579,13 +577,13 @@ class UsingTest { @Test def usingOpThrow(): Unit = { - val ex = UseWrapped(new NoOpResource, new UsingException(_)) + val ex = useWrapped(new NoOpResource, new UsingException(_)) assertThrowableClass[UsingException](ex) } @Test def managerOpThrow(): Unit = { - val ex = UseManager(new NoOpResource, new UsingException(_)) + val ex = useManager(new NoOpResource, new UsingException(_)) assertThrowableClass[UsingException](ex) } @@ -779,13 +777,11 @@ object UsingTest { final class ErrorResource extends CustomResource(new ClosingError(_)) final class ExceptionResource extends CustomResource(new ClosingException(_)) - sealed trait SuppressionBehavior - /** is added as a suppressed exception to the other exception, and the other exception is thrown */ - case object IsSuppressed extends SuppressionBehavior - /** is thrown, and the other exception is added to this as suppressed */ - case object AcceptsSuppressed extends SuppressionBehavior - /** is thrown, and the other exception is ignored */ - case object IgnoresSuppressed extends SuppressionBehavior + sealed trait ThrowBehavior + /** resource use exception is thrown */ + case object UseIsThrown extends ThrowBehavior + /** resource closing exception is thrown */ + case object CloseIsThrown extends ThrowBehavior def assertThrowableClass[T <: Throwable: ClassTag](t: Throwable): Unit = { assertEquals(s"Caught [${t.getMessage}]", implicitly[ClassTag[T]].runtimeClass, t.getClass) @@ -810,31 +806,24 @@ object UsingTest { } } - object UseWrapped { - def apply(resource: => BaseResource, t: String => Throwable): Throwable = - Using(resource)(opThrowing(t)).failed.get + def use(resource: BaseResource, t: String => Throwable): Throwable = + catchThrowable(Using.resource(resource)(opThrowing(t))) - def catching(resource: => BaseResource, t: String => Throwable): Throwable = - catchThrowable(Using(resource)(opThrowing(t))) - } + def useWrapped(resource: => BaseResource, t: String => Throwable): Throwable = + try Using(resource)(opThrowing(t)).failed.get + catch { + case t: Throwable => t + } - object UseManager { - def apply(resource: => BaseResource, t: String => Throwable): Throwable = + def useManager(resource: => BaseResource, t: String => Throwable): Throwable = + try { Using.Manager { m => val r = m(resource) opThrowing(t)(r) }.failed.get - def catching(resource: => BaseResource, t: String => Throwable): Throwable = - catchThrowable { - Using.Manager { m => - val r = m(resource) - opThrowing(t)(r) - } - } - } - - def use(resource: BaseResource, t: String => Throwable): Throwable = - catchThrowable(Using.resource(resource)(opThrowing(t))) + } catch { + case t: Throwable => t // this is awful + } private def opThrowing(t: String => Throwable): BaseResource => Nothing = r => { diff --git a/test/junit/scala/util/hashing/MurmurHash3Test.scala b/test/junit/scala/util/hashing/MurmurHash3Test.scala index 139b289ab99c..f222f3462a0d 100644 --- a/test/junit/scala/util/hashing/MurmurHash3Test.scala +++ b/test/junit/scala/util/hashing/MurmurHash3Test.scala @@ -56,4 +56,16 @@ class MurmurHash3Test { assertEquals(r5, r6) assertEquals(r5.hashCode, r6.hashCode) } + + @Test + def testEqualArray(): Unit = { + val z1 = (1 to 1).map(_ => 0).toArray + val z2 = (1 to 2).map(_ => 0).toArray + val z3 = (1 to 3).map(_ => 0).toArray + val z4 = (1 to 4).map(_ => 0).toArray + Seq(z1, z2, z3, z4).foreach(z => check(z.toIndexedSeq.hashCode(), z)) + Seq(z1, z2, z3, z4).sliding(2).foreach{ case Seq(a, b) => + assertNotEquals(a.toIndexedSeq.hashCode(), b.toIndexedSeq.hashCode()) + } + } } diff --git a/test/macro-annot/run/repl/repl_2.scala b/test/macro-annot/run/repl/repl_2.scala index db7320da6cb2..9e026ca5354f 100644 --- a/test/macro-annot/run/repl/repl_2.scala +++ b/test/macro-annot/run/repl/repl_2.scala @@ -4,7 +4,7 @@ import scala.tools.nsc.interpreter.shell._ object Test extends App { private def repl(code: String): String = { val s = new Settings - s.Xjline.value = "off" + s.Xnojline.value = true s.usejavacp.value = false s.classpath.value = sys.props("sbt.paths.tests.classpath") s.plugin.value = List(sys.props("sbt.paths.plugin.jar")) diff --git a/test/osgi/src/BasicLibrary.scala b/test/osgi/src/BasicLibrary.scala index ee8b7634ff7c..54aa83ea8b5c 100644 --- a/test/osgi/src/BasicLibrary.scala +++ b/test/osgi/src/BasicLibrary.scala @@ -2,7 +2,6 @@ package tools.test.osgi package libonly import org.junit.Assert._ -import org.ops4j.pax.exam.CoreOptions._ import org.junit.Test import org.junit.runner.RunWith @@ -10,10 +9,6 @@ import org.ops4j.pax.exam import org.ops4j.pax.exam.Configuration import org.ops4j.pax.exam.junit.PaxExam import org.ops4j.pax.exam.spi.reactors.{ ExamReactorStrategy, PerMethod } -import org.ops4j.pax.swissbox.tracker.ServiceLookup -import org.osgi.framework.BundleContext - - @RunWith(classOf[PaxExam]) @ExamReactorStrategy(Array(classOf[PerMethod])) diff --git a/test/osgi/src/BasicReflection.scala b/test/osgi/src/BasicReflection.scala index 53ab7e5345f5..169798429d6d 100644 --- a/test/osgi/src/BasicReflection.scala +++ b/test/osgi/src/BasicReflection.scala @@ -2,10 +2,7 @@ package tools.test.osgi package reflection package basic -import scala.language.higherKinds - import org.junit.Assert._ -import org.ops4j.pax.exam.CoreOptions._ import org.junit.Test import org.junit.runner.RunWith @@ -13,9 +10,6 @@ import org.ops4j.pax.exam import org.ops4j.pax.exam.Configuration import org.ops4j.pax.exam.junit.PaxExam import org.ops4j.pax.exam.spi.reactors.{ ExamReactorStrategy, PerMethod } -import org.ops4j.pax.swissbox.tracker.ServiceLookup -import org.osgi.framework.BundleContext - class C { val f1 = 2 diff --git a/test/osgi/src/BasicTest.scala b/test/osgi/src/BasicTest.scala index 5adf87ecc1fb..10a72b8ba8a1 100644 --- a/test/osgi/src/BasicTest.scala +++ b/test/osgi/src/BasicTest.scala @@ -1,20 +1,11 @@ package tools.test.osgi -import org.junit.Assert._ -import org.ops4j.pax.exam.CoreOptions._ - import org.junit.Test import org.junit.runner.RunWith import org.ops4j.pax.exam import org.ops4j.pax.exam.Configuration import org.ops4j.pax.exam.junit.PaxExam import org.ops4j.pax.exam.spi.reactors.{ ExamReactorStrategy, PerMethod } -import org.ops4j.pax.swissbox.tracker.ServiceLookup -import org.osgi.framework.BundleContext - - - - @RunWith(classOf[PaxExam]) @ExamReactorStrategy(Array(classOf[PerMethod])) diff --git a/test/osgi/src/ReflectionToolboxTest.scala b/test/osgi/src/ReflectionToolboxTest.scala index a23de18d07b4..5ee750550491 100644 --- a/test/osgi/src/ReflectionToolboxTest.scala +++ b/test/osgi/src/ReflectionToolboxTest.scala @@ -3,7 +3,6 @@ package reflection package toolbox import org.junit.Assert._ -import org.ops4j.pax.exam.CoreOptions._ import org.junit.Test import org.junit.runner.RunWith @@ -11,9 +10,6 @@ import org.ops4j.pax.exam import org.ops4j.pax.exam.Configuration import org.ops4j.pax.exam.junit.PaxExam import org.ops4j.pax.exam.spi.reactors.{ ExamReactorStrategy, PerMethod } -import org.ops4j.pax.swissbox.tracker.ServiceLookup -import org.osgi.framework.BundleContext - class C { val f1 = 2 @@ -35,6 +31,7 @@ class ReflectionToolBoxTest extends ScalaOsgiHelper { import scala.tools.reflect.ToolBox val cm = runtimeMirror(classOf[C].getClassLoader) val tb = cm.mkToolBox() + @annotation.unused val im = cm.reflect(new C) val tree = tb.parse("1 to 3 map (_+1)") val eval = tb.eval(tree) diff --git a/test/sbt-test/source-dependencies/empty-package/test b/test/sbt-test/source-dependencies/empty-package/test index e865967b3618..36ceba6bdc81 100644 --- a/test/sbt-test/source-dependencies/empty-package/test +++ b/test/sbt-test/source-dependencies/empty-package/test @@ -9,9 +9,7 @@ $ copy-file changes/Define2.scala Define.scala $ delete Define.scala -# https://github.com/sbt/zinc/issues/1268 -# This compilation should fail, but it doesn't. The `Test` classfiles are deleted, but Use.scala is not re-compiled. -> compile +-> compile $ copy-file changes/Define1.scala Define.scala > compile diff --git a/test/sbt-test/source-dependencies/nested-type-params/test b/test/sbt-test/source-dependencies/nested-type-params/pending similarity index 84% rename from test/sbt-test/source-dependencies/nested-type-params/test rename to test/sbt-test/source-dependencies/nested-type-params/pending index 906e5c82bfbb..787969af7177 100644 --- a/test/sbt-test/source-dependencies/nested-type-params/test +++ b/test/sbt-test/source-dependencies/nested-type-params/pending @@ -5,8 +5,7 @@ $ copy-file changes/Providers.scala Providers.scala $ copy-file changes/Bar.scala Bar.scala -# This should compile --> compile +> compile > clean # Make sure that clean compile is fine > compile diff --git a/test/sbt-test/source-dependencies/sourcepath-virtualfile/changes/B.scala b/test/sbt-test/source-dependencies/sourcepath-virtualfile/changes/B.scala new file mode 100644 index 000000000000..3826c673f1cd --- /dev/null +++ b/test/sbt-test/source-dependencies/sourcepath-virtualfile/changes/B.scala @@ -0,0 +1,3 @@ +class B { + def f: A = new A() +} diff --git a/test/sbt-test/source-dependencies/sourcepath-virtualfile/project/ScriptedTestPlugin.scala b/test/sbt-test/source-dependencies/sourcepath-virtualfile/project/ScriptedTestPlugin.scala new file mode 100644 index 000000000000..b942d9e11876 --- /dev/null +++ b/test/sbt-test/source-dependencies/sourcepath-virtualfile/project/ScriptedTestPlugin.scala @@ -0,0 +1,24 @@ +import sbt._ +import Keys._ + +object ScriptedTestPlugin extends AutoPlugin { + override def requires = plugins.JvmPlugin + override def trigger = allRequirements + + object autoImport { + val setup = taskKey[StateTransform]("setup scripted test") + val cacheId = AttributeKey[String]("cacheId") + } + import autoImport._ + + override val projectSettings = Seq( + scalaVersion := sys.props("plugin.scalaVersion"), + setup := { + IO.copyFile(Path(sys.props("scripted.common")).asFile, baseDirectory.value / "common.sbt") + val id = java.util.UUID.randomUUID().toString + StateTransform(_.put(cacheId, id)) + }, + // https://github.com/sbt/sbt/issues/7432 + Compile / compileAnalysisFilename := (Compile / compileAnalysisFilename).value.dropRight(4) + "-" + state.value.get(cacheId).get + ".zip" + ) +} diff --git a/test/sbt-test/source-dependencies/sourcepath-virtualfile/src/main/scala/A.scala b/test/sbt-test/source-dependencies/sourcepath-virtualfile/src/main/scala/A.scala new file mode 100644 index 000000000000..83d15dc739b5 --- /dev/null +++ b/test/sbt-test/source-dependencies/sourcepath-virtualfile/src/main/scala/A.scala @@ -0,0 +1 @@ +class A diff --git a/test/sbt-test/source-dependencies/sourcepath-virtualfile/src/main/scala/B.scala b/test/sbt-test/source-dependencies/sourcepath-virtualfile/src/main/scala/B.scala new file mode 100644 index 000000000000..a97bc1e396af --- /dev/null +++ b/test/sbt-test/source-dependencies/sourcepath-virtualfile/src/main/scala/B.scala @@ -0,0 +1,3 @@ +class B { + def f = new A() +} diff --git a/test/sbt-test/source-dependencies/sourcepath-virtualfile/test b/test/sbt-test/source-dependencies/sourcepath-virtualfile/test new file mode 100644 index 000000000000..c71f5ed0dec0 --- /dev/null +++ b/test/sbt-test/source-dependencies/sourcepath-virtualfile/test @@ -0,0 +1,10 @@ +> setup; reload + +> set scalacOptions ++= Seq("-sourcepath", (sourceDirectory in Compile).value.getAbsolutePath + "/scala") + +> compile + +$ copy-file changes/B.scala src/main/scala/B.scala +$ touch src/main/scala/A.scala + +> compile diff --git a/test/scalacheck/CheckEither.scala b/test/scalacheck/CheckEither.scala index c650cee4ade3..67bed9b2fb13 100644 --- a/test/scalacheck/CheckEither.scala +++ b/test/scalacheck/CheckEither.scala @@ -1,9 +1,7 @@ -import org.scalacheck.{ Arbitrary, Prop, Properties } +import org.scalacheck.{Arbitrary, Properties} import org.scalacheck.Arbitrary.{arbitrary, arbThrowable} import org.scalacheck.Gen.oneOf import org.scalacheck.Prop._ -import org.scalacheck.Test.check -import Function.tupled import scala.util.Either.LeftProjection @annotation.nowarn("cat=deprecation") diff --git a/test/scalacheck/Ctrie.scala b/test/scalacheck/Ctrie.scala index 9c120c552566..e0d7e12fa54d 100644 --- a/test/scalacheck/Ctrie.scala +++ b/test/scalacheck/Ctrie.scala @@ -5,6 +5,8 @@ import collection._ import collection.concurrent.TrieMap import scala.language.reflectiveCalls +import annotation.unused + case class Wrap(i: Int) { override def hashCode = i // * 0x9e3775cd } @@ -101,7 +103,7 @@ object CtrieTest extends Properties("concurrent.TrieMap") { val ct = new TrieMap[Wrap, Int] // checker - val checker = spawn { + @unused val checker = spawn { def check(last: Map[Wrap, Int], iterationsLeft: Int): Boolean = { val current = ct.readOnlySnapshot() if (!hasGrown(last, current)) false @@ -187,7 +189,7 @@ object CtrieTest extends Properties("concurrent.TrieMap") { val totalInserts = new java.util.concurrent.atomic.AtomicInteger val ct = new TrieMap[Wrap, String] - val results = inParallel(p) { + @unused val results = inParallel(p) { idx => (0 until sz) foreach { i => diff --git a/test/scalacheck/SeqMap.scala b/test/scalacheck/SeqMap.scala index c50996db4dab..04477d93161c 100644 --- a/test/scalacheck/SeqMap.scala +++ b/test/scalacheck/SeqMap.scala @@ -5,8 +5,6 @@ import Arbitrary.arbitrary import Prop._ import Gen._ -import scala.collection.mutable.ListBuffer - object SeqMapTest extends Properties("SeqMap") { property("overrides stringPrefix") = { diff --git a/test/scalacheck/array-new.scala b/test/scalacheck/array-new.scala index de2df68b3a85..fdaab252359b 100644 --- a/test/scalacheck/array-new.scala +++ b/test/scalacheck/array-new.scala @@ -5,7 +5,6 @@ import Gen._ import Arbitrary._ import util._ import Buildable._ -import scala.collection.mutable.ArraySeq object ArrayNewTest extends Properties("Array") { /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out. diff --git a/test/scalacheck/array-old.scala b/test/scalacheck/array-old.scala index 953263666045..639b264cb979 100644 --- a/test/scalacheck/array-old.scala +++ b/test/scalacheck/array-old.scala @@ -4,7 +4,6 @@ import Gen._ import Arbitrary._ import util._ import Buildable._ -import scala.collection.mutable.ArraySeq object ArrayOldTest extends Properties("Array") { /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out. diff --git a/test/scalacheck/primitive-eqeq.scala b/test/scalacheck/primitive-eqeq.scala index ef8a394919c1..71a4e4138894 100644 --- a/test/scalacheck/primitive-eqeq.scala +++ b/test/scalacheck/primitive-eqeq.scala @@ -15,7 +15,7 @@ object PrimitiveEqEqTest extends Properties("==") { property("transitivity") = forAll { (x: AnyVal, y: AnyVal, z: AnyVal) => x != y || y != z || x == z } property("##") = forAll { x: Short => - val anyvals = List(x.toByte, x.toChar, x, x.toInt, x.toLong, x.toFloat, x.toDouble, BigInt(x), BigDecimal(x)) + val anyvals = List[Any](x.toByte, x.toChar, x, x.toInt, x.toLong, x.toFloat, x.toDouble, BigInt(x), BigDecimal(x)) val shortAndLarger = anyvals drop 2 (anyvals.lazyZip(anyvals) forall equalObjectsEqualHashcodes) && diff --git a/test/scalacheck/range.scala b/test/scalacheck/range.scala index f06606b59fbc..339861cb716b 100644 --- a/test/scalacheck/range.scala +++ b/test/scalacheck/range.scala @@ -104,7 +104,6 @@ abstract class RangeTest(kind: String) extends Properties("Range "+kind) { property("foreach.inside.range") = forAll(myGen) { r => // println("foreach.inside.range "+str(r)) var allValid = true - var last: Option[Int] = None val cnt = new Counter(r) r foreach { x => cnt(x) allValid &&= within(r, x) diff --git a/test/scalacheck/redblacktree.scala b/test/scalacheck/redblacktree.scala index 901343852ed7..5cbf4bd7a667 100644 --- a/test/scalacheck/redblacktree.scala +++ b/test/scalacheck/redblacktree.scala @@ -78,10 +78,10 @@ trait RedBlackTreeInvariants[K, V] { import RB._ object RedTree { - def unapply[A, B](t: Tree[A, B]) = if ((t ne null) && t.isRed) Some(t.key, t.value, t.left, t.right) else None + def unapply[A, B](t: Tree[A, B]) = if ((t ne null) && t.isRed) Some((t.key, t.value, t.left, t.right)) else None } object BlackTree { - def unapply[A, B](t: Tree[A, B]) = if ((t ne null) && t.isBlack) Some(t.key, t.value, t.left, t.right) else None + def unapply[A, B](t: Tree[A, B]) = if ((t ne null) && t.isBlack) Some((t.key, t.value, t.left, t.right)) else None } implicit def ordering: Ordering[K] @@ -132,7 +132,7 @@ object TestInsert extends RedBlackTreeTest("RedBlackTree.insert") { override type ModifyParm = Int override def genParm(tree: Tree[String, Int]): Gen[ModifyParm] = choose(0, iterator(tree).size + 1) - override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = update(tree, generateKey(tree, parm), 0, true) + override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = update(tree, generateKey(tree, parm), 0, overwrite = true) def generateKey(tree: Tree[String, Int], parm: ModifyParm): String = nodeAt(tree, parm) match { case Some((key, _)) => key.init.mkString + "MN" @@ -155,7 +155,7 @@ object TestModify extends RedBlackTreeTest("RedBlackTree.modify") { override type ModifyParm = Int override def genParm(tree: Tree[String, Int]): Gen[ModifyParm] = choose(0, iterator(tree).size) override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = nodeAt(tree, parm) map { - case (key, _) => update(tree, key, newValue, true) + case (key, _) => update(tree, key, newValue, overwrite = true) } getOrElse tree property("update modifies values") = forAll(genInput) { case (tree, parm, newTree) => @@ -345,9 +345,9 @@ abstract class BulkTest(pName: String) extends RedBlackTreeTest(pName) { def gen(l1: List[Int], l2: List[Int]) = { var t1: Tree[String, Int] = null - l1.foreach { case i => t1 = update(t1, ""+i, i, false) } + l1.foreach { case i => t1 = update(t1, ""+i, i, overwrite = false) } var t2: Tree[String, Int] = null - l2.foreach { case i => t2 = update(t2, ""+i, i, false) } + l2.foreach { case i => t2 = update(t2, ""+i, i, overwrite = false) } val t3 = validate(modify(t1, t2)) (t1, t2, t3) } diff --git a/test/scalacheck/scala/OptionTest.scala b/test/scalacheck/scala/OptionTest.scala index fe2f0c8637fd..ede217f9b1da 100644 --- a/test/scalacheck/scala/OptionTest.scala +++ b/test/scalacheck/scala/OptionTest.scala @@ -167,7 +167,7 @@ object OptionTest extends Properties("scala.Option") { case Some(x) => option.get ?= { option match { - case Some(x) => x + case Some(y) => y case None => throw new Exception } } diff --git a/test/scalacheck/scala/collection/FloatFormatTest.scala b/test/scalacheck/scala/collection/FloatFormatTest.scala index 6a70352fde82..f42fa9317d62 100644 --- a/test/scalacheck/scala/collection/FloatFormatTest.scala +++ b/test/scalacheck/scala/collection/FloatFormatTest.scala @@ -1,8 +1,7 @@ package scala.collection import scala.util.Try -import org.scalacheck.{Arbitrary, Gen, Properties, Shrink} -import org.scalacheck.Test.Parameters +import org.scalacheck.{Arbitrary, Gen, Properties} import org.scalacheck.Prop._ object FloatFormatTest extends Properties("FloatFormat") { diff --git a/test/scalacheck/scala/collection/IntegralParseTest.scala b/test/scalacheck/scala/collection/IntegralParseTest.scala index b49466e9bb15..a61ea8318791 100644 --- a/test/scalacheck/scala/collection/IntegralParseTest.scala +++ b/test/scalacheck/scala/collection/IntegralParseTest.scala @@ -1,13 +1,9 @@ package scala.collection import scala.util.Try -import org.scalacheck.{Arbitrary, Gen, Properties} -import org.scalacheck.Shrink -import org.scalacheck.Test.Parameters +import org.scalacheck.{Gen, Properties, Shrink} import org.scalacheck.Prop._ -import org.scalacheck.Gen - object NumericStringGenerators { val nearOverflowByteUpper = { diff --git a/test/scalacheck/scala/collection/IteratorProperties.scala b/test/scalacheck/scala/collection/IteratorProperties.scala index 62481d6a4895..f1b495fad175 100644 --- a/test/scalacheck/scala/collection/IteratorProperties.scala +++ b/test/scalacheck/scala/collection/IteratorProperties.scala @@ -1,7 +1,7 @@ package scala.collection import org.scalacheck.{Arbitrary, Gen, Properties, Prop} -import org.scalacheck.Prop.{forAll, all, propBoolean} +import org.scalacheck.Prop.{forAll, propBoolean} object IteratorProperties extends Properties("Iterator") { diff --git a/test/scalacheck/scala/collection/StringOpsProps.scala b/test/scalacheck/scala/collection/StringOpsProps.scala index bdade1547a72..570918b85f76 100644 --- a/test/scalacheck/scala/collection/StringOpsProps.scala +++ b/test/scalacheck/scala/collection/StringOpsProps.scala @@ -28,8 +28,8 @@ object StringOpsTest extends Properties("StringOps") { val stripped = s.linesIterator.toList val lines = s.linesWithSeparators.toList val zipped = stripped.zip(lines) - def shorter = zipped.init.forall { case (s, l) => s.length < l.length } - def maybe = zipped.last match { case (s, l) => s.length <= l.length } + def shorter = zipped.init.forall { case (strip, ln) => strip.length < ln.length } + def maybe = zipped.last match { case (strip, ln) => strip.length <= ln.length } (stripped.length == lines.length && (lines.isEmpty || shorter && maybe)) } diff --git a/test/scalacheck/scala/collection/convert/WrapperProperties.scala b/test/scalacheck/scala/collection/convert/WrapperProperties.scala index fa1e91b0a760..02ecbaeacad5 100644 --- a/test/scalacheck/scala/collection/convert/WrapperProperties.scala +++ b/test/scalacheck/scala/collection/convert/WrapperProperties.scala @@ -1,7 +1,7 @@ package scala.collection.convert -import org.scalacheck.{Properties, Test} +import org.scalacheck.Properties import org.scalacheck.Prop._ import scala.collection.immutable diff --git a/test/scalacheck/scala/collection/immutable/ImmutableChampHashMapProperties.scala b/test/scalacheck/scala/collection/immutable/ImmutableChampHashMapProperties.scala index 2a61d5fe0382..50a7a2e91dbc 100644 --- a/test/scalacheck/scala/collection/immutable/ImmutableChampHashMapProperties.scala +++ b/test/scalacheck/scala/collection/immutable/ImmutableChampHashMapProperties.scala @@ -248,7 +248,7 @@ object ImmutableChampHashMapProperties extends Properties("HashMap") { } val ys: HashMap[Container, Int] = xs.map { case (k, v) => Container(k) -> v } - val zs = ys.filterImpl( { case (k, v) => p((k.inner, v))}, flipped) + @annotation.unused val zs = ys.filterImpl( { case (k, v) => p((k.inner, v))}, flipped) ys.forall(_._1.timesHashed <= 1) } diff --git a/test/scalacheck/scala/collection/immutable/ImmutableChampHashSetProperties.scala b/test/scalacheck/scala/collection/immutable/ImmutableChampHashSetProperties.scala index 257460e5cb37..03f142eaf8cc 100644 --- a/test/scalacheck/scala/collection/immutable/ImmutableChampHashSetProperties.scala +++ b/test/scalacheck/scala/collection/immutable/ImmutableChampHashSetProperties.scala @@ -337,7 +337,6 @@ object ImmutableChampHashSetProperties extends Properties("immutable.HashSet") { property("hs.concat(list) does not mutate hs") = forAll { (hs: HashSet[K], l: List[K]) => - val asList = hs.toList val clone = hs.to(List).to(HashSet) hs.concat(l) hs ?= clone diff --git a/test/scalacheck/scala/collection/immutable/MapProperties.scala b/test/scalacheck/scala/collection/immutable/MapProperties.scala index 3b04b8a60671..377d07a1c3a4 100644 --- a/test/scalacheck/scala/collection/immutable/MapProperties.scala +++ b/test/scalacheck/scala/collection/immutable/MapProperties.scala @@ -2,7 +2,6 @@ package scala.collection.immutable import org.scalacheck.Properties -import scala.language.higherKinds import org.scalacheck.Arbitrary.arbInt import org.scalacheck.Arbitrary import org.scalacheck.Gen diff --git a/test/scalacheck/scala/collection/immutable/SeqProperties.scala b/test/scalacheck/scala/collection/immutable/SeqProperties.scala index 0cd7ecbcbb4f..11c044af1c40 100644 --- a/test/scalacheck/scala/collection/immutable/SeqProperties.scala +++ b/test/scalacheck/scala/collection/immutable/SeqProperties.scala @@ -1,7 +1,5 @@ package scala.collection.immutable - -import scala.language.higherKinds import org.scalacheck.Arbitrary import org.scalacheck.Gen import org.scalacheck.commands.Commands @@ -10,7 +8,6 @@ import scala.collection.mutable import scala.util.{Success, Try} import org.scalacheck.Properties - @annotation.nowarn("cat=deprecation&msg=Stream") object SeqProperties extends Properties("immutable.Seq builder implementations"){ diff --git a/test/scalacheck/scala/collection/immutable/SetProperties.scala b/test/scalacheck/scala/collection/immutable/SetProperties.scala index f34a303cc164..bc3a6fe08a7b 100644 --- a/test/scalacheck/scala/collection/immutable/SetProperties.scala +++ b/test/scalacheck/scala/collection/immutable/SetProperties.scala @@ -1,6 +1,5 @@ package scala.collection.immutable -import scala.language.higherKinds import org.scalacheck.{Arbitrary, Gen, Properties, Shrink} import org.scalacheck.commands.Commands diff --git a/test/scalacheck/scala/collection/immutable/VectorMapProperties.scala b/test/scalacheck/scala/collection/immutable/VectorMapProperties.scala index 1253c6804a95..8feb58fd2aea 100644 --- a/test/scalacheck/scala/collection/immutable/VectorMapProperties.scala +++ b/test/scalacheck/scala/collection/immutable/VectorMapProperties.scala @@ -1,14 +1,12 @@ package scala.collection.immutable import org.scalacheck._ -import Arbitrary.arbitrary import Prop._ import Gen._ import commands.Commands import scala.util.Try - object VectorMapProperties extends Properties("immutable.VectorMap") { type K = Int @@ -145,4 +143,4 @@ object VectorMapProperties extends Properties("immutable.VectorMap") { } VectorMapCommandsChecker.property() } -} \ No newline at end of file +} diff --git a/test/scalacheck/scala/collection/mutable/BuilderProperties.scala b/test/scalacheck/scala/collection/mutable/BuilderProperties.scala index 3f8f834babb9..b26f254bcf0a 100644 --- a/test/scalacheck/scala/collection/mutable/BuilderProperties.scala +++ b/test/scalacheck/scala/collection/mutable/BuilderProperties.scala @@ -1,11 +1,7 @@ package scala.collection.mutable -class BuilderProperties { +class BuilderProperties -} - - -import scala.language.higherKinds import org.scalacheck.Arbitrary.arbInt import org.scalacheck.Arbitrary import org.scalacheck.Gen diff --git a/test/scalacheck/scala/collection/mutable/RedBlackTree.scala b/test/scalacheck/scala/collection/mutable/RedBlackTree.scala index c643a3d4c104..bb80242b4d90 100644 --- a/test/scalacheck/scala/collection/mutable/RedBlackTree.scala +++ b/test/scalacheck/scala/collection/mutable/RedBlackTree.scala @@ -33,14 +33,14 @@ abstract class RedBlackTreeTest(tname: String) extends Properties(tname) with Re def height(node: Node[_, _]): Int = if (node eq null) 0 else (1 + math.max(height(node.left), height(node.right))) def RedTree[A, B](k: A, v: B, l: Tree[A, B], r: Tree[A, B]): Tree[A, B] = { - val n = new Node(k, v, true, l.root, r.root, null) + val n = new Node(k, v, red = true, l.root, r.root, null) if(l.root ne null) l.root.parent = n if(r.root ne null) r.root.parent = n new Tree(n, l.size + r.size + 1) } def BlackTree[A, B](k: A, v: B, l: Tree[A, B], r: Tree[A, B]): Tree[A, B] = { - val n = new Node(k, v, false, l.root, r.root, null) + val n = new Node(k, v, red = false, l.root, r.root, null) if(l.root ne null) l.root.parent = n if(r.root ne null) r.root.parent = n new Tree(n, l.size + r.size + 1) diff --git a/test/scalacheck/scala/jdk/AccumulatorTest.scala b/test/scalacheck/scala/jdk/AccumulatorTest.scala index 6754e6d97feb..ca40e416278a 100644 --- a/test/scalacheck/scala/jdk/AccumulatorTest.scala +++ b/test/scalacheck/scala/jdk/AccumulatorTest.scala @@ -12,10 +12,9 @@ package scala.jdk -import org.scalacheck.{Arbitrary, Gen, Properties} +import org.scalacheck.{Arbitrary, Properties} import Arbitrary.arbitrary import org.scalacheck.Prop.forAll -import scala.util.Random object AccumulatorTest extends Properties("Accumulators") { property("IntAccumulatorConvert") = forAll( diff --git a/test/scalacheck/scala/reflect/quasiquotes/ArbitraryTreesAndNames.scala b/test/scalacheck/scala/reflect/quasiquotes/ArbitraryTreesAndNames.scala index bc6e6089c231..097852caf266 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/ArbitraryTreesAndNames.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/ArbitraryTreesAndNames.scala @@ -1,8 +1,8 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ +import org.scalacheck._, Gen._, Arbitrary._ import scala.language.implicitConversions -import scala.reflect.runtime.universe._, internal._, Flag._ +import scala.reflect.runtime.universe._, Flag._ trait ArbitraryTreesAndNames { def smallList[T](size: Int, g: Gen[T]) = { @@ -34,7 +34,7 @@ trait ArbitraryTreesAndNames { def genModifiers = for(flagset <- genFlagSet) yield Modifiers(flagset) def genConstant = - for(value <- oneOf(arbitrary[Byte], arbitrary[Short], arbitrary[Char], + for (value <- oneOf[Any](arbitrary[Byte], arbitrary[Short], arbitrary[Char], arbitrary[Int], arbitrary[Long], arbitrary[Float], arbitrary[Double], arbitrary[Boolean], arbitrary[String])) yield Constant(value) diff --git a/test/scalacheck/scala/reflect/quasiquotes/DefinitionDeconstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/DefinitionDeconstructionProps.scala index be030bcda094..a6f951a8210a 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/DefinitionDeconstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/DefinitionDeconstructionProps.scala @@ -1,6 +1,6 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ +import org.scalacheck._, Prop._, Gen._ import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.SyntacticClassDef object DefinitionDeconstructionProps diff --git a/test/scalacheck/scala/reflect/quasiquotes/DeprecationProps.scala b/test/scalacheck/scala/reflect/quasiquotes/DeprecationProps.scala index cccb06144ce5..ba72a981fa17 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/DeprecationProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/DeprecationProps.scala @@ -1,6 +1,5 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ import scala.reflect.runtime.universe._ @annotation.nowarn("cat=deprecation") diff --git a/test/scalacheck/scala/reflect/quasiquotes/ErrorProps.scala b/test/scalacheck/scala/reflect/quasiquotes/ErrorProps.scala index cbfc08a8588b..50d16b2664a6 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/ErrorProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/ErrorProps.scala @@ -1,7 +1,5 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ - object ErrorProps extends QuasiquoteProperties("errors") { property("can't extract two .. rankinalities in a row") = fails( "Can't extract with .. here", diff --git a/test/scalacheck/scala/reflect/quasiquotes/ForProps.scala b/test/scalacheck/scala/reflect/quasiquotes/ForProps.scala index 7b2164a5bc13..be299afd5e87 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/ForProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/ForProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport._ +import org.scalacheck._, Prop._, Gen._ +import scala.reflect.runtime.universe._, internal.reificationSupport._ object ForProps extends QuasiquoteProperties("for") { case class ForEnums(val value: List[Tree]) diff --git a/test/scalacheck/scala/reflect/quasiquotes/LiftableProps.scala b/test/scalacheck/scala/reflect/quasiquotes/LiftableProps.scala index 0df4207e3959..2fe82cfc4864 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/LiftableProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/LiftableProps.scala @@ -1,7 +1,6 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import scala.reflect.runtime.universe._ object LiftableProps extends QuasiquoteProperties("liftable") { property("unquote byte") = test { diff --git a/test/scalacheck/scala/reflect/quasiquotes/PatternConstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/PatternConstructionProps.scala index e62a004adc1d..425a89939d1c 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/PatternConstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/PatternConstructionProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import scala.reflect.runtime.universe._ object PatternConstructionProps extends QuasiquoteProperties("pattern construction") { property("unquote bind") = forAll { (bind: Bind) => diff --git a/test/scalacheck/scala/reflect/quasiquotes/PatternDeconstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/PatternDeconstructionProps.scala index 182e905c04c0..4cb4d2b1241b 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/PatternDeconstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/PatternDeconstructionProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import scala.reflect.runtime.universe._ object PatternDeconstructionProps extends QuasiquoteProperties("pattern deconstruction") { property("extract bind") = forAll { (bind: Bind) => diff --git a/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala b/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala index 6dd0cd5c0644..ec6727a7c67d 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala @@ -1,9 +1,9 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ +import org.scalacheck._, Prop._ import scala.tools.reflect.{ToolBox, ToolBoxError} import scala.reflect.runtime.currentMirror -import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.setSymbol +import scala.reflect.runtime.universe._, internal.reificationSupport.setSymbol abstract class QuasiquoteProperties(name: String) extends Properties(name) with ArbitraryTreesAndNames with Helpers diff --git a/test/scalacheck/scala/reflect/quasiquotes/RuntimeErrorProps.scala b/test/scalacheck/scala/reflect/quasiquotes/RuntimeErrorProps.scala index 3335a24c1bed..194c3c148d27 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/RuntimeErrorProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/RuntimeErrorProps.scala @@ -1,7 +1,6 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import scala.reflect.runtime.universe._ object RuntimeErrorProps extends QuasiquoteProperties("errors") { def testFails[T](block: => T) = test { diff --git a/test/scalacheck/scala/reflect/quasiquotes/TermConstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/TermConstructionProps.scala index d06fe6a0736a..b78f16369f6c 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/TermConstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/TermConstructionProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import scala.reflect.runtime.universe._ object TermConstructionProps extends QuasiquoteProperties("term construction") { property("unquote single tree return tree itself") = forAll { (t: Tree) => @@ -232,13 +232,14 @@ object TermConstructionProps extends QuasiquoteProperties("term construction") { object O implicit val liftO = Liftable[O.type] { _ => q"foo; bar" } assertEqAst(q"f(..$O)", "f(foo, bar)") - } + }: @annotation.nowarn("cat=unused-locals") + property("scala/bug#7275 c2") = test { object O implicit val liftO = Liftable[O.type] { _ => q"{ foo; bar }; { baz; bax }" } assertEqAst(q"f(...$O)", "f(foo, bar)(baz, bax)") - } + }: @annotation.nowarn("cat=unused-locals") property("scala/bug#7275 d") = test { val l = q"a; b" :: q"c; d" :: Nil diff --git a/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala index d3534bd5e586..9493664fb0a0 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import org.scalacheck._, Prop._, Gen._ +import scala.reflect.runtime.universe._ object TermDeconstructionProps extends QuasiquoteProperties("term deconstruction") { property("f(..x) = f") = test { diff --git a/test/scalacheck/scala/reflect/quasiquotes/TypeConstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/TypeConstructionProps.scala index c96018b31723..1234e67e1e58 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/TypeConstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/TypeConstructionProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.ScalaDot +import org.scalacheck._, Prop._, Gen._ +import scala.reflect.runtime.universe._, internal.reificationSupport.ScalaDot object TypeConstructionProps extends QuasiquoteProperties("type construction") { property("bare idents contain type names") = test { diff --git a/test/scalacheck/scala/reflect/quasiquotes/TypeDeconstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/TypeDeconstructionProps.scala index ee28d450a9e7..dd4a4783e30d 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/TypeDeconstructionProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/TypeDeconstructionProps.scala @@ -1,7 +1,7 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._ +import org.scalacheck._, Prop._, Gen._ +import scala.reflect.runtime.universe._ object TypeDeconstructionProps extends QuasiquoteProperties("type deconstruction") { property("ident(type name)") = forAll { (name: TypeName) => diff --git a/test/scalacheck/scala/reflect/quasiquotes/TypecheckedProps.scala b/test/scalacheck/scala/reflect/quasiquotes/TypecheckedProps.scala index 4646388c8696..169d657db3b4 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/TypecheckedProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/TypecheckedProps.scala @@ -1,7 +1,6 @@ package scala.reflect.quasiquotes -import org.scalacheck._, Prop._, Gen._, Arbitrary._ -import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport._ +import scala.reflect.runtime.universe._ object TypecheckedProps extends QuasiquoteProperties("typechecked") with TypecheckedTypes { diff --git a/test/scalacheck/scala/reflect/quasiquotes/UnliftableProps.scala b/test/scalacheck/scala/reflect/quasiquotes/UnliftableProps.scala index ae2d9aaf0b7f..e0c8f606d6f2 100644 --- a/test/scalacheck/scala/reflect/quasiquotes/UnliftableProps.scala +++ b/test/scalacheck/scala/reflect/quasiquotes/UnliftableProps.scala @@ -1,7 +1,6 @@ package scala.reflect.quasiquotes import org.junit.Assert.{assertEquals, assertTrue} -import org.scalacheck._, Prop._, Gen._, Arbitrary._ import scala.reflect.runtime.universe._, Flag._ @annotation.nowarn("msg=deprecated adaptation") diff --git a/test/scalacheck/scala/tools/nsc/PhaseAssemblyTest.scala b/test/scalacheck/scala/tools/nsc/PhaseAssemblyTest.scala new file mode 100644 index 000000000000..27616518674a --- /dev/null +++ b/test/scalacheck/scala/tools/nsc/PhaseAssemblyTest.scala @@ -0,0 +1,72 @@ +package scala.tools.nsc + +import scala.collection.mutable + +import org.scalacheck._ +import Prop._ +//import Gen._ +//import Arbitrary._ + +case class Component[G <: Global with Singleton]( + global: G, + phaseName: String, + override val runsRightAfter: Option[String] = None, + override val runsAfter: List[String] = Nil, + override val runsBefore: List[String] = Nil, + override val initial: Boolean = false, + override val terminal: Boolean = false, +) extends SubComponent { + override def newPhase(prev: Phase): Phase = new Phase(prev) { + override def name = phaseName + override def run() = () + } +} + +object PhaseAssemblyTest extends Properties("PhaseAssembly constraints") { + val genTrivialInt: Gen[Int] = Gen.choose(min = 1, max = 2) + val genSmallInt: Gen[Int] = Gen.choose(min = 2, max = 20) + val random = new scala.util.Random(123502L) + property("one or two vertices") = forAllNoShrink(genTrivialInt) { N => + val settings = new Settings + val global = new Global(settings) + val names = Array.tabulate(N)(n => s"phase_${n+1}_${random.nextInt(1024)}") + val components = (0 until N).map(i => Component( + global, + phaseName = names(i), + initial = i == 0, + terminal = i == N-1, + )) + val inputs = random.shuffle(components) + val graph = DependencyGraph(inputs) + val phases: List[SubComponent] = graph.compilerPhaseList() + components(0) == phases.head + components(N-1) == phases.last + } + property("small graph with follow constraints") = forAllNoShrink(genSmallInt) { N => + val settings = new Settings + val global = new Global(settings) + val names = Array.tabulate(N)(n => s"phase_${n+1}_${random.nextInt(1024)}") + def randomBefore(n: Int): List[String] = + if (n == 0) Nil + else (1 to 3).map(_ => names(random.nextInt(n))).distinct.toList + val components = (0 until N).map(i => Component( + global, + phaseName = names(i), + runsAfter = randomBefore(i), + initial = i == 0, + terminal = i == N-1, + )) + val inputs = random.shuffle(components) + val graph = DependencyGraph(inputs) + val phases: List[SubComponent] = graph.compilerPhaseList() + val (_, fails) = phases.foldLeft((mutable.Set.empty[String],mutable.Set.empty[SubComponent])) { case ((seen,fails), comp) => + if (!comp.runsAfter.forall(seen)) fails.addOne(comp) + (seen.addOne(comp.phaseName), fails) + } + if (fails.nonEmpty) println { + fails.map(comp => s"${comp.phaseName} runs after ${comp.runsAfter.mkString(",")}") + .mkString("failures\n", "\n", s"\n${phases.map(_.phaseName).mkString(",")}") + } + components(0) == phases.head && fails.isEmpty + } +} diff --git a/test/scalacheck/scala/tools/nsc/scaladoc/HtmlFactoryTest.scala b/test/scalacheck/scala/tools/nsc/scaladoc/HtmlFactoryTest.scala index 67c4d5c3c99b..82cf41613caf 100644 --- a/test/scalacheck/scala/tools/nsc/scaladoc/HtmlFactoryTest.scala +++ b/test/scalacheck/scala/tools/nsc/scaladoc/HtmlFactoryTest.scala @@ -28,7 +28,7 @@ object HtmlFactoryTest extends Properties("HtmlFactory") { new DocFactory(reporter, settings) } - import scala.tools.nsc.doc.html.HtmlTags.{textOf, Elem => Node, Elems => NodeSeq} + import scala.tools.nsc.doc.html.HtmlTags.textOf def createTemplates(basename: String, set: Settings => Unit = _ => ()): collection.Map[String, HtmlPage] = { val result = mutable.Map[String, HtmlPage]() diff --git a/test/scalacheck/scala/tools/nsc/scaladoc/SettingsUtil.scala b/test/scalacheck/scala/tools/nsc/scaladoc/SettingsUtil.scala index 6ab703a437a6..165341f3f79d 100644 --- a/test/scalacheck/scala/tools/nsc/scaladoc/SettingsUtil.scala +++ b/test/scalacheck/scala/tools/nsc/scaladoc/SettingsUtil.scala @@ -1,6 +1,5 @@ package scala.tools.nsc.scaladoc -import java.net.{URLClassLoader, URLDecoder} import java.nio.file.{Files, Path, Paths} import scala.tools.nsc.Settings diff --git a/test/scalacheck/treeset.scala b/test/scalacheck/treeset.scala index e4ba91f54727..5706fc8c7664 100644 --- a/test/scalacheck/treeset.scala +++ b/test/scalacheck/treeset.scala @@ -3,7 +3,6 @@ import org.scalacheck._ import Prop._ import Gen._ import Arbitrary._ -import util._ object TreeSetTest extends Properties("TreeSet") { def genTreeSet[A: Arbitrary: Ordering]: Gen[TreeSet[A]] = diff --git a/test/scaladoc/resources/doc-root/Any.scala b/test/scaladoc/resources/doc-root/Any.scala index b00a744c36a9..63cd5dc33648 100644 --- a/test/scaladoc/resources/doc-root/Any.scala +++ b/test/scaladoc/resources/doc-root/Any.scala @@ -15,7 +15,6 @@ package scala /** Class `Any` is the root of the Scala class hierarchy. Every class in a Scala * execution environment inherits directly or indirectly from this class. * - * Starting with Scala 2.10 it is possible to directly extend `Any` using ''universal traits''. * A ''universal trait'' is a trait that extends `Any`, only has `def`s as members, and does no initialization. * * The main use case for universal traits is to allow basic inheritance of methods for [[scala.AnyVal value classes]]. diff --git a/test/scaladoc/run/t8755.check b/test/scaladoc/run/t8755.check new file mode 100644 index 000000000000..059eb801b2b8 --- /dev/null +++ b/test/scaladoc/run/t8755.check @@ -0,0 +1,8 @@ +warning: No phase `refchecks` for ploogin.runsAfter +warning: Dropping phase ploogin, it is not reachable from parser +parser -> namer -> packageobjects -> typer -> terminal +[running phase parser on newSource] +[running phase namer on newSource] +[running phase packageobjects on newSource] +[running phase typer on newSource] +Done. diff --git a/test/scaladoc/run/t8755/Test_2.scala b/test/scaladoc/run/t8755/Test_2.scala new file mode 100644 index 000000000000..9b69c67e9643 --- /dev/null +++ b/test/scaladoc/run/t8755/Test_2.scala @@ -0,0 +1,25 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest +import scala.tools.nsc.plugins.PluginDescription +import scala.util.chaining._ + +object Test extends ScaladocModelTest { + + override def code = """ + class C + """ + + override def scaladocSettings = s"-Vdebug -Xplugin:$testOutput -Xplugin-require:ploogin" + + override def testModel(rootPackage: Package) = () + + override def newDocFactory = + super.newDocFactory.tap(df => println(df.compiler.phaseNames.mkString(" -> "))) + + override def show() = { + val xml = PluginDescription("ploogin", "t8755.Ploogin").toXML + (testOutput / "scalac-plugin.xml").toFile.writeAll(xml) + super.show() + } +} diff --git a/test/scaladoc/run/t8755/ploogin_1.scala b/test/scaladoc/run/t8755/ploogin_1.scala new file mode 100644 index 000000000000..590289b99db6 --- /dev/null +++ b/test/scaladoc/run/t8755/ploogin_1.scala @@ -0,0 +1,28 @@ + +package t8755 + +import scala.tools.nsc.{Global, Phase} +import scala.tools.nsc.plugins.{Plugin, PluginComponent} +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global) extends Plugin { + import global._ + + val name = "ploogin" + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + val runsAfter = List("refchecks") + val phaseName = Ploogin.this.name + override def description = "Follows refchecks, so must not run in Scaladoc" + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit): Unit = ??? + } + } +} diff --git a/test/scaladoc/run/t8755b.check b/test/scaladoc/run/t8755b.check new file mode 100644 index 000000000000..05d8171972e8 --- /dev/null +++ b/test/scaladoc/run/t8755b.check @@ -0,0 +1,10 @@ +warning: No phase `refchecks` for ploogin.runsAfter +warning: No phase `jvm` for ploogin.runsBefore +parser -> namer -> packageobjects -> typer -> ploogin -> terminal +[running phase parser on newSource] +[running phase namer on newSource] +[running phase packageobjects on newSource] +[running phase typer on newSource] +[running phase ploogin on newSource] +running plugin +Done. diff --git a/test/scaladoc/run/t8755b/Test_2.scala b/test/scaladoc/run/t8755b/Test_2.scala new file mode 100644 index 000000000000..9b69c67e9643 --- /dev/null +++ b/test/scaladoc/run/t8755b/Test_2.scala @@ -0,0 +1,25 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest +import scala.tools.nsc.plugins.PluginDescription +import scala.util.chaining._ + +object Test extends ScaladocModelTest { + + override def code = """ + class C + """ + + override def scaladocSettings = s"-Vdebug -Xplugin:$testOutput -Xplugin-require:ploogin" + + override def testModel(rootPackage: Package) = () + + override def newDocFactory = + super.newDocFactory.tap(df => println(df.compiler.phaseNames.mkString(" -> "))) + + override def show() = { + val xml = PluginDescription("ploogin", "t8755.Ploogin").toXML + (testOutput / "scalac-plugin.xml").toFile.writeAll(xml) + super.show() + } +} diff --git a/test/scaladoc/run/t8755b/ploogin_1.scala b/test/scaladoc/run/t8755b/ploogin_1.scala new file mode 100644 index 000000000000..ceecb0d97031 --- /dev/null +++ b/test/scaladoc/run/t8755b/ploogin_1.scala @@ -0,0 +1,29 @@ + +package t8755 + +import scala.tools.nsc.{Global, Phase} +import scala.tools.nsc.plugins.{Plugin, PluginComponent} +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global) extends Plugin { + import global._ + + val name = "ploogin" + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + override val runsBefore = List("jvm") + val runsAfter = List("typer", "refchecks") + val phaseName = Ploogin.this.name + override def description = "Multiple unsatisfiable constraints in Scaladoc" + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit): Unit = println("running plugin") + } + } +} diff --git a/test/scaladoc/run/t8755c.check b/test/scaladoc/run/t8755c.check new file mode 100644 index 000000000000..7d783baa4c3f --- /dev/null +++ b/test/scaladoc/run/t8755c.check @@ -0,0 +1,8 @@ +warning: No phase `refchecks` for ploogin.runsBefore +warning: Dropping phase ploogin, it is not reachable from parser +parser -> namer -> packageobjects -> typer -> terminal +[running phase parser on newSource] +[running phase namer on newSource] +[running phase packageobjects on newSource] +[running phase typer on newSource] +Done. diff --git a/test/scaladoc/run/t8755c/Test_2.scala b/test/scaladoc/run/t8755c/Test_2.scala new file mode 100644 index 000000000000..7e27589d568c --- /dev/null +++ b/test/scaladoc/run/t8755c/Test_2.scala @@ -0,0 +1,25 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest +import scala.tools.nsc.plugins.PluginDescription +import scala.util.chaining._ + +object Test extends ScaladocModelTest { + + override def code = """ + class C + """ + + override def scaladocSettings = s"-Xplugin:$testOutput -Xplugin-require:ploogin -Vdebug" + + override def testModel(rootPackage: Package) = () + + override def newDocFactory = + super.newDocFactory.tap(df => println(df.compiler.phaseNames.mkString(" -> "))) + + override def show() = { + val xml = PluginDescription("ploogin", "t8755.Ploogin").toXML + (testOutput / "scalac-plugin.xml").toFile.writeAll(xml) + super.show() + } +} diff --git a/test/scaladoc/run/t8755c/ploogin_1.scala b/test/scaladoc/run/t8755c/ploogin_1.scala new file mode 100644 index 000000000000..d4578f3631c3 --- /dev/null +++ b/test/scaladoc/run/t8755c/ploogin_1.scala @@ -0,0 +1,29 @@ + +package t8755 + +import scala.tools.nsc.{Global, Phase} +import scala.tools.nsc.plugins.{Plugin, PluginComponent} +import scala.reflect.io.Path +import scala.reflect.io.File + +/** A test plugin. */ +class Ploogin(val global: Global) extends Plugin { + import global._ + + val name = "ploogin" + val description = "A sample plugin for testing." + val components = List[PluginComponent](TestComponent) + + private object TestComponent extends PluginComponent { + val global: Ploogin.this.global.type = Ploogin.this.global + override val runsBefore = List("refchecks") + val runsAfter = Nil + val phaseName = Ploogin.this.name + override def description = "Before refchecks but empty after; warn if debug" + def newPhase(prev: Phase) = new TestPhase(prev) + class TestPhase(prev: Phase) extends StdPhase(prev) { + override def description = TestComponent.this.description + def apply(unit: CompilationUnit): Unit = ??? + } + } +} diff --git a/test/tasty/neg-full-circle/src-3-app/TestExperimentalDefsPre.check b/test/tasty/neg-full-circle/src-3-app/TestExperimentalDefsPre.check index bdd98c5ac849..117f99d896f0 100644 --- a/test/tasty/neg-full-circle/src-3-app/TestExperimentalDefsPre.check +++ b/test/tasty/neg-full-circle/src-3-app/TestExperimentalDefsPre.check @@ -1,17 +1,37 @@ -- Error: TestExperimentalDefsPre_fail.scala:1:18 1 |import downstream.ExperimentalDefsPre.* | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |object ExperimentalDefsPre is marked @experimental and therefore may only be used in an experimental scope. + | object ExperimentalDefsPre is marked @experimental + | + | Experimental definition may only be used under experimental mode: + | 1. in a definition marked as @experimental, or + | 2. an experimental feature is imported at the package level, or + | 3. compiling with the -experimental compiler flag. -- Error: TestExperimentalDefsPre_fail.scala:4:10 4 | def test = new SubExperimentalNotExperimental | ^ - |object ExperimentalDefsPre is marked @experimental and therefore may only be used in an experimental scope. + | object ExperimentalDefsPre is marked @experimental + | + | Experimental definition may only be used under experimental mode: + | 1. in a definition marked as @experimental, or + | 2. an experimental feature is imported at the package level, or + | 3. compiling with the -experimental compiler flag. -- Error: TestExperimentalDefsPre_fail.scala:4:17 4 | def test = new SubExperimentalNotExperimental | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |object ExperimentalDefsPre is marked @experimental and therefore may only be used in an experimental scope. + | object ExperimentalDefsPre is marked @experimental + | + | Experimental definition may only be used under experimental mode: + | 1. in a definition marked as @experimental, or + | 2. an experimental feature is imported at the package level, or + | 3. compiling with the -experimental compiler flag. -- Error: TestExperimentalDefsPre_fail.scala:6:35 6 | class SubSubExperimental extends SubExperimentalNotExperimental | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |object ExperimentalDefsPre is marked @experimental and therefore may only be used in an experimental scope. + | object ExperimentalDefsPre is marked @experimental + | + | Experimental definition may only be used under experimental mode: + | 1. in a definition marked as @experimental, or + | 2. an experimental feature is imported at the package level, or + | 3. compiling with the -experimental compiler flag. 4 errors found diff --git a/test/tasty/neg-pipelined/src-2/tastytest/TestRawTypes.check b/test/tasty/neg-pipelined/src-2/tastytest/TestRawTypes.check index fd6f4d2bf488..d49fb4d79f96 100644 --- a/test/tasty/neg-pipelined/src-2/tastytest/TestRawTypes.check +++ b/test/tasty/neg-pipelined/src-2/tastytest/TestRawTypes.check @@ -1,22 +1,22 @@ TestRawTypes_fail.scala:15: error: type mismatch; found : lib.RawTypes#C[String]#D[String] required: lib.RawTypes#C[T]#D[_] -Note: String <: Object, but Java-defined class D is invariant in type U. -You may wish to investigate a wildcard type such as `_ <: Object`. (SLS 3.2.10) +Note: String <: Any, but Java-defined class D is invariant in type U. +You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10) RawTypes.mii_Raw_Raw(cd_ii) // error ^ TestRawTypes_fail.scala:16: error: type mismatch; found : lib.RawTypes#C[String]#D[String]#E[String] required: lib.RawTypes#C[T]#D[U]#E[_] -Note: String <: Object, but Java-defined class E is invariant in type V. -You may wish to investigate a wildcard type such as `_ <: Object`. (SLS 3.2.10) +Note: String <: Any, but Java-defined class E is invariant in type V. +You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10) RawTypes.miii_Raw_Raw_Raw(cde_iii) // error ^ TestRawTypes_fail.scala:18: error: type mismatch; found : lib.RawTypes.CStatic[String]#D[String] required: lib.RawTypes.CStatic[T]#D[_] -Note: String <: Object, but Java-defined class D is invariant in type U. -You may wish to investigate a wildcard type such as `_ <: Object`. (SLS 3.2.10) +Note: String <: Any, but Java-defined class D is invariant in type U. +You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10) RawTypes.msi_Raw_Raw(cd_si) // error ^ 3 errors diff --git a/test/tasty/neg/src-2/TestTrackedParam.check b/test/tasty/neg/src-2/TestTrackedParam.check new file mode 100644 index 000000000000..4f3ca85c2569 --- /dev/null +++ b/test/tasty/neg/src-2/TestTrackedParam.check @@ -0,0 +1,6 @@ +TestTrackedParam_fail.scala:12: error: type mismatch; + found : tastytest.TrackedParam.C#T + required: Int + def test: Int = new F(y).x.t // error: just ignore tracked flag - so x is not refined. + ^ +1 error diff --git a/test/tasty/neg/src-2/TestTrackedParam_fail.scala b/test/tasty/neg/src-2/TestTrackedParam_fail.scala new file mode 100644 index 000000000000..0f679212123e --- /dev/null +++ b/test/tasty/neg/src-2/TestTrackedParam_fail.scala @@ -0,0 +1,14 @@ +package tastytest + +import scala.annotation.experimental + +@experimental +object TestTrackedParam { + + import TrackedParam._ + + val y: C { type T = Int } = ??? + + def test: Int = new F(y).x.t // error: just ignore tracked flag - so x is not refined. +} + diff --git a/test/tasty/neg/src-3/TrackedParam.scala b/test/tasty/neg/src-3/TrackedParam.scala new file mode 100644 index 000000000000..0552226850d9 --- /dev/null +++ b/test/tasty/neg/src-3/TrackedParam.scala @@ -0,0 +1,23 @@ +package tastytest + +import scala.language.future +import scala.language.experimental.modularity + +object TrackedParam { + + class C { + type T + lazy val t: T = ??? + } + + def f(x: C): x.T = x.t + + val y: C { type T = Int } = ??? + + class F(tracked val x: C) { + lazy val result: x.T = f(x) + } + + def test: Int = new F(y).result +} + diff --git a/test/tasty/pos-doctool/src-2/app/Main.scala b/test/tasty/pos-doctool/src-2/app/Main.scala new file mode 100644 index 000000000000..d9ef49e0f357 --- /dev/null +++ b/test/tasty/pos-doctool/src-2/app/Main.scala @@ -0,0 +1,8 @@ +package app + +object Main { + def main(args: Array[String]): Unit = { + println(testlib.ADT.SingletonCase) + println(testlib.ADT.ClassCase("foo")) + } +} diff --git a/test/tasty/pos-doctool/src-3/testlib/ADT.scala b/test/tasty/pos-doctool/src-3/testlib/ADT.scala new file mode 100644 index 000000000000..0a867618d309 --- /dev/null +++ b/test/tasty/pos-doctool/src-3/testlib/ADT.scala @@ -0,0 +1,5 @@ +package testlib + +enum ADT: + case SingletonCase + case ClassCase(x: String) diff --git a/test/tasty/pos/src-2/tastytest/TestArrayAnnot.scala b/test/tasty/pos/src-2/tastytest/TestArrayAnnot.scala index 328bd2d213a8..565cabac1eb1 100644 --- a/test/tasty/pos/src-2/tastytest/TestArrayAnnot.scala +++ b/test/tasty/pos/src-2/tastytest/TestArrayAnnot.scala @@ -3,9 +3,9 @@ package tastytest object TestArrayAnnot { def test = { forceAnnots[ - Tagged, + Tagged, SuppressWarnings, - "new SuppressWarnings(Array.type.apply[String]((Array[String]{\"xyz\", \"foo\"}: String*))(reflect#ClassTag.type.apply[String](classOf[java.lang.String])))" + "new SuppressWarnings(value = Array.type.apply[String]((Array[String]{\"xyz\", \"foo\"}: String*))(reflect#ClassTag.type.apply[String](classOf[java.lang.String])))" ] } } diff --git a/test/tasty/run-pipelined/src-2/tastytest/TestInnerClass.scala b/test/tasty/run-pipelined/src-2/tastytest/TestInnerClass.scala index 0ebede740674..c085ecad129e 100644 --- a/test/tasty/run-pipelined/src-2/tastytest/TestInnerClass.scala +++ b/test/tasty/run-pipelined/src-2/tastytest/TestInnerClass.scala @@ -51,7 +51,7 @@ object TestInnerClass extends scala.App { * 71: IDENTtpt 13 [U] * 73: SHAREDtype 62 () * So either we do branching to lookup `Inner` in the non-static scope, or we do nothing - * and fix the TASTy generation (AKA fix the scala 3 typer, see https://github.com/lampepfl/dotty/issues/19619) + * and fix the TASTy generation (AKA fix the scala 3 typer, see https://github.com/scala/scala3/issues/19619) */ val ici_inner3: InnerClass#Inner[Long] = InnerClass.createInnerStatic[Long](47L) diff --git a/test/tasty/run/src-2/tastytest/TestAppliedTypeLambda.scala b/test/tasty/run/src-2/tastytest/TestAppliedTypeLambda.scala new file mode 100644 index 000000000000..3a7652984eae --- /dev/null +++ b/test/tasty/run/src-2/tastytest/TestAppliedTypeLambda.scala @@ -0,0 +1,22 @@ +package tastytest + +object TestAppliedTypeLambda extends Suite("TestAppliedTypeLambda") { + + test("make empty array") { + val arr: Array[Int] = AppliedTypeLambda.emptyArray[Int] + assert(arr.getClass().isArray() && arr.getClass().getComponentType() == java.lang.Integer.TYPE) + } + + test("make empty array with class Tparam") { + val factory = new AppliedTypeLambda.InTypeParam[reflect.ClassTag] + val arr: Array[Int] = factory.emptyArray[Int] + assert(arr.getClass().isArray() && arr.getClass().getComponentType() == java.lang.Integer.TYPE) + } + + test("make empty array with method Tparam") { + val arr: Array[Int] = AppliedTypeLambda.emptyArray2[Int, reflect.ClassTag] + assert(arr.getClass().isArray() && arr.getClass().getComponentType() == java.lang.Integer.TYPE) + } +} + + diff --git a/test/tasty/run/src-2/tastytest/TestEnum.scala b/test/tasty/run/src-2/tastytest/TestEnum.scala index 6e050475f2ce..5f86551c80bc 100644 --- a/test/tasty/run/src-2/tastytest/TestEnum.scala +++ b/test/tasty/run/src-2/tastytest/TestEnum.scala @@ -6,7 +6,7 @@ object TestEnum extends Suite("TestEnum") { final class Colour(name: String, ordinal: Int) extends Enum[Colour](name, ordinal) - object Colour extends EnumCompanion[Colour] { + object Colour extends EnumCompanion[Colour](implicitly)() { val Red = new Colour("Red", 0) val Green = new Colour("Green", 1) val Blue = new Colour("Blue", 2) diff --git a/test/tasty/run/src-2/tastytest/TestHKNest.scala b/test/tasty/run/src-2/tastytest/TestHKNest.scala index b055ef8bc7df..a90c56d571c3 100644 --- a/test/tasty/run/src-2/tastytest/TestHKNest.scala +++ b/test/tasty/run/src-2/tastytest/TestHKNest.scala @@ -25,6 +25,6 @@ object TestHKNest extends Suite("TestHKNest") { type OrNothing[I] = Either[Nothing, I] - // test(assert(new HKClass_8[Boo].foo(new Boo[StringOrInt]) == "Boo")) blocked by https://github.com/lampepfl/dotty/issues/8329 + // test(assert(new HKClass_8[Boo].foo(new Boo[StringOrInt]) == "Boo")) blocked by https://github.com/scala/scala3/issues/8329 } diff --git a/test/tasty/run/src-2/tastytest/TestHello.scala b/test/tasty/run/src-2/tastytest/TestHello.scala index 0ef576f11533..8097b36bb18f 100644 --- a/test/tasty/run/src-2/tastytest/TestHello.scala +++ b/test/tasty/run/src-2/tastytest/TestHello.scala @@ -25,7 +25,7 @@ object TestHello extends Suite("TestHello") { test(assert((HelloWorld.lzy: "lazy") === "lazy")) test(assert(HelloWorld.acceptsOnlyMsg4(HelloWorld.msg4) === "Hello, World!Hello, World!")) test(assert(HelloWorld.`1) my long test assertion that 1^3 == 2` === 2)) - // test(assert(HelloWorld.`` === 157)) // wait until https://github.com/lampepfl/dotty/issues/7799 + // test(assert(HelloWorld.`` === 157)) // wait until https://github.com/scala/scala3/issues/7799 type OrInt[A] = Either[Int, A] diff --git a/test/tasty/run/src-2/tastytest/TestTraitsWithSideEffects.scala b/test/tasty/run/src-2/tastytest/TestTraitsWithSideEffects.scala index 02b840937e6e..bdcf982cf7fb 100644 --- a/test/tasty/run/src-2/tastytest/TestTraitsWithSideEffects.scala +++ b/test/tasty/run/src-2/tastytest/TestTraitsWithSideEffects.scala @@ -15,7 +15,7 @@ object TestTraitsWithSideEffects extends Suite("TestTraitsWithSideEffects") { test("init map with no backing field") { class ExprMapInit(val map: mutable.Map[String, Boolean]) extends ExprMapNoField - val exprMap = new ExprMapInit(mutable.AnyRefMap.empty) + val exprMap = new ExprMapInit(mutable.HashMap.empty) assert(checkEntries(exprMap.map)) } } diff --git a/test/tasty/run/src-3/tastytest/AppliedTypeLambda.scala b/test/tasty/run/src-3/tastytest/AppliedTypeLambda.scala new file mode 100644 index 000000000000..a7fab8e2e6ee --- /dev/null +++ b/test/tasty/run/src-3/tastytest/AppliedTypeLambda.scala @@ -0,0 +1,15 @@ +package tastytest + +object AppliedTypeLambda: + + // This reflects the state of context function expansion in Scala 3.5.0-RC1 + // this was fixed in 3.5.0-RC3, but technically any user could type this? + def emptyArray[T](using ct: ([T1] =>> reflect.ClassTag[T1])[T]): Array[T] = + new Array[T](0) + + def emptyArray2[T, F[T2] <: ([T1] =>> reflect.ClassTag[T1])[T2]](using ct: F[T]): Array[T] = + new Array[T](0) + + class InTypeParam[F[T] <: ([T1] =>> reflect.ClassTag[T1])[T]]: + def emptyArray[T](using ct: F[T]): Array[T] = new Array[T](0) + diff --git a/test/tasty/run/src-3/tastytest/HKNest.scala b/test/tasty/run/src-3/tastytest/HKNest.scala index 6f72cfc78cae..c07f9c0fd735 100644 --- a/test/tasty/run/src-3/tastytest/HKNest.scala +++ b/test/tasty/run/src-3/tastytest/HKNest.scala @@ -59,11 +59,11 @@ object HKNest { type ThrowawayHK[G[X]] = Foo[[T] =>> Either[Nothing, T]] // class HKClass_8[P[F[X <: String]] <: Hoo[StringOrInt]] { - // def foo[F[X <: String]](x: P[F]): String = x.toString() https://github.com/lampepfl/dotty/issues/8329 + // def foo[F[X <: String]](x: P[F]): String = x.toString() https://github.com/scala/scala3/issues/8329 // } type OrInt[X] = Either[X, Int] - // type StringOrInt[X <: String] = Either[X, Int] https://github.com/lampepfl/dotty/issues/8329 + // type StringOrInt[X <: String] = Either[X, Int] https://github.com/scala/scala3/issues/8329 class Box[A] @@ -109,7 +109,7 @@ object HKNest { override def toString(): String = "Contra" } - // class Hoo[F[X <: String] <: Either[X, Int]] { https://github.com/lampepfl/dotty/issues/8329 + // class Hoo[F[X <: String] <: Either[X, Int]] { https://github.com/scala/scala3/issues/8329 // override def toString(): String = "Hoo" // } diff --git a/test/tasty/run/src-3/tastytest/HelloWorld.scala b/test/tasty/run/src-3/tastytest/HelloWorld.scala index ac99a54a7fa2..b1154531249c 100644 --- a/test/tasty/run/src-3/tastytest/HelloWorld.scala +++ b/test/tasty/run/src-3/tastytest/HelloWorld.scala @@ -27,6 +27,6 @@ object HelloWorld { def acceptsOnlyMsg4(m: msg4.type): String = m + m final lazy val lzy = "lazy" def `1) my long test assertion that 1^3 == 2`: Int = 1^3 - // def ``: Int = 157 // broken in https://github.com/lampepfl/dotty/issues/7799 + // def ``: Int = 157 // broken in https://github.com/scala/scala3/issues/7799 } diff --git a/test/tasty/run/src-3/tastytest/TraitsWithSideEffects.scala b/test/tasty/run/src-3/tastytest/TraitsWithSideEffects.scala index 0410c5cd5f92..94b6a0bf6e46 100644 --- a/test/tasty/run/src-3/tastytest/TraitsWithSideEffects.scala +++ b/test/tasty/run/src-3/tastytest/TraitsWithSideEffects.scala @@ -10,7 +10,7 @@ object TraitsWithSideEffects { } trait ExprMap { - val map: mutable.Map[String, Boolean] = mutable.AnyRefMap.empty + val map: mutable.Map[String, Boolean] = mutable.HashMap.empty setupEntries(map) } diff --git a/test/tasty/test/scala/tools/tastytest/TastyTestJUnit.scala b/test/tasty/test/scala/tools/tastytest/TastyTestJUnit.scala index 324163ff847c..dbd53a19c5e5 100644 --- a/test/tasty/test/scala/tools/tastytest/TastyTestJUnit.scala +++ b/test/tasty/test/scala/tools/tastytest/TastyTestJUnit.scala @@ -2,14 +2,12 @@ package scala.tools.tastytest import org.junit.{Test => test, BeforeClass => setup, AfterClass => teardown} import org.junit.Assert._ -import org.junit.Assume._ -import scala.util.{Try, Failure, Properties} +import scala.util.Properties import TastyTestJUnit._ class TastyTestJUnit { - val isWindows = Properties.isWin @test def run(): Unit = TastyTest.runSuite( src = "run", @@ -18,18 +16,17 @@ class TastyTestJUnit { outDir = None, additionalSettings = Nil, additionalDottySettings = Nil - ).eval + ).get @test def runPipelined(): Unit = { - assumeFalse("Disabled on Windows due to bug in jar format", isWindows) TastyTest.runPipelinedSuite( src = "run-pipelined", srcRoot = assertPropIsSet(propSrc), pkgName = assertPropIsSet(propPkgName), outDirs = None, additionalSettings = Nil, - additionalDottySettings = Nil - ).eval + additionalDottySettings = Seq("-Yexplicit-nulls"), // test flexible types from Java + ).get } @test def pos(): Unit = TastyTest.posSuite( @@ -39,7 +36,7 @@ class TastyTestJUnit { outDir = None, additionalSettings = Nil, additionalDottySettings = Nil - ).eval + ).get /** false positives that should fail, but work when annotations are not read */ @test def posFalseNoAnnotations(): Unit = TastyTest.posSuite( @@ -49,7 +46,16 @@ class TastyTestJUnit { outDir = None, additionalSettings = Seq("-Ytasty-no-annotations"), additionalDottySettings = Nil - ).eval + ).get + + @test def posDoctool(): Unit = TastyTest.posDocSuite( + src = "pos-doctool", + srcRoot = assertPropIsSet(propSrc), + pkgName = assertPropIsSet(propPkgName), + outDir = None, + additionalSettings = Nil, + additionalDottySettings = Nil + ).get @test def neg(): Unit = TastyTest.negSuite( src = "neg", @@ -58,18 +64,17 @@ class TastyTestJUnit { outDir = None, additionalSettings = Nil, additionalDottySettings = Nil - ).eval + ).get @test def negPipelined(): Unit = { - assumeFalse("Disabled on Windows due to bug in jar format", isWindows) TastyTest.negPipelinedSuite( src = "neg-pipelined", srcRoot = assertPropIsSet(propSrc), pkgName = assertPropIsSet(propPkgName), outDirs = None, additionalSettings = Nil, - additionalDottySettings = Nil - ).eval + additionalDottySettings = Seq("-Yexplicit-nulls") // test flexible types from Java + ).get } @test def negMoveMacros(): Unit = TastyTest.negChangePreSuite( @@ -79,7 +84,7 @@ class TastyTestJUnit { outDirs = None, additionalSettings = Nil, additionalDottySettings = Nil - ).eval + ).get @test def negIsolated(): Unit = TastyTest.negSuiteIsolated( src = "neg-isolated", @@ -88,7 +93,7 @@ class TastyTestJUnit { outDirs = None, additionalSettings = Nil, additionalDottySettings = Nil - ).eval + ).get @test def negFullCircle(): Unit = TastyTest.negFullCircleSuite( src = "neg-full-circle", @@ -97,7 +102,7 @@ class TastyTestJUnit { outDir = None, additionalSettings = Nil, additionalDottySettings = Nil - ).eval + ).get val propSrc = "tastytest.src" val propPkgName = "tastytest.packageName" @@ -124,11 +129,4 @@ object TastyTestJUnit { def finish(): Unit = { _dottyClassLoader = null } - - final implicit class TryOps(val op: Try[Unit]) extends AnyVal { - def eval: Unit = op match { - case Failure(err) => fail(err.getMessage) - case _ => () - } - } } diff --git a/versions.properties b/versions.properties index 91a885489c97..57f5135041b9 100644 --- a/versions.properties +++ b/versions.properties @@ -1,14 +1,12 @@ # Scala version used for bootstrapping (see README.md) -starr.version=2.13.12 +starr.version=2.13.17-M1 # These are the versions of the modules that go with this release. # Artifact dependencies: # - scala-compiler: jline (% "optional") # Other usages: # - scala-asm: jar content included in scala-compiler -scala-asm.version=9.6.0-scala-1 +scala-asm.version=9.8.0-scala-1 # REPL -jline.version=3.24.1 -## also update jline-terminal-jna in the IntelliJ sample -jna.version=5.13.0 +jline.version=3.29.0