diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md index 52f8010c372e..afbaa8020e07 100644 --- a/.github/ISSUE_TEMPLATE/feature.md +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -1,10 +1,10 @@ --- name: "\U0001F389 Suggest a feature" -about: Please create a feature request here https://github.com/lampepfl/dotty/discussions/new?category=feature-requests +about: Please create a feature request here https://github.com/scala/scala3/discussions/new?category=feature-requests title: '' labels: '' assignees: '' --- -Please create a feature request in the [Dotty Discussions](https://github.com/lampepfl/dotty/discussions/new?category=feature-requests). +Please create a feature request in the [Dotty Discussions](https://github.com/scala/scala3/discussions/new?category=feature-requests). diff --git a/.github/ISSUE_TEMPLATE/improve-error.md b/.github/ISSUE_TEMPLATE/improve-error.md index 918196e1ec53..72d556951e53 100644 --- a/.github/ISSUE_TEMPLATE/improve-error.md +++ b/.github/ISSUE_TEMPLATE/improve-error.md @@ -19,7 +19,7 @@ This code should be self-contained, reproducible (i.e. produces the expected err Ideally, we should be able to just copy this code in a file and run `scalac` (and maybe `scala`) to reproduce the issue. -For a good example, see https://github.com/lampepfl/dotty/issues/18657 +For a good example, see https://github.com/scala/scala3/issues/18657 --> ```Scala @@ -44,12 +44,12 @@ for example: ## Why this Error/Warning was not helpful -<!-- For a good example, see https://github.com/lampepfl/dotty/issues/18657 --> +<!-- For a good example, see https://github.com/scala/scala3/issues/18657 --> The message was unhelpful because... ## Suggested improvement -<!-- For a good example, see https://github.com/lampepfl/dotty/issues/18657 --> +<!-- For a good example, see https://github.com/scala/scala3/issues/18657 --> It could be made more helpful by... diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fd1fe30d3fa9..cf375b147793 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -53,7 +53,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || ( github.event_name == 'pull_request' @@ -62,14 +62,17 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: - name: Set JDK 16 as default run: echo "/usr/lib/jvm/java-16-openjdk-amd64/bin" >> $GITHUB_PATH + ## Workaround for https://github.com/actions/runner/issues/2033 (See https://github.com/scala/scala3/pull/19720) - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -102,7 +105,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || github.event_name == 'merge_group' || ( @@ -112,7 +115,7 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: @@ -120,7 +123,9 @@ jobs: run: echo "/usr/lib/jvm/java-16-openjdk-amd64/bin" >> $GITHUB_PATH - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -136,7 +141,7 @@ jobs: - name: Cmd Tests run: | - ./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/* ;scala2-library-tasty-tests/run ;scala2-library-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test" + ./project/scripts/sbt ";dist/pack; scala3-bootstrapped/compile; scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/*; scala2-library-tasty-tests/test; scala3-compiler-bootstrapped/scala3CompilerCoursierTest:test" ./project/scripts/cmdTests ./project/scripts/bootstrappedOnlyCmdTests @@ -145,7 +150,10 @@ jobs: ./project/scripts/sbt ";sjsSandbox/run ;sjsSandbox/test ;sjsJUnitTests/test ;set sjsJUnitTests/scalaJSLinkerConfig ~= switchToESModules ;sjsJUnitTests/test ;sjsCompilerTests/test" - name: Test with Scala 2 library TASTy (fast) - run: ./project/scripts/sbt ";set ThisBuild/Build.useScala2LibraryTasty := true ;scala3-bootstrapped/testCompilation i5; scala3-bootstrapped/testCompilation tests/run/typelevel-peano.scala; scala3-bootstrapped/testOnly dotty.tools.backend.jvm.DottyBytecodeTests" # only test a subset of test to avoid doubling the CI execution time + run: ./project/scripts/sbt ";set ThisBuild/Build.scala2Library := Build.Scala2LibraryTasty ;scala3-bootstrapped/testCompilation i5; scala3-bootstrapped/testCompilation tests/run/typelevel-peano.scala; scala3-bootstrapped/testOnly dotty.tools.backend.jvm.DottyBytecodeTests" # only test a subset of test to avoid doubling the CI execution time + + - name: Test with Scala 2 library with CC TASTy (fast) + run: ./project/scripts/sbt "scala2-library-cc/compile; scala2-library-cc-tasty/compile; scala3-bootstrapped/testCompilation i3" test_scala2_library_tasty: runs-on: [self-hosted, Linux] @@ -156,14 +164,14 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || ( github.event_name == 'pull_request' && contains(github.event.pull_request.body, '[test_scala2_library_tasty]') ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: @@ -171,7 +179,9 @@ jobs: run: echo "/usr/lib/jvm/java-16-openjdk-amd64/bin" >> $GITHUB_PATH - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -186,7 +196,11 @@ jobs: run: cp -vf .github/workflows/repositories /root/.sbt/ ; true - name: Test with Scala 2 library TASTy - run: ./project/scripts/sbt ";set ThisBuild/Build.useScala2LibraryTasty := true ;scala3-bootstrapped/test" + run: ./project/scripts/sbt ";set ThisBuild/Build.scala2Library := Build.Scala2LibraryTasty ;scala3-bootstrapped/test" + + # TODO test all the test configurations in non-CC library (currently disabled due to bug while loading the library) + # - name: Test with Scala 2 library with CC TASTy + # run: ./project/scripts/sbt ";set ThisBuild/Build.scala2Library := Build.Scala2LibraryCCTasty ;scala3-bootstrapped/test" test_windows_fast: @@ -204,8 +218,10 @@ jobs: steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true shell: cmd + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Git Checkout uses: actions/checkout@v4 @@ -236,7 +252,7 @@ jobs: test_windows_full: runs-on: [self-hosted, Windows] - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || ( github.event_name == 'pull_request' @@ -246,8 +262,10 @@ jobs: steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true shell: cmd + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Git Checkout uses: actions/checkout@v4 @@ -270,7 +288,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || github.event_name == 'merge_group' || ( @@ -280,11 +298,13 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -316,7 +336,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || github.event_name == 'merge_group' || ( @@ -327,12 +347,14 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -348,6 +370,7 @@ jobs: - name: Test run: | + git config --global --add safe.directory /__w/scala3/scala3 git submodule sync git submodule update --init --recursive --jobs 7 ./project/scripts/sbt "community-build/testOnly dotty.communitybuild.CommunityBuildTestA" @@ -365,7 +388,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || github.event_name == 'merge_group' || ( @@ -376,12 +399,14 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -397,6 +422,7 @@ jobs: - name: Test run: | + git config --global --add safe.directory /__w/scala3/scala3 git submodule sync git submodule update --init --recursive --jobs 7 ./project/scripts/sbt "community-build/testOnly dotty.communitybuild.CommunityBuildTestB" @@ -414,7 +440,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || github.event_name == 'merge_group' || ( @@ -425,12 +451,14 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -446,6 +474,7 @@ jobs: - name: Test run: | + git config --global --add safe.directory /__w/scala3/scala3 git submodule sync git submodule update --init --recursive --jobs 7 ./project/scripts/sbt "community-build/testOnly dotty.communitybuild.CommunityBuildTestC" @@ -463,7 +492,7 @@ jobs: - ${{ github.workspace }}/../../cache/sbt:/root/.sbt - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || github.event_name == 'push' || ( github.event_name == 'pull_request' @@ -472,12 +501,14 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -504,7 +535,7 @@ jobs: - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache - if: "github.event_name == 'schedule' && github.repository == 'lampepfl/dotty' + if: "github.event_name == 'schedule' && github.repository == 'scala/scala3' || ( github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/') @@ -516,7 +547,7 @@ jobs: ) || ( github.event_name == 'workflow_dispatch' - && github.repository == 'lampepfl/dotty' + && github.repository == 'scala/scala3' )" steps: @@ -524,7 +555,9 @@ jobs: run: echo "/usr/lib/jvm/java-8-openjdk-amd64/bin" >> $GITHUB_PATH - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -540,7 +573,7 @@ jobs: - name: Test run: | - ./project/scripts/sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/* ;scala2-library-tasty-tests/run ;scala2-library-tasty-tests/test" + ./project/scripts/sbt ";dist/pack ;scala3-bootstrapped/compile ;scala3-bootstrapped/test ;sbt-test/scripted scala2-compat/*; scala2-library-tasty-tests/test" ./project/scripts/cmdTests ./project/scripts/bootstrappedOnlyCmdTests @@ -558,7 +591,7 @@ jobs: - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache needs: [test_non_bootstrapped, test, mima, community_build_a, community_build_b, community_build_c, test_sbt, test_java8] - if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'lampepfl/dotty'" + if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'scala/scala3'" env: NIGHTLYBUILD: yes PGP_PW: ${{ secrets.PGP_PW }} # PGP passphrase @@ -568,7 +601,9 @@ jobs: steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -609,7 +644,7 @@ jobs: - ${{ github.workspace }}/../../cache/ivy:/root/.ivy2/cache - ${{ github.workspace }}/../../cache/general:/root/.cache needs: [publish_nightly] - if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'lampepfl/dotty'" + if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'scala/scala3'" env: NIGHTLYBUILD: yes DOTTY_WEBSITE_BOT_TOKEN: ${{ secrets.BOT_TOKEN }} # If you need to change this: @@ -622,7 +657,9 @@ jobs: steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 @@ -638,6 +675,7 @@ jobs: - name: Generate Website run: | + git config --global --add safe.directory /__w/scala3/scala3 ./project/scripts/genDocs -doc-snapshot - name: Deploy Website to dotty-website @@ -672,7 +710,9 @@ jobs: steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/scala3/scala3 + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/scala/scala3" && git reset --hard FETCH_HEAD || true - name: Checkout cleanup script uses: actions/checkout@v4 diff --git a/.github/workflows/lts-backport.yaml b/.github/workflows/lts-backport.yaml index 8e8added1c03..090b55b8eaf5 100644 --- a/.github/workflows/lts-backport.yaml +++ b/.github/workflows/lts-backport.yaml @@ -15,7 +15,7 @@ jobs: with: fetch-depth: 0 - uses: coursier/cache-action@v6 - - uses: VirtusLab/scala-cli-setup@v1.1.0 + - uses: VirtusLab/scala-cli-setup@v1.1.2 - run: scala-cli ./project/scripts/addToBackportingProject.scala -- ${{ github.sha }} env: GRAPHQL_API_TOKEN: ${{ secrets.GRAPHQL_API_TOKEN }} diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index f2cd0706cfe7..dde8b0372d52 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -18,7 +18,9 @@ jobs: steps: - name: Reset existing repo - run: git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true + run: | + git config --global --add safe.directory /__w/dotty/dotty + git -c "http.https://github.com/.extraheader=" fetch --recurse-submodules=no "https://github.com/lampepfl/dotty" && git reset --hard FETCH_HEAD || true - name: Cleanup run: .github/workflows/cleanup.sh diff --git a/.github/workflows/scripts/publish-sdkman.sh b/.github/workflows/scripts/publish-sdkman.sh index 70987bff175b..f959c426e9d8 100755 --- a/.github/workflows/scripts/publish-sdkman.sh +++ b/.github/workflows/scripts/publish-sdkman.sh @@ -10,8 +10,8 @@ set -u # latest stable dotty version -DOTTY_VERSION=$(curl -s https://api.github.com/repos/lampepfl/dotty/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') -DOTTY_URL="https://github.com/lampepfl/dotty/releases/download/$DOTTY_VERSION/scala3-$DOTTY_VERSION.zip" +DOTTY_VERSION=$(curl -s https://api.github.com/repos/scala/scala3/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') +DOTTY_URL="https://github.com/scala/scala3/releases/download/$DOTTY_VERSION/scala3-$DOTTY_VERSION.zip" # checking if dotty version is available if ! curl --output /dev/null --silent --head --fail "$DOTTY_URL"; then diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 1e80f891e987..fd14bab68153 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -15,11 +15,11 @@ The issue supervisor is responsible for: - Modifying issue labels to best capture information about the issues - Attempting to reproduce the issue (or label “stat:cannot reproduce”) - Further minimizing the issue or asking the reporter of the issue to minimize it correctly (or label “stat:needs minimization”) - - Identifying which issues are of considerable importance and bringing them to the attention of the team during the Dotty meeting, where they can be filtered and added to the [Future Versions](https://github.com/lampepfl/dotty/milestone/46) milestone. + - Identifying which issues are of considerable importance and bringing them to the attention of the team during the Dotty meeting, where they can be filtered and added to the [Future Versions](https://github.com/scala/scala3/milestone/46) milestone. - Identifying if a report is really a feature request and if so, converting it to - a [feature request discussion](https://github.com/lampepfl/dotty/discussions/categories/feature-requests). + a [feature request discussion](https://github.com/scala/scala3/discussions/categories/feature-requests). - Keeping an eye on new -[discussions](https://github.com/lampepfl/dotty/discussions), making sure they +[discussions](https://github.com/scala/scala3/discussions), making sure they don't go unanswered and also correctly labeling new feature requests. Other core teammates are responsible for providing information to the issue supervisor in a timely manner when it is requested if they have that information. diff --git a/NOTICE.md b/NOTICE.md index 64c1ede1a5eb..fd931397a500 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1,6 +1,6 @@ Dotty (https://dotty.epfl.ch) -Copyright 2012-2023 EPFL -Copyright 2012-2023 Lightbend, Inc. +Copyright 2012-2024 EPFL +Copyright 2012-2024 Lightbend, Inc. Licensed under the Apache License, Version 2.0 (the "License"): http://www.apache.org/licenses/LICENSE-2.0 @@ -104,4 +104,4 @@ major authors were omitted by oversight. [3] https://github.com/sbt/sbt/tree/0.13/compile/interface/src/main/scala/xsbt [4] https://github.com/scoverage/scalac-scoverage-plugin [5] https://github.com/scalameta/metals -[6] https://github.com/lampepfl/dotty/pull/5783/files +[6] https://github.com/scala/scala3/pull/5783/files diff --git a/README.md b/README.md index 1e62e90a1845..6c3212f0676b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Dotty ===== -[![Dotty CI](https://github.com/lampepfl/dotty/workflows/Dotty/badge.svg?branch=master)](https://github.com/lampepfl/dotty/actions?query=branch%3Amain) +[![Dotty CI](https://github.com/scala/scala3/workflows/Dotty/badge.svg?branch=master)](https://github.com/scala/scala3/actions?query=branch%3Amain) [![Join the chat at https://discord.com/invite/scala](https://img.shields.io/discord/632150470000902164)](https://discord.com/invite/scala) * [Documentation](https://docs.scala-lang.org/scala3/) @@ -23,7 +23,7 @@ other more direct lines of communication such as email. How to Contribute ================= * [Getting Started as Contributor](https://docs.scala-lang.org/scala3/guides/contribution/contribution-intro.html) -* [Issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) +* [Issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) License ======= diff --git a/bench/profiles/compiletime.yml b/bench/profiles/compiletime.yml index fd77df7dfe9a..520af3750aa4 100644 --- a/bench/profiles/compiletime.yml +++ b/bench/profiles/compiletime.yml @@ -1,31 +1,31 @@ charts: - name: "Compile-time sums of constant integer types (generated)" - url: https://github.com/lampepfl/dotty/blob/main/bench/src/main/scala/generateBenchmarks.scala + url: https://github.com/scala/scala3/blob/main/bench/src/main/scala/generateBenchmarks.scala lines: - key: compiletime-sum-constants label: bootstrapped - name: "Compile-time sums of term reference types (generated)" - url: https://github.com/lampepfl/dotty/blob/main/bench/src/main/scala/generateBenchmarks.scala + url: https://github.com/scala/scala3/blob/main/bench/src/main/scala/generateBenchmarks.scala lines: - key: compiletime-sum-termrefs label: bootstrapped - name: "Sums of term references, result type inferred (generated)" - url: https://github.com/lampepfl/dotty/blob/main/bench/src/main/scala/generateBenchmarks.scala + url: https://github.com/scala/scala3/blob/main/bench/src/main/scala/generateBenchmarks.scala lines: - key: compiletime-sum-termrefs-terms label: bootstrapped - name: "Compile-time sums of type applications (generated)" - url: https://github.com/lampepfl/dotty/blob/main/bench/src/main/scala/generateBenchmarks.scala + url: https://github.com/scala/scala3/blob/main/bench/src/main/scala/generateBenchmarks.scala lines: - key: compiletime-sum-applications label: bootstrapped - name: "Compile-time additions inside multiplications (generated)" - url: https://github.com/lampepfl/dotty/blob/main/bench/src/main/scala/generateBenchmarks.scala + url: https://github.com/scala/scala3/blob/main/bench/src/main/scala/generateBenchmarks.scala lines: - key: compiletime-distribute label: bootstrapped @@ -48,4 +48,4 @@ scripts: - measure 6 6 7 1 $PROG_HOME/dotty/bench/tests-generated/compiletime-ops/distribute.scala config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/default.yml b/bench/profiles/default.yml index 22ed6d5f31df..5867816217fe 100644 --- a/bench/profiles/default.yml +++ b/bench/profiles/default.yml @@ -11,4 +11,4 @@ includes: config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/empty.yml b/bench/profiles/empty.yml index ac571e64e831..108150d3934e 100644 --- a/bench/profiles/empty.yml +++ b/bench/profiles/empty.yml @@ -1,19 +1,19 @@ charts: - name: "empty class" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/empty-class.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/empty-class.scala lines: - key: empty-class label: bootstrapped - name: "empty object" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/empty-object.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/empty-object.scala lines: - key: empty-object label: bootstrapped - name: "empty file" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/empty-file.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/empty-file.scala lines: - key: empty-file label: bootstrapped @@ -30,4 +30,4 @@ scripts: - measure $PROG_HOME/dotty/tests/bench/empty-file.scala config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/exhaustivity.yml b/bench/profiles/exhaustivity.yml index af6eb4041f6c..47710f7cb39f 100644 --- a/bench/profiles/exhaustivity.yml +++ b/bench/profiles/exhaustivity.yml @@ -1,54 +1,54 @@ charts: - name: "exhaustivity check" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/patmatexhaust.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/patmatexhaust.scala lines: - key: patmatexhaust label: bootstrapped - name: "exhaustivity I" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/exhaustivity-I.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/exhaustivity-I.scala lines: - key: exhaustivity-I label: bootstrapped - name: "exhaustivity S" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/exhaustivity-S.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/exhaustivity-S.scala lines: - key: exhaustivity-S label: bootstrapped - name: "exhaustivity T" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/exhaustivity-T.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/exhaustivity-T.scala lines: - key: exhaustivity-T label: bootstrapped - name: "exhaustivity V" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/exhaustivity-V.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/exhaustivity-V.scala lines: - key: exhaustivity-V label: bootstrapped - name: "exhaustivity MIPS" - url: https://github.com/lampepfl/dotty/blob/main/tests/patmat/i7186.scala + url: https://github.com/scala/scala3/blob/main/tests/patmat/i7186.scala lines: - key: exhaustivity-mips label: bootstrapped - name: "exhaustivity i12241" - url: https://github.com/lampepfl/dotty/blob/main/tests/patmat/i12241.scala + url: https://github.com/scala/scala3/blob/main/tests/patmat/i12241.scala lines: - key: exhaustivity-i12241 label: bootstrapped - name: "exhaustivity i12358" - url: https://github.com/lampepfl/dotty/blob/main/tests/patmat/i12358.scala + url: https://github.com/scala/scala3/blob/main/tests/patmat/i12358.scala lines: - key: exhaustivity-i12358 label: bootstrapped - name: "exhaustivity i13565" - url: https://github.com/lampepfl/dotty/blob/main/tests/pos/i13565.scala + url: https://github.com/scala/scala3/blob/main/tests/pos/i13565.scala lines: - key: exhaustivity-i13565 label: bootstrapped @@ -83,4 +83,4 @@ scripts: - measure 20 40 3 $PROG_HOME/dotty/tests/pos/i13565.scala config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/implicits.yml b/bench/profiles/implicits.yml index 3e944b5be28b..ff7f8c34b872 100644 --- a/bench/profiles/implicits.yml +++ b/bench/profiles/implicits.yml @@ -1,6 +1,6 @@ charts: - name: "implicit cache I" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/implicit_cache.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/implicit_cache.scala lines: - key: implicit-cache label: bootstrapped @@ -8,7 +8,7 @@ charts: label: from tasty - name: "implicit cache II" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/implicitNums.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/implicitNums.scala lines: - key: implicitNums label: bootstrapped @@ -16,13 +16,13 @@ charts: label: from tasty - name: "implicit scope loop" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/implicit-scope-loop.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/implicit-scope-loop.scala lines: - key: implicit-scope-loop label: bootstrapped - name: "inductive implicits" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/inductive-implicits.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/inductive-implicits.scala lines: - key: inductive-implicits label: bootstrapped @@ -48,4 +48,4 @@ scripts: - source $PROG_HOME/dotty/bench/scripts/implicitNums-from-tasty config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/misc.yml b/bench/profiles/misc.yml index 668f8e60c176..7ef168a0eea9 100644 --- a/bench/profiles/misc.yml +++ b/bench/profiles/misc.yml @@ -1,13 +1,13 @@ charts: - name: "issue #1535" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/i1535.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/i1535.scala lines: - key: i1535 label: bootstrapped - name: "issue #1687" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/i1687.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/i1687.scala lines: - key: i1687 label: bootstrapped diff --git a/bench/profiles/projects.yml b/bench/profiles/projects.yml index f1133d180c54..72e506290bad 100644 --- a/bench/profiles/projects.yml +++ b/bench/profiles/projects.yml @@ -41,4 +41,4 @@ scripts: - source $PROG_HOME/dotty/bench/scripts/stdlib213 config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/pull.yml b/bench/profiles/pull.yml index 163d75a8769d..4760e27daf95 100644 --- a/bench/profiles/pull.yml +++ b/bench/profiles/pull.yml @@ -5,4 +5,4 @@ includes: - empty.yml config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/quotes.yml b/bench/profiles/quotes.yml index afd970543aa1..454cd0dc5faa 100644 --- a/bench/profiles/quotes.yml +++ b/bench/profiles/quotes.yml @@ -1,18 +1,18 @@ charts: - name: "Inline a quote" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/power-macro/PowerInlined-1.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/power-macro/PowerInlined-1.scala lines: - key: power-macro-power-inlined-1 label: bootstrapped - name: "Inline 1k quotes" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/power-macro/PowerInlined-1k.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/power-macro/PowerInlined-1k.scala lines: - key: power-macro-power-inlined-1k label: bootstrapped - name: "Quote String interpolation matching" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/string-interpolation-macro/Test.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/string-interpolation-macro/Test.scala lines: - key: quote-string-interpolation-matching label: bootstrapped @@ -29,4 +29,4 @@ scripts: - source $PROG_HOME/dotty/bench/scripts/quote-string-interpolation-matching config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/sbt.yml b/bench/profiles/sbt.yml index 3ab0e43f3db2..653b10381959 100644 --- a/bench/profiles/sbt.yml +++ b/bench/profiles/sbt.yml @@ -12,4 +12,4 @@ scripts: - measure -with-compiler -Yforce-sbt-phases -with-dotty $(find $PROG_HOME/dotty/compiler/src/dotty -name *.scala -o -name *.java) config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/tuples.yml b/bench/profiles/tuples.yml index 5e41ecf7c80d..24bf76f786cc 100644 --- a/bench/profiles/tuples.yml +++ b/bench/profiles/tuples.yml @@ -1,42 +1,42 @@ charts: - name: "Tuple22 creation with Tuple22.apply" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/tuple22-creation-apply.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/tuple22-creation-apply.scala lines: - key: tuple22-creation-apply label: bootstrapped - name: "Tuple22 creation with *:" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/tuple22-creation-cons.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/tuple22-creation-cons.scala lines: - key: tuple22-creation-cons label: bootstrapped - name: "Tuple22.tail" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/tuple22-tails.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/tuple22-tails.scala lines: - key: tuple22-tails label: bootstrapped - name: "Tuple22.apply" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/tuple22-apply.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/tuple22-apply.scala lines: - key: tuple22-apply label: bootstrapped - name: "Tuple22.size" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/tuple22-size.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/tuple22-size.scala lines: - key: tuple22-size label: bootstrapped - name: "Tuple reverse (Runtime)" - url: https://github.com/lampepfl/dotty/blob/main/bench-run/src/main/scala/dotty/tools/benchmarks/tuples/TupleOps.scala#L59 + url: https://github.com/scala/scala3/blob/main/bench-run/src/main/scala/dotty/tools/benchmarks/tuples/TupleOps.scala#L59 lines: - key: tuple-reverse label: bootstrapped - name: "Tuple flatMap (Runtime)" - url: https://github.com/lampepfl/dotty/blob/main/bench-run/src/main/scala/dotty/tools/benchmarks/tuples/TupleOps.scala#L64 + url: https://github.com/scala/scala3/blob/main/bench-run/src/main/scala/dotty/tools/benchmarks/tuples/TupleOps.scala#L64 lines: - key: tuple-flatMap label: bootstrapped @@ -65,4 +65,4 @@ scripts: - measure-run TupleOps.flatMap config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/bench/profiles/typing.yml b/bench/profiles/typing.yml index f6476bca7006..929438cb5a93 100644 --- a/bench/profiles/typing.yml +++ b/bench/profiles/typing.yml @@ -1,6 +1,6 @@ charts: - name: "Find Ref" - url: https://github.com/lampepfl/dotty/blob/main/tests/bench/FindRef.scala + url: https://github.com/scala/scala3/blob/main/tests/bench/FindRef.scala lines: - key: find-ref label: bootstrapped @@ -11,4 +11,4 @@ scripts: - measure $PROG_HOME/dotty/tests/bench/FindRef.scala config: - pr_base_url: "https://github.com/lampepfl/dotty/pull/" + pr_base_url: "https://github.com/scala/scala3/pull/" diff --git a/build.sbt b/build.sbt index 9b6ebc194ea0..1712e80405ae 100644 --- a/build.sbt +++ b/build.sbt @@ -17,6 +17,8 @@ val `scala3-bench-micro` = Build.`scala3-bench-micro` val `scala2-library-bootstrapped` = Build.`scala2-library-bootstrapped` val `scala2-library-tasty` = Build.`scala2-library-tasty` val `scala2-library-tasty-tests` = Build.`scala2-library-tasty-tests` +val `scala2-library-cc` = Build.`scala2-library-cc` +val `scala2-library-cc-tasty` = Build.`scala2-library-cc-tasty` val `tasty-core` = Build.`tasty-core` val `tasty-core-bootstrapped` = Build.`tasty-core-bootstrapped` val `tasty-core-scala2` = Build.`tasty-core-scala2` diff --git a/changelogs/3.4.1-RC1.md b/changelogs/3.4.1-RC1.md new file mode 100644 index 000000000000..f374c6768497 --- /dev/null +++ b/changelogs/3.4.1-RC1.md @@ -0,0 +1,190 @@ +# Highlights of the release + +- Add support for `@deprecatedInheritance` [#19082](https://github.com/lampepfl/dotty/pull/19082) +- Avoid generating given definitions that loop [#19282](https://github.com/lampepfl/dotty/pull/19282) + +# Other changes and fixes + +## Coverage + +- Correctly prettify names in coverage info [#18542](https://github.com/lampepfl/dotty/pull/18542) + +## Desugaring + +- Make apply proxies work with overloaded ctors [#19464](https://github.com/lampepfl/dotty/pull/19464) +- Fix possible crash in Desugar [#19567](https://github.com/lampepfl/dotty/pull/19567) + +## Documentation + +- Update `private[this]` deprecation warning and documentation [#19393](https://github.com/lampepfl/dotty/pull/19393) + +## Erasure + +- Make eraseInfo work for classes with EmptyScopes [#19550](https://github.com/lampepfl/dotty/pull/19550) + +## Exports + +- Do not propagate `@tailrec` to exported methods [#19509](https://github.com/lampepfl/dotty/pull/19509) +- Fix retained flags in exports [#19636](https://github.com/lampepfl/dotty/pull/19636) + +## GADTs + +- Only cache base types when gadt state is empty [#19562](https://github.com/lampepfl/dotty/pull/19562) + +## Implicits + +- Run CheckStatic after UncacheGivenAliases [#19318](https://github.com/lampepfl/dotty/pull/19318) +- Add tests to verify that crash is fixed elsewhere. Fixes #19328 [#19329](https://github.com/lampepfl/dotty/pull/19329) +- Don't search for implicit conversions to NoType [#19563](https://github.com/lampepfl/dotty/pull/19563) +- Instantiate argument type vars before implicit search [#19096](https://github.com/lampepfl/dotty/pull/19096) + +## Java Interop + +- Classfile reader: handle JDK 9+ constant types in constant pool [#19533](https://github.com/lampepfl/dotty/pull/19533) + +## Linting + +- Make fatal warnings not fail compilation early & aggregate warns [#19245](https://github.com/lampepfl/dotty/pull/19245) + +## Macro Annotations + +- Check and enter missing symbols in MacroAnnotations only for definitions [#19579](https://github.com/lampepfl/dotty/pull/19579) + +## Match Types + +- Normalize MatchAlias in unrollTupleTypes [#19565](https://github.com/lampepfl/dotty/pull/19565) +- Fix #19445: Remove too-strict test in match type matching. [#19511](https://github.com/lampepfl/dotty/pull/19511) + +## Opaque Types + +- Fix problems with cycle checks [#19453](https://github.com/lampepfl/dotty/pull/19453) + +## Parser + +- Fix(#18265): crash on extension method without type nor RHS [#18743](https://github.com/lampepfl/dotty/pull/18743) +- Warn when @volatile is used on vals [#19462](https://github.com/lampepfl/dotty/pull/19462) +- Fix(#16459) xml parse regression [#19531](https://github.com/lampepfl/dotty/pull/19531) + +## Pattern Matching + +- Fix false unreachable due to opaqueness [#19368](https://github.com/lampepfl/dotty/pull/19368) +- Improve recursive decompose prefix fix [#19375](https://github.com/lampepfl/dotty/pull/19375) +- Allow constraining a parameter to Nothing [#19397](https://github.com/lampepfl/dotty/pull/19397) +- Add a test case, proving i15661 is fixed [#19432](https://github.com/lampepfl/dotty/pull/19432) + +## Presentation Compiler + +- Improvement: Support completions for implicit classes [#19314](https://github.com/lampepfl/dotty/pull/19314) +- Chore: Backport changes from Metals [#19410](https://github.com/lampepfl/dotty/pull/19410) +- Fix goto-def on exported forwarders [#19494](https://github.com/lampepfl/dotty/pull/19494) +- Backport pc changes from metals [#19617](https://github.com/lampepfl/dotty/pull/19617) +- Chore: Backport changes from Metals [#19592](https://github.com/lampepfl/dotty/pull/19592) +- Use comma counting for all signature help types [#19520](https://github.com/lampepfl/dotty/pull/19520) +- Make PC more resilient to crashes [#19488](https://github.com/lampepfl/dotty/pull/19488) +- Make order of renames and missing imports deterministic [#19468](https://github.com/lampepfl/dotty/pull/19468) +- Chore: backport changes from metals [#19452](https://github.com/lampepfl/dotty/pull/19452) +- Improve signature help by more stable position calculation + better named arg support [#19214](https://github.com/lampepfl/dotty/pull/19214) +- Instantiate Type Vars in completion labels of extension methods [#18914](https://github.com/lampepfl/dotty/pull/18914) + +## Quotes + +- Only evaluate transparent inline unapply once [#19380](https://github.com/lampepfl/dotty/pull/19380) +- Update `staging.Compiler.make` documentation [#19428](https://github.com/lampepfl/dotty/pull/19428) +- Error instead of StaleSymbol crash for certain cyclic macro dependencies [#19549](https://github.com/lampepfl/dotty/pull/19549) +- Refine handling of StaleSymbol type errors [#19605](https://github.com/lampepfl/dotty/pull/19605) +- Fix module symbol recovery from `NoClassDefFoundError` [#19645](https://github.com/lampepfl/dotty/pull/19645) +- Fix HOAS pattern example and error message [#19655](https://github.com/lampepfl/dotty/pull/19655) +- Set the correct type when copying reflect Inlined trees [#19409](https://github.com/lampepfl/dotty/pull/19409) + +## Reporting + +- Don't explain erroneous bounds [#19338](https://github.com/lampepfl/dotty/pull/19338) +- Better error diagnostics for cyclic references [#19408](https://github.com/lampepfl/dotty/pull/19408) +- Properly identify empty bounds in error message [#19310](https://github.com/lampepfl/dotty/pull/19310) + +## Scala-JS + +- Fix #19528: Actually remove Dynamic from interfaces of native JS classes. [#19536](https://github.com/lampepfl/dotty/pull/19536) +- Consider static and non-static methods as non-double def [#19400](https://github.com/lampepfl/dotty/pull/19400) + +## Scaladoc + +- Scaladoc - add option for dynamic side menu [#19337](https://github.com/lampepfl/dotty/pull/19337) +- Scaladoc: Fix "case case Foo" in enum's cases [#19519](https://github.com/lampepfl/dotty/pull/19519) +- Fix(#19377): show inherited abstract members in dedicated section [#19552](https://github.com/lampepfl/dotty/pull/19552) +- Jsoup: 1.14.3 → 1.17.2 [#19564](https://github.com/lampepfl/dotty/pull/19564) +- Extend copyright into 2024 [#19367](https://github.com/lampepfl/dotty/pull/19367) + +## Tooling + +- Prioritize TASTy files over classfiles on classpath aggregation [#19431](https://github.com/lampepfl/dotty/pull/19431) + +## Transform + +- Fix purity check for val inside of object [#19598](https://github.com/lampepfl/dotty/pull/19598) +- Drop special treatment of function types in overloading resolution [#19654](https://github.com/lampepfl/dotty/pull/19654) +- Add checks for the consistency of the parents in TreeChecker [#18935](https://github.com/lampepfl/dotty/pull/18935) + +## Type Inference + +- More careful type variable instance improvements [#19659](https://github.com/lampepfl/dotty/pull/19659) + +## Typer + +- Reject wildcard types in using clauses [#19459](https://github.com/lampepfl/dotty/pull/19459) +- Don't leave underspecified SAM types in the code [#19461](https://github.com/lampepfl/dotty/pull/19461) +- Also compute base classes of wildcardTypes [#19465](https://github.com/lampepfl/dotty/pull/19465) +- Fix(#15784): ident rule for pat match was too strict [#19501](https://github.com/lampepfl/dotty/pull/19501) +- Heal occurrences of => T between ElimByName and Erasure [#19558](https://github.com/lampepfl/dotty/pull/19558) +- Fix(#i18645): overload ext method body in braces didn't compile [#19651](https://github.com/lampepfl/dotty/pull/19651) +- Fix #19202: Passing NotNullInfos to a mutable field of a Completer [#19463](https://github.com/lampepfl/dotty/pull/19463) +- Fix Java record problems (#19578) and (#19386) [#19583](https://github.com/lampepfl/dotty/pull/19583) +- Improve when deprecation warnings are emitted [#19621](https://github.com/lampepfl/dotty/pull/19621) +- Space: Replace showType & make Space Showable [#19370](https://github.com/lampepfl/dotty/pull/19370) + + +# Contributors + +Thank you to all the contributors who made this release possible 🎉 + +According to `git shortlog -sn --no-merges 3.4.0..3.4.1-RC1` these are: + +``` + 53 Martin Odersky + 53 Nicolas Stucki + 20 Dale Wijnand + 11 Szymon Rodziewicz + 11 i10416 + 7 noti0na1 + 6 Yilin Wei + 4 Hamza REMMAL + 4 Jędrzej Rochala + 3 Eugene Flesselle + 3 Paweł Marks + 3 Seth Tisue + 2 Florian3k + 2 Hamza Remmal + 2 Jan Chyb + 2 Katarzyna Marek + 2 Sébastien Doeraene + 2 Tomasz Godzik + 2 dependabot[bot] + 1 Bersier + 1 Fabián Heredia Montiel + 1 Jakub Ciesluk + 1 Jakub Cieśluk + 1 Kacper Korban + 1 Kenji Yoshida + 1 Mehdi Alaoui + 1 Nikita Gazarov + 1 Oron Port + 1 Pascal Weisenburger + 1 Philippus Baalman + 1 Quentin Bernet + 1 Som Snytt + 1 Wojciech Mazur + 1 Yichen Xu + 1 aherlihy + 1 rochala + +``` diff --git a/changelogs/3.4.1-RC2.md b/changelogs/3.4.1-RC2.md new file mode 100644 index 000000000000..7267d2339c35 --- /dev/null +++ b/changelogs/3.4.1-RC2.md @@ -0,0 +1,18 @@ +# Backported fixes + +- Adjust owner in Interactive.contextOfPath causing crash in ImplicitSearch [#19875](https://github.com/lampepfl/dotty/pull/19875) +- Add GADT symbols when typing typing-ahead lambda bodies[#19644](https://github.com/lampepfl/dotty/pull/19644) + +# Contributors + +Thank you to all the contributors who made this release possible 🎉 + +According to `git shortlog -sn --no-merges 3.4.1-RC1..3.4.1-RC2` these are: + +``` + 4 Hamza REMMAL + 2 Dale Wijnand + 2 Paweł Marks + 1 Jędrzej Rochala + +``` diff --git a/changelogs/3.4.1.md b/changelogs/3.4.1.md new file mode 100644 index 000000000000..920c78f61e8f --- /dev/null +++ b/changelogs/3.4.1.md @@ -0,0 +1,192 @@ +# Highlights of the release + +- Add support for `@deprecatedInheritance` [#19082](https://github.com/lampepfl/dotty/pull/19082) +- Avoid generating given definitions that loop [#19282](https://github.com/lampepfl/dotty/pull/19282) + +# Other changes and fixes + +## Coverage + +- Correctly prettify names in coverage info [#18542](https://github.com/lampepfl/dotty/pull/18542) + +## Desugaring + +- Make apply proxies work with overloaded ctors [#19464](https://github.com/lampepfl/dotty/pull/19464) +- Fix possible crash in Desugar [#19567](https://github.com/lampepfl/dotty/pull/19567) + +## Documentation + +- Update `private[this]` deprecation warning and documentation [#19393](https://github.com/lampepfl/dotty/pull/19393) + +## Erasure + +- Make eraseInfo work for classes with EmptyScopes [#19550](https://github.com/lampepfl/dotty/pull/19550) + +## Exports + +- Do not propagate `@tailrec` to exported methods [#19509](https://github.com/lampepfl/dotty/pull/19509) +- Fix retained flags in exports [#19636](https://github.com/lampepfl/dotty/pull/19636) + +## GADTs + +- Only cache base types when gadt state is empty [#19562](https://github.com/lampepfl/dotty/pull/19562) +- Add GADT symbols when typing typing-ahead lambda bodies[#19644](https://github.com/lampepfl/dotty/pull/19644) + +## Implicits + +- Run CheckStatic after UncacheGivenAliases [#19318](https://github.com/lampepfl/dotty/pull/19318) +- Add tests to verify that crash is fixed elsewhere. Fixes #19328 [#19329](https://github.com/lampepfl/dotty/pull/19329) +- Don't search for implicit conversions to NoType [#19563](https://github.com/lampepfl/dotty/pull/19563) +- Instantiate argument type vars before implicit search [#19096](https://github.com/lampepfl/dotty/pull/19096) +- Adjust owner in Interactive.contextOfPath causing crash in ImplicitSearch [#19875](https://github.com/lampepfl/dotty/pull/19875) + +## Java Interop + +- Classfile reader: handle JDK 9+ constant types in constant pool [#19533](https://github.com/lampepfl/dotty/pull/19533) + +## Linting + +- Make fatal warnings not fail compilation early & aggregate warns [#19245](https://github.com/lampepfl/dotty/pull/19245) + +## Macro Annotations + +- Check and enter missing symbols in MacroAnnotations only for definitions [#19579](https://github.com/lampepfl/dotty/pull/19579) + +## Match Types + +- Normalize MatchAlias in unrollTupleTypes [#19565](https://github.com/lampepfl/dotty/pull/19565) +- Fix #19445: Remove too-strict test in match type matching. [#19511](https://github.com/lampepfl/dotty/pull/19511) + +## Opaque Types + +- Fix problems with cycle checks [#19453](https://github.com/lampepfl/dotty/pull/19453) + +## Parser + +- Fix(#18265): crash on extension method without type nor RHS [#18743](https://github.com/lampepfl/dotty/pull/18743) +- Warn when @volatile is used on vals [#19462](https://github.com/lampepfl/dotty/pull/19462) +- Fix(#16459) xml parse regression [#19531](https://github.com/lampepfl/dotty/pull/19531) + +## Pattern Matching + +- Fix false unreachable due to opaqueness [#19368](https://github.com/lampepfl/dotty/pull/19368) +- Improve recursive decompose prefix fix [#19375](https://github.com/lampepfl/dotty/pull/19375) +- Allow constraining a parameter to Nothing [#19397](https://github.com/lampepfl/dotty/pull/19397) +- Add a test case, proving i15661 is fixed [#19432](https://github.com/lampepfl/dotty/pull/19432) + +## Presentation Compiler + +- Improvement: Support completions for implicit classes [#19314](https://github.com/lampepfl/dotty/pull/19314) +- Chore: Backport changes from Metals [#19410](https://github.com/lampepfl/dotty/pull/19410) +- Fix goto-def on exported forwarders [#19494](https://github.com/lampepfl/dotty/pull/19494) +- Backport pc changes from metals [#19617](https://github.com/lampepfl/dotty/pull/19617) +- Chore: Backport changes from Metals [#19592](https://github.com/lampepfl/dotty/pull/19592) +- Use comma counting for all signature help types [#19520](https://github.com/lampepfl/dotty/pull/19520) +- Make PC more resilient to crashes [#19488](https://github.com/lampepfl/dotty/pull/19488) +- Make order of renames and missing imports deterministic [#19468](https://github.com/lampepfl/dotty/pull/19468) +- Chore: backport changes from metals [#19452](https://github.com/lampepfl/dotty/pull/19452) +- Improve signature help by more stable position calculation + better named arg support [#19214](https://github.com/lampepfl/dotty/pull/19214) +- Instantiate Type Vars in completion labels of extension methods [#18914](https://github.com/lampepfl/dotty/pull/18914) + +## Quotes + +- Only evaluate transparent inline unapply once [#19380](https://github.com/lampepfl/dotty/pull/19380) +- Update `staging.Compiler.make` documentation [#19428](https://github.com/lampepfl/dotty/pull/19428) +- Error instead of StaleSymbol crash for certain cyclic macro dependencies [#19549](https://github.com/lampepfl/dotty/pull/19549) +- Refine handling of StaleSymbol type errors [#19605](https://github.com/lampepfl/dotty/pull/19605) +- Fix module symbol recovery from `NoClassDefFoundError` [#19645](https://github.com/lampepfl/dotty/pull/19645) +- Fix HOAS pattern example and error message [#19655](https://github.com/lampepfl/dotty/pull/19655) +- Set the correct type when copying reflect Inlined trees [#19409](https://github.com/lampepfl/dotty/pull/19409) + +## Reporting + +- Don't explain erroneous bounds [#19338](https://github.com/lampepfl/dotty/pull/19338) +- Better error diagnostics for cyclic references [#19408](https://github.com/lampepfl/dotty/pull/19408) +- Properly identify empty bounds in error message [#19310](https://github.com/lampepfl/dotty/pull/19310) + +## Scala-JS + +- Fix #19528: Actually remove Dynamic from interfaces of native JS classes. [#19536](https://github.com/lampepfl/dotty/pull/19536) +- Consider static and non-static methods as non-double def [#19400](https://github.com/lampepfl/dotty/pull/19400) + +## Scaladoc + +- Scaladoc - add option for dynamic side menu [#19337](https://github.com/lampepfl/dotty/pull/19337) +- Scaladoc: Fix "case case Foo" in enum's cases [#19519](https://github.com/lampepfl/dotty/pull/19519) +- Fix(#19377): show inherited abstract members in dedicated section [#19552](https://github.com/lampepfl/dotty/pull/19552) +- Jsoup: 1.14.3 → 1.17.2 [#19564](https://github.com/lampepfl/dotty/pull/19564) +- Extend copyright into 2024 [#19367](https://github.com/lampepfl/dotty/pull/19367) + +## Tooling + +- Prioritize TASTy files over classfiles on classpath aggregation [#19431](https://github.com/lampepfl/dotty/pull/19431) + +## Transform + +- Fix purity check for val inside of object [#19598](https://github.com/lampepfl/dotty/pull/19598) +- Drop special treatment of function types in overloading resolution [#19654](https://github.com/lampepfl/dotty/pull/19654) +- Add checks for the consistency of the parents in TreeChecker [#18935](https://github.com/lampepfl/dotty/pull/18935) + +## Type Inference + +- More careful type variable instance improvements [#19659](https://github.com/lampepfl/dotty/pull/19659) + +## Typer + +- Reject wildcard types in using clauses [#19459](https://github.com/lampepfl/dotty/pull/19459) +- Don't leave underspecified SAM types in the code [#19461](https://github.com/lampepfl/dotty/pull/19461) +- Also compute base classes of wildcardTypes [#19465](https://github.com/lampepfl/dotty/pull/19465) +- Fix(#15784): ident rule for pat match was too strict [#19501](https://github.com/lampepfl/dotty/pull/19501) +- Heal occurrences of => T between ElimByName and Erasure [#19558](https://github.com/lampepfl/dotty/pull/19558) +- Fix(#i18645): overload ext method body in braces didn't compile [#19651](https://github.com/lampepfl/dotty/pull/19651) +- Fix #19202: Passing NotNullInfos to a mutable field of a Completer [#19463](https://github.com/lampepfl/dotty/pull/19463) +- Fix Java record problems (#19578) and (#19386) [#19583](https://github.com/lampepfl/dotty/pull/19583) +- Improve when deprecation warnings are emitted [#19621](https://github.com/lampepfl/dotty/pull/19621) +- Space: Replace showType & make Space Showable [#19370](https://github.com/lampepfl/dotty/pull/19370) + + +# Contributors + +Thank you to all the contributors who made this release possible 🎉 + +According to `git shortlog -sn --no-merges 3.4.0..3.4.1` these are: + +``` + 53 Martin Odersky + 53 Nicolas Stucki + 22 Dale Wijnand + 11 Szymon Rodziewicz + 11 i10416 + 8 Hamza REMMAL + 7 Paweł Marks + 7 noti0na1 + 6 Yilin Wei + 5 Jędrzej Rochala + 3 Eugene Flesselle + 3 Seth Tisue + 2 Florian3k + 2 Hamza Remmal + 2 Jan Chyb + 2 Katarzyna Marek + 2 Sébastien Doeraene + 2 Tomasz Godzik + 2 dependabot[bot] + 1 Bersier + 1 Fabián Heredia Montiel + 1 Jakub Ciesluk + 1 Jakub Cieśluk + 1 Kacper Korban + 1 Kenji Yoshida + 1 Mehdi Alaoui + 1 Nikita Gazarov + 1 Oron Port + 1 Pascal Weisenburger + 1 Philippus Baalman + 1 Quentin Bernet + 1 Som Snytt + 1 Wojciech Mazur + 1 Yichen Xu + 1 aherlihy + 1 rochala + +``` diff --git a/community-build/community-projects/libretto b/community-build/community-projects/libretto index d229f3ccb9c4..64de079d5a7c 160000 --- a/community-build/community-projects/libretto +++ b/community-build/community-projects/libretto @@ -1 +1 @@ -Subproject commit d229f3ccb9c49aa3b0fef1b3f7425e986155cc97 +Subproject commit 64de079d5a7cf3efe3345421ac3e375a718f57f7 diff --git a/community-build/src/scala/dotty/communitybuild/projects.scala b/community-build/src/scala/dotty/communitybuild/projects.scala index 767667b491ce..ae030dc66336 100644 --- a/community-build/src/scala/dotty/communitybuild/projects.scala +++ b/community-build/src/scala/dotty/communitybuild/projects.scala @@ -140,7 +140,7 @@ final case class SbtCommunityProject( case Some(ivyHome) => List(s"-Dsbt.ivy.home=$ivyHome") case _ => Nil extraSbtArgs ++ sbtProps ++ List( - "-sbt-version", "1.9.3", + "-sbt-version", "1.9.7", "-Dsbt.supershell=false", s"-Ddotty.communitybuild.dir=$communitybuildDir", s"--addPluginSbtFile=$sbtPluginFilePath" diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 2ad58fea4cd1..385521e2785f 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -754,7 +754,7 @@ trait BCodeHelpers extends BCodeIdiomatic { case tp => report.warning( s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + - "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") + "If possible, please file a bug on https://github.com/scala/scala3/issues") tp match { case tp: ThisType if tp.cls == defn.ArrayClass => ObjectRef.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test @@ -795,7 +795,7 @@ trait BCodeHelpers extends BCodeIdiomatic { report.error( em"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName} |signature: $sig - |if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues + |if this is reproducible, please report bug at https://github.com/scala/scala3/issues """, sym.sourcePos) throw ex } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 0ab9ed85b6cf..394700c2898e 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -191,7 +191,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // Should we do this transformation earlier, say in Constructors? Or would that just cause // pain for scala-{js, native}? // - // @sjrd (https://github.com/lampepfl/dotty/pull/9181#discussion_r457458205): + // @sjrd (https://github.com/scala/scala3/pull/9181#discussion_r457458205): // moving that before the back-end would make things significantly more complicated for // Scala.js and Native. Both have a first-class concept of ModuleClass, and encode the // singleton pattern of MODULE$ in a completely different way. In the Scala.js IR, there @@ -202,7 +202,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // TODO: remove `!f.name.is(LazyBitMapName)` once we change lazy val encoding - // https://github.com/lampepfl/dotty/issues/7140 + // https://github.com/scala/scala3/issues/7140 // // Lazy val encoding assumes bitmap fields are non-static // diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 37045bda17ec..8016c2bfc209 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -126,7 +126,7 @@ object DottyBackendInterface { * See also `genPlainClass` in `BCodeSkelBuilder.scala`. * * TODO: remove the special handing of `LazyBitMapName` once we swtich to - * the new lazy val encoding: https://github.com/lampepfl/dotty/issues/7140 + * the new lazy val encoding: https://github.com/scala/scala3/issues/7140 */ def isStaticModuleField(using Context): Boolean = sym.owner.isStaticModuleClass && sym.isField && !sym.name.is(LazyBitMapName) && !sym.name.is(LazyLocalName) diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 54af9f8dd088..5b0d37d28a9b 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -643,7 +643,7 @@ class JSCodeGen()(using genCtx: Context) { kind, None, superClass, - genClassInterfaces(sym, forJSClass = false), + genClassInterfaces(sym, forJSClass = true), None, jsNativeLoadSpec, Nil, @@ -793,6 +793,9 @@ class JSCodeGen()(using genCtx: Context) { name.name }.toSet + val staticNames = moduleClass.companionClass.info.allMembers + .collect { case d if d.name.isTermName && d.symbol.isScalaStatic => d.name }.toSet + val members = { moduleClass.info.membersBasedOnFlags(required = Flags.Method, excluded = Flags.ExcludedForwarder).map(_.symbol) @@ -815,6 +818,7 @@ class JSCodeGen()(using genCtx: Context) { || hasAccessBoundary || isOfJLObject || m.hasAnnotation(jsdefn.JSNativeAnnot) || isDefaultParamOfJSNativeDef // #4557 + || staticNames(m.name) } val forwarders = for { @@ -4769,7 +4773,7 @@ class JSCodeGen()(using genCtx: Context) { } private def isMethodStaticInIR(sym: Symbol): Boolean = - sym.is(JavaStatic) + sym.is(JavaStatic) || sym.isScalaStatic /** Generate a Class[_] value (e.g. coming from classOf[T]) */ private def genClassConstant(tpe: Type)(implicit pos: Position): js.Tree = diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index aaa14a052936..290df761d117 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -64,7 +64,6 @@ class Compiler { new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars new ElimPackagePrefixes, // Eliminate references to package prefixes in Select nodes new CookComments, // Cook the comments: expand variables, doc, etc. - new CheckStatic, // Check restrictions that apply to @static members new CheckLoopingImplicits, // Check that implicit defs do not call themselves in an infinite loop new BetaReduce, // Reduce closure applications new InlineVals, // Check right hand-sides of an `inline val`s @@ -76,6 +75,7 @@ class Compiler { List(new ProtectedAccessors, // Add accessors for protected members new ExtensionMethods, // Expand methods of value classes with extension methods new UncacheGivenAliases, // Avoid caching RHS of simple parameterless given aliases + new CheckStatic, // Check restrictions that apply to @static members new ElimByName, // Map by-name parameters to functions new HoistSuperArgs, // Hoist complex arguments of supercalls to enclosing scope new ForwardDepChecks, // Check that there are no forward references to local vals diff --git a/compiler/src/dotty/tools/dotc/Driver.scala b/compiler/src/dotty/tools/dotc/Driver.scala index 4207baa57470..196752aceb29 100644 --- a/compiler/src/dotty/tools/dotc/Driver.scala +++ b/compiler/src/dotty/tools/dotc/Driver.scala @@ -54,8 +54,7 @@ class Driver { if (ctx.settings.XprintSuspension.value) report.echo(i"compiling suspended $suspendedUnits%, %") val run1 = compiler.newRun - for unit <- suspendedUnits do unit.suspended = false - run1.compileUnits(suspendedUnits) + run1.compileSuspendedUnits(suspendedUnits) finish(compiler, run1)(using MacroClassLoader.init(ctx.fresh)) protected def initCtx: Context = (new ContextBase).initialCtx @@ -127,7 +126,7 @@ class Driver { * The trade-off is that you can only pass a SimpleReporter to this method * and not a normal Reporter which is more powerful. * - * Usage example: [[https://github.com/lampepfl/dotty/tree/master/compiler/test/dotty/tools/dotc/InterfaceEntryPointTest.scala]] + * Usage example: [[https://github.com/scala/scala3/tree/master/compiler/test/dotty/tools/dotc/InterfaceEntryPointTest.scala]] * * @param args Arguments to pass to the compiler. * @param simple Used to log errors, warnings, and info messages. @@ -144,7 +143,7 @@ class Driver { /** Principal entry point to the compiler. * - * Usage example: [[https://github.com/lampepfl/dotty/tree/master/compiler/test/dotty/tools/dotc/EntryPointsTest.scala.disabled]] + * Usage example: [[https://github.com/scala/scala3/tree/master/compiler/test/dotty/tools/dotc/EntryPointsTest.scala.disabled]] * in method `runCompiler` * * @param args Arguments to pass to the compiler. @@ -183,7 +182,7 @@ class Driver { * the other overloads cannot be overridden, instead you * should override this one which they call internally. * - * Usage example: [[https://github.com/lampepfl/dotty/tree/master/compiler/test/dotty/tools/dotc/EntryPointsTest.scala.disabled]] + * Usage example: [[https://github.com/scala/scala3/tree/master/compiler/test/dotty/tools/dotc/EntryPointsTest.scala.disabled]] * in method `runCompilerWithContext` * * @param args Arguments to pass to the compiler. diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index bec1c89d7216..4e0b7d09e95f 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -343,9 +343,12 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint runCtx.setProfiler(Profiler()) unfusedPhases.foreach(_.initContext(runCtx)) val fusedPhases = runCtx.base.allPhases + if ctx.settings.explainCyclic.value then + runCtx.setProperty(CyclicReference.Trace, new CyclicReference.Trace()) runCtx.withProgressCallback: cb => _progress = Progress(cb, this, fusedPhases.map(_.traversals).sum) runPhases(allPhases = fusedPhases)(using runCtx) + ctx.reporter.finalizeReporting() if (!ctx.reporter.hasErrors) Rewrites.writeBack() suppressions.runFinished(hasErrors = ctx.reporter.hasErrors) @@ -356,6 +359,17 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint compiling = false } + private var myCompilingSuspended: Boolean = false + + /** Is this run started via a compilingSuspended? */ + def isCompilingSuspended: Boolean = myCompilingSuspended + + /** Compile units `us` which were suspended in a previous run */ + def compileSuspendedUnits(us: List[CompilationUnit]): Unit = + myCompilingSuspended = true + for unit <- us do unit.suspended = false + compileUnits(us) + /** Enter top-level definitions of classes and objects contained in source file `file`. * The newly added symbols replace any previously entered symbols. * If `typeCheck = true`, also run typer on the compilation unit, and set diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 36f2d593de1c..9591bc5a93f0 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1602,15 +1602,17 @@ object desugar { * skipping elements that are not convertible. */ def patternsToParams(elems: List[Tree])(using Context): List[ValDef] = - def toParam(elem: Tree, tpt: Tree): Tree = + def toParam(elem: Tree, tpt: Tree, span: Span): Tree = elem match - case Annotated(elem1, _) => toParam(elem1, tpt) - case Typed(elem1, tpt1) => toParam(elem1, tpt1) - case Ident(id: TermName) => ValDef(id, tpt, EmptyTree).withFlags(Param) + case Annotated(elem1, _) => toParam(elem1, tpt, span) + case Typed(elem1, tpt1) => toParam(elem1, tpt1, span) + case Ident(id: TermName) => ValDef(id, tpt, EmptyTree).withFlags(Param).withSpan(span) case _ => EmptyTree - elems.map(param => toParam(param, TypeTree()).withSpan(param.span)).collect { - case vd: ValDef => vd - } + elems + .map: param => + toParam(param, TypeTree(), param.span) + .collect: + case vd: ValDef => vd def makeContextualFunction(formals: List[Tree], paramNamesOrNil: List[TermName], body: Tree, erasedParams: List[Boolean])(using Context): Function = { val mods = Given diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index 5ded0e1262e4..28d3ef6daaef 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -578,8 +578,9 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => sym.owner.isPrimitiveValueClass || sym.owner == defn.StringClass || defn.pureMethods.contains(sym) + tree.tpe.isInstanceOf[ConstantType] && tree.symbol != NoSymbol && isKnownPureOp(tree.symbol) // A constant expression with pure arguments is pure. - || fn.symbol.isStableMember && !fn.symbol.is(Lazy) // constructors of no-inits classes are stable + || fn.symbol.isStableMember && fn.symbol.isConstructor // constructors of no-inits classes are stable /** The purity level of this reference. * @return diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index 4ec41b95a90b..c64b636648ee 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -1501,7 +1501,7 @@ object Trees { * It ensures that the source is correct, and that the local context is used if * that's necessary for transforming the whole tree. * TODO: ensure transform is always called with the correct context as argument - * @see https://github.com/lampepfl/dotty/pull/13880#discussion_r836395977 + * @see https://github.com/scala/scala3/pull/13880#discussion_r836395977 */ def transformCtx(tree: Tree)(using Context): Context = val sourced = diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 44fa4e9b22fd..71b85d97a187 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -118,13 +118,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { * otherwise specified). */ def Closure(meth: TermSymbol, rhsFn: List[List[Tree]] => Tree, targs: List[Tree] = Nil, targetType: Type = NoType)(using Context): Block = { - val targetTpt = if (targetType.exists) TypeTree(targetType) else EmptyTree + val targetTpt = if (targetType.exists) TypeTree(targetType, inferred = true) else EmptyTree val call = if (targs.isEmpty) Ident(TermRef(NoPrefix, meth)) else TypeApply(Ident(TermRef(NoPrefix, meth)), targs) - Block( - DefDef(meth, rhsFn) :: Nil, - Closure(Nil, call, targetTpt)) + var mdef0 = DefDef(meth, rhsFn) + val mdef = cpy.DefDef(mdef0)(tpt = TypeTree(mdef0.tpt.tpe, inferred = true)) + Block(mdef :: Nil, Closure(Nil, call, targetTpt)) } /** A closure whose anonymous function has the given method type */ @@ -1142,6 +1142,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { buf.toList } + def collectSubTrees[A](f: PartialFunction[Tree, A])(using Context): List[A] = + val buf = mutable.ListBuffer[A]() + foreachSubTree(f.runWith(buf += _)(_)) + buf.toList + /** Set this tree as the `defTree` of its symbol and return this tree */ def setDefTree(using Context): ThisTree = { val sym = tree.symbol diff --git a/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala b/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala index a0d874007728..7c75ed833945 100644 --- a/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala +++ b/compiler/src/dotty/tools/dotc/cc/CaptureOps.scala @@ -98,10 +98,14 @@ extension (tree: Tree) tree.putAttachment(Captures, refs) refs - /** The arguments of a @retains or @retainsByName annotation */ + /** The arguments of a @retains, @retainsCap or @retainsByName annotation */ def retainedElems(using Context): List[Tree] = tree match - case Apply(_, Typed(SeqLiteral(elems, _), _) :: Nil) => elems - case _ => Nil + case Apply(_, Typed(SeqLiteral(elems, _), _) :: Nil) => + elems + case _ => + if tree.symbol.maybeOwner == defn.RetainsCapAnnot + then ref(defn.captureRoot.termRef) :: Nil + else Nil extension (tp: Type) @@ -207,7 +211,7 @@ extension (tp: Type) def dropAllRetains(using Context): Type = // TODO we should drop retains from inferred types before unpickling val tm = new TypeMap: def apply(t: Type) = t match - case AnnotatedType(parent, annot) if annot.symbol == defn.RetainsAnnot => + case AnnotatedType(parent, annot) if annot.symbol.isRetains => apply(parent) case _ => mapOver(t) @@ -220,9 +224,31 @@ extension (tp: Type) * type of `x`. If `x` and `y` are different variables then `{x*}` and `{y*}` * are unrelated. */ - def reach(using Context): CaptureRef = - assert(tp.isTrackableRef) - AnnotatedType(tp, Annotation(defn.ReachCapabilityAnnot, util.Spans.NoSpan)) + def reach(using Context): CaptureRef = tp match + case tp: CaptureRef if tp.isTrackableRef => + if tp.isReach then tp else ReachCapability(tp) + + /** If `x` is a capture ref, its maybe capability `x?`, represented internally + * as `x @maybeCapability`. `x?` stands for a capability `x` that might or might + * not be part of a capture set. We have `{} <: {x?} <: {x}`. Maybe capabilities + * cannot be propagated between sets. If `a <: b` and `a` acquires `x?` then + * `x` is propagated to `b` as a conservative approximation. + * + * Maybe capabilities should only arise for capture sets that appear in invariant + * position in their surrounding type. They are similar to TypeBunds types, but + * restricted to capture sets. For instance, + * + * Array[C^{x?}] + * + * should be morally equivalent to + * + * Array[_ >: C^{} <: C^{x}] + * + * but it has fewer issues with type inference. + */ + def maybe(using Context): CaptureRef = tp match + case tp: CaptureRef if tp.isTrackableRef => + if tp.isMaybe then tp else MaybeCapability(tp) /** If `ref` is a trackable capture ref, and `tp` has only covariant occurrences of a * universal capture set, replace all these occurrences by `{ref*}`. This implements @@ -236,19 +262,19 @@ extension (tp: Type) * (2) all covariant occurrences of cap replaced by `x*`, provided there * are no occurrences in `T` at other variances. (1) is standard, whereas * (2) is new. - * + * * For (2), multiple-flipped covariant occurrences of cap won't be replaced. * In other words, * * - For xs: List[File^] ==> List[File^{xs*}], the cap is replaced; * - while f: [R] -> (op: File^ => R) -> R remains unchanged. - * + * * Without this restriction, the signature of functions like withFile: - * + * * (path: String) -> [R] -> (op: File^ => R) -> R * * could be refined to - * + * * (path: String) -> [R] -> (op: File^{withFile*} => R) -> R * * which is clearly unsound. @@ -315,8 +341,25 @@ extension (cls: ClassSymbol) // and err on the side of impure. && selfType.exists && selfType.captureSet.isAlwaysEmpty + def baseClassHasExplicitSelfType(using Context): Boolean = + cls.baseClasses.exists: bc => + bc.is(CaptureChecked) && bc.givenSelfType.exists + + def matchesExplicitRefsInBaseClass(refs: CaptureSet)(using Context): Boolean = + cls.baseClasses.tail.exists: bc => + val selfType = bc.givenSelfType + bc.is(CaptureChecked) && selfType.exists && selfType.captureSet.elems == refs.elems + extension (sym: Symbol) + /** This symbol is one of `retains` or `retainsCap` */ + def isRetains(using Context): Boolean = + sym == defn.RetainsAnnot || sym == defn.RetainsCapAnnot + + /** This symbol is one of `retains`, `retainsCap`, or`retainsByName` */ + def isRetainsLike(using Context): Boolean = + isRetains || sym == defn.RetainsByNameAnnot + /** A class is pure if: * - one its base types has an explicitly declared self type with an empty capture set * - or it is a value class @@ -410,12 +453,21 @@ object ReachCapabilityApply: case Apply(reach, arg :: Nil) if reach.symbol == defn.Caps_reachCapability => Some(arg) case _ => None +class AnnotatedCapability(annot: Context ?=> ClassSymbol): + def apply(tp: Type)(using Context) = + AnnotatedType(tp, Annotation(annot, util.Spans.NoSpan)) + def unapply(tree: AnnotatedType)(using Context): Option[SingletonCaptureRef] = tree match + case AnnotatedType(parent: SingletonCaptureRef, ann) if ann.symbol == annot => Some(parent) + case _ => None + /** An extractor for `ref @annotation.internal.reachCapability`, which is used to express * the reach capability `ref*` as a type. */ -object ReachCapability: - def unapply(tree: AnnotatedType)(using Context): Option[SingletonCaptureRef] = tree match - case AnnotatedType(parent: SingletonCaptureRef, ann) - if ann.symbol == defn.ReachCapabilityAnnot => Some(parent) - case _ => None +object ReachCapability extends AnnotatedCapability(defn.ReachCapabilityAnnot) + +/** An extractor for `ref @maybeCapability`, which is used to express + * the maybe capability `ref?` as a type. + */ +object MaybeCapability extends AnnotatedCapability(defn.MaybeCapabilityAnnot) + diff --git a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala index fb086ca0399b..d1a5a07f6a0f 100644 --- a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala +++ b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala @@ -145,15 +145,16 @@ sealed abstract class CaptureSet extends Showable: /** x subsumes x * this subsumes this.f - * x subsumes y ==> x* subsumes y - * x subsumes y ==> x* subsumes y* + * x subsumes y ==> x* subsumes y, x subsumes y? + * x subsumes y ==> x* subsumes y*, x? subsumes y? */ extension (x: CaptureRef) private def subsumes(y: CaptureRef)(using Context): Boolean = (x eq y) || x.isRootCapability || y.match - case y: TermRef => !y.isReach && (y.prefix eq x) + case y: TermRef => y.prefix eq x + case MaybeCapability(y1) => x.stripMaybe.subsumes(y1) case _ => false || x.match case ReachCapability(x1) => x1.subsumes(y.stripReach) @@ -312,6 +313,8 @@ sealed abstract class CaptureSet extends Showable: def substParams(tl: BindingType, to: List[Type])(using Context) = map(Substituters.SubstParamsMap(tl, to)) + def maybe(using Context): CaptureSet = map(MaybeMap()) + /** Invoke handler if this set has (or later aquires) the root capability `cap` */ def disallowRootCapability(handler: () => Context ?=> Unit)(using Context): this.type = if isUniversal then handler() @@ -445,6 +448,8 @@ object CaptureSet: def isConst = isSolved def isAlwaysEmpty = false + def isMaybeSet = false // overridden in BiMapped + /** A handler to be invoked if the root reference `cap` is added to this set */ var rootAddedHandler: () => Context ?=> Unit = () => () @@ -490,9 +495,10 @@ object CaptureSet: if elem.isRootCapability then rootAddedHandler() newElemAddedHandler(elem) + val normElem = if isMaybeSet then elem else elem.stripMaybe // assert(id != 5 || elems.size != 3, this) val res = (CompareResult.OK /: deps): (r, dep) => - r.andAlso(dep.tryInclude(elem, this)) + r.andAlso(dep.tryInclude(normElem, this)) res.orElse: elems -= elem res.addToTrace(this) @@ -508,6 +514,8 @@ object CaptureSet: levelLimit.isContainedIn(elem.cls.levelOwner) case ReachCapability(elem1) => levelOK(elem1) + case MaybeCapability(elem1) => + levelOK(elem1) case _ => true @@ -701,24 +709,17 @@ object CaptureSet: if mapped.isConst then CompareResult.OK else if mapped.asVar.recordDepsState() then { addAsDependentTo(mapped); CompareResult.OK } else CompareResult.Fail(this :: Nil) - else if !isFixpoint then - // We did not yet observe the !isFixpoint condition in our tests, but it's a - // theoretical possibility. In that case, it would be inconsistent to both - // add `elem` to the set and back-propagate it. But if `{elem} <:< tm(elem)` - // and the variance of the set is positive, we can soundly add `tm(ref)` to - // the set while back-propagating `ref` as before. Otherwise there's nothing - // obvious left to do except fail (which is always sound). - if variance > 0 - && elem.singletonCaptureSet.subCaptures(mapped, frozen = true).isOK then - // widen to fixpoint. mapped is known to be a fixpoint since tm is idempotent. - // The widening is sound, but loses completeness. - addMapped - else - failNoFixpoint else if accountsFor(elem) then CompareResult.OK - else + else if variance > 0 then + // we can soundly add nothing to source and `x` to this set + addNewElem(elem) + else if isFixpoint then + // We can soundly add `x` to both this set and source since `f(x) = x` addNewElem(elem).andAlso(propagate) + else + // we are out of options; fail (which is always sound). + failNoFixpoint end tryInclude override def computeApprox(origin: CaptureSet)(using Context): CaptureSet = @@ -767,6 +768,7 @@ object CaptureSet: if source eq origin then supApprox.map(bimap.inverse) else source.upperApprox(this).map(bimap) ** supApprox + override def isMaybeSet: Boolean = bimap.isInstanceOf[MaybeMap] override def toString = s"BiMapped$id($source, elems = $elems)" end BiMapped @@ -847,8 +849,7 @@ object CaptureSet: upper.isAlwaysEmpty || upper.isConst && upper.elems.size == 1 && upper.elems.contains(r1) if variance > 0 || isExact then upper else if variance < 0 then CaptureSet.empty - else if ctx.mode.is(Mode.Printing) then upper - else assert(false, i"trying to add $upper from $r via ${tm.getClass} in a non-variant setting") + else upper.maybe /** Apply `f` to each element in `xs`, and join result sets with `++` */ def mapRefs(xs: Refs, f: CaptureRef => CaptureSet)(using Context): CaptureSet = @@ -987,6 +988,26 @@ object CaptureSet: /** The current VarState, as passed by the implicit context */ def varState(using state: VarState): VarState = state + /** Maps `x` to `x?` */ + private class MaybeMap(using Context) extends BiTypeMap: + + def apply(t: Type) = t match + case t: CaptureRef if t.isTrackableRef => t.maybe + case _ => mapOver(t) + + override def toString = "Maybe" + + lazy val inverse = new BiTypeMap: + + def apply(t: Type) = t match + case t: CaptureRef if t.isMaybe => t.stripMaybe + case t => mapOver(t) + + def inverse = MaybeMap.this + + override def toString = "Maybe.inverse" + end MaybeMap + /* Not needed: def ofClass(cinfo: ClassInfo, argTypes: List[Type])(using Context): CaptureSet = CaptureSet.empty diff --git a/compiler/src/dotty/tools/dotc/cc/CapturingType.scala b/compiler/src/dotty/tools/dotc/cc/CapturingType.scala index 2a5cb91b45d3..ee0cad4d4d03 100644 --- a/compiler/src/dotty/tools/dotc/cc/CapturingType.scala +++ b/compiler/src/dotty/tools/dotc/cc/CapturingType.scala @@ -58,8 +58,7 @@ object CapturingType: case AnnotatedType(parent, ann: CaptureAnnotation) if isCaptureCheckingOrSetup => Some((parent, ann.refs)) - case AnnotatedType(parent, ann) - if ann.symbol == defn.RetainsAnnot && isCaptureChecking => + case AnnotatedType(parent, ann) if ann.symbol.isRetains && isCaptureChecking => // There are some circumstances where we cannot map annotated types // with retains annotations to capturing types, so this second recognizer // path still has to exist. One example is when checking capture sets diff --git a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala index d635096b2318..4564bed6db01 100644 --- a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala +++ b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala @@ -68,12 +68,6 @@ object CheckCaptures: */ final class SubstParamsMap(from: BindingType, to: List[Type])(using Context) extends ApproximatingTypeMap, IdempotentCaptRefMap: - /** This SubstParamsMap is exact if `to` only contains `CaptureRef`s. */ - private val isExactSubstitution: Boolean = to.forall(_.isTrackableRef) - - /** As long as this substitution is exact, there is no need to create `Range`s when mapping invariant positions. */ - override protected def needsRangeIfInvariant(refs: CaptureSet): Boolean = !isExactSubstitution - def apply(tp: Type): Type = tp match case tp: ParamRef => @@ -672,17 +666,13 @@ class CheckCaptures extends Recheck, SymTransformer: def checkInferredResult(tp: Type, tree: ValOrDefDef)(using Context): Type = val sym = tree.symbol - def isLocal = - sym.owner.ownersIterator.exists(_.isTerm) - || sym.accessBoundary(defn.RootClass).isContainedIn(sym.topLevelClass) - def canUseInferred = // If canUseInferred is false, all capturing types in the type of `sym` need to be given explicitly sym.is(Private) // private symbols can always have inferred types || sym.name.is(DefaultGetterName) // default getters are exempted since otherwise it would be // too annoying. This is a hole since a defualt getter's result type // might leak into a type variable. || // non-local symbols cannot have inferred types since external capture types are not inferred - isLocal // local symbols still need explicit types if + sym.isLocalToCompilationUnit // local symbols still need explicit types if && !sym.owner.is(Trait) // they are defined in a trait, since we do OverridingPairs checking before capture inference def addenda(expected: Type) = new Addenda: @@ -847,9 +837,13 @@ class CheckCaptures extends Recheck, SymTransformer: * where local capture roots are instantiated to root variables. */ override def checkConformsExpr(actual: Type, expected: Type, tree: Tree, addenda: Addenda)(using Context): Type = - val expected1 = alignDependentFunction(addOuterRefs(expected, actual), actual.stripCapturing) + var expected1 = alignDependentFunction(expected, actual.stripCapturing) val actualBoxed = adaptBoxed(actual, expected1, tree.srcPos) //println(i"check conforms $actualBoxed <<< $expected1") + + if actualBoxed eq actual then + // Only `addOuterRefs` when there is no box adaptation + expected1 = addOuterRefs(expected1, actual) if isCompatible(actualBoxed, expected1) then if debugSuccesses then tree match case Ident(_) => @@ -1178,7 +1172,7 @@ class CheckCaptures extends Recheck, SymTransformer: /** Check that self types of subclasses conform to self types of super classes. * (See comment below how this is achieved). The check assumes that classes * without an explicit self type have the universal capture set `{cap}` on the - * self type. If a class without explicit self type is not `effectivelyFinal` + * self type. If a class without explicit self type is not `effectivelySealed` * it is checked that the inferred self type is universal, in order to assure * that joint and separate compilation give the same result. */ @@ -1208,23 +1202,20 @@ class CheckCaptures extends Recheck, SymTransformer: checkSelfAgainstParents(root, root.baseClasses) val selfType = root.asClass.classInfo.selfType interpolator(startingVariance = -1).traverse(selfType) - if !root.isEffectivelySealed then - def matchesExplicitRefsInBaseClass(refs: CaptureSet, cls: ClassSymbol): Boolean = - cls.baseClasses.tail.exists { psym => - val selfType = psym.asClass.givenSelfType - selfType.exists && selfType.captureSet.elems == refs.elems - } - selfType match - case CapturingType(_, refs: CaptureSet.Var) - if !refs.elems.exists(_.isRootCapability) && !matchesExplicitRefsInBaseClass(refs, root) => - // Forbid inferred self types unless they are already implied by an explicit - // self type in a parent. - report.error( - em"""$root needs an explicitly declared self type since its - |inferred self type $selfType - |is not visible in other compilation units that define subclasses.""", - root.srcPos) - case _ => + selfType match + case CapturingType(_, refs: CaptureSet.Var) + if !root.isEffectivelySealed + && !refs.elems.exists(_.isRootCapability) + && !root.matchesExplicitRefsInBaseClass(refs) + => + // Forbid inferred self types unless they are already implied by an explicit + // self type in a parent. + report.error( + em"""$root needs an explicitly declared self type since its + |inferred self type $selfType + |is not visible in other compilation units that define subclasses.""", + root.srcPos) + case _ => parentTrees -= root capt.println(i"checked $root with $selfType") end checkSelfTypes diff --git a/compiler/src/dotty/tools/dotc/cc/RetainingType.scala b/compiler/src/dotty/tools/dotc/cc/RetainingType.scala index 7902b03445fb..efd0e96fd658 100644 --- a/compiler/src/dotty/tools/dotc/cc/RetainingType.scala +++ b/compiler/src/dotty/tools/dotc/cc/RetainingType.scala @@ -23,7 +23,7 @@ object RetainingType: def unapply(tp: AnnotatedType)(using Context): Option[(Type, List[Tree])] = val sym = tp.annot.symbol - if sym == defn.RetainsAnnot || sym == defn.RetainsByNameAnnot then + if sym.isRetainsLike then tp.annot match case _: CaptureAnnotation => assert(ctx.mode.is(Mode.IgnoreCaptures), s"bad retains $tp at ${ctx.phase}") diff --git a/compiler/src/dotty/tools/dotc/cc/Setup.scala b/compiler/src/dotty/tools/dotc/cc/Setup.scala index 74e67bda5fab..9ab41859f170 100644 --- a/compiler/src/dotty/tools/dotc/cc/Setup.scala +++ b/compiler/src/dotty/tools/dotc/cc/Setup.scala @@ -120,7 +120,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: case tp @ CapturingType(parent, refs) => if tp.isBoxed then tp else tp.boxed case tp @ AnnotatedType(parent, ann) => - if ann.symbol == defn.RetainsAnnot + if ann.symbol.isRetains then CapturingType(parent, ann.tree.toCaptureSet, boxed = true) else tp.derivedAnnotatedType(box(parent), ann) case tp1 @ AppliedType(tycon, args) if defn.isNonRefinedFunction(tp1) => @@ -192,7 +192,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: def apply(tp: Type) = val tp1 = tp match - case AnnotatedType(parent, annot) if annot.symbol == defn.RetainsAnnot => + case AnnotatedType(parent, annot) if annot.symbol.isRetains => // Drop explicit retains annotations apply(parent) case tp @ AppliedType(tycon, args) => @@ -283,7 +283,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: t.derivedCapturingType(this(parent), refs) case t @ AnnotatedType(parent, ann) => val parent1 = this(parent) - if ann.symbol == defn.RetainsAnnot then + if ann.symbol.isRetains then for tpt <- tptToCheck do checkWellformedLater(parent1, ann.tree, tpt) CapturingType(parent1, ann.tree.toCaptureSet) @@ -416,7 +416,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: case tree @ SeqLiteral(elems, tpt: TypeTree) => traverse(elems) - transformTT(tpt, boxed = true, exact = false) + tpt.rememberType(box(transformInferredType(tpt.tpe))) case _ => traverseChildren(tree) @@ -517,21 +517,34 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: tree.symbol match case cls: ClassSymbol => val cinfo @ ClassInfo(prefix, _, ps, decls, selfInfo) = cls.classInfo - if ((selfInfo eq NoType) || cls.is(ModuleClass) && !cls.isStatic) - && !cls.isPureClass - then - // add capture set to self type of nested classes if no self type is given explicitly. - val newSelfType = CapturingType(cinfo.selfType, CaptureSet.Var(cls)) - val ps1 = inContext(ctx.withOwner(cls)): - ps.mapConserve(transformExplicitType(_)) - val newInfo = ClassInfo(prefix, cls, ps1, decls, newSelfType) + def innerModule = cls.is(ModuleClass) && !cls.isStatic + val selfInfo1 = + if (selfInfo ne NoType) && !innerModule then + // if selfInfo is explicitly given then use that one, except if + // self info applies to non-static modules, these still need to be inferred + selfInfo + else if cls.isPureClass then + // is cls is known to be pure, nothing needs to be added to self type + selfInfo + else if !cls.isEffectivelySealed && !cls.baseClassHasExplicitSelfType then + // assume {cap} for completely unconstrained self types of publicly extensible classes + CapturingType(cinfo.selfType, CaptureSet.universal) + else + // Infer the self type for the rest, which is all classes without explicit + // self types (to which we also add nested module classes), provided they are + // neither pure, nor are publicily extensible with an unconstrained self type. + CapturingType(cinfo.selfType, CaptureSet.Var(cls)) + val ps1 = inContext(ctx.withOwner(cls)): + ps.mapConserve(transformExplicitType(_)) + if (selfInfo1 ne selfInfo) || (ps1 ne ps) then + val newInfo = ClassInfo(prefix, cls, ps1, decls, selfInfo1) updateInfo(cls, newInfo) capt.println(i"update class info of $cls with parents $ps selfinfo $selfInfo to $newInfo") cls.thisType.asInstanceOf[ThisType].invalidateCaches() if cls.is(ModuleClass) then // if it's a module, the capture set of the module reference is the capture set of the self type val modul = cls.sourceModule - updateInfo(modul, CapturingType(modul.info, newSelfType.captureSet)) + updateInfo(modul, CapturingType(modul.info, selfInfo1.asInstanceOf[Type].captureSet)) modul.termRef.invalidateCaches() case _ => case _ => diff --git a/compiler/src/dotty/tools/dotc/classpath/AggregateClassPath.scala b/compiler/src/dotty/tools/dotc/classpath/AggregateClassPath.scala index 5fbe7212a674..4c5b632bf6ab 100644 --- a/compiler/src/dotty/tools/dotc/classpath/AggregateClassPath.scala +++ b/compiler/src/dotty/tools/dotc/classpath/AggregateClassPath.scala @@ -39,14 +39,14 @@ case class AggregateClassPath(aggregates: Seq[ClassPath]) extends ClassPath { def findEntry(isSource: Boolean): Option[ClassRepresentation] = aggregatesForPackage(PackageName(pkg)).iterator.map(_.findClass(className)).collectFirst { case Some(s: SourceFileEntry) if isSource => s - case Some(s: ClassFileEntry) if !isSource => s + case Some(s: BinaryFileEntry) if !isSource => s } val classEntry = findEntry(isSource = false) val sourceEntry = findEntry(isSource = true) (classEntry, sourceEntry) match { - case (Some(c: ClassFileEntry), Some(s: SourceFileEntry)) => Some(ClassAndSourceFilesEntry(c.file, s.file)) + case (Some(c: BinaryFileEntry), Some(s: SourceFileEntry)) => Some(BinaryAndSourceFilesEntry(c, s)) case (c @ Some(_), _) => c case (_, s) => s } @@ -63,7 +63,7 @@ case class AggregateClassPath(aggregates: Seq[ClassPath]) extends ClassPath { aggregatedPackages } - override private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = + override private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = getDistinctEntries(_.classes(inPackage)) override private[dotty] def sources(inPackage: PackageName): Seq[SourceFileEntry] = @@ -102,10 +102,15 @@ case class AggregateClassPath(aggregates: Seq[ClassPath]) extends ClassPath { ClassPathEntries(distinctPackages, distinctClassesAndSources) } - /** - * Returns only one entry for each name. If there's both a source and a class entry, it - * creates an entry containing both of them. If there would be more than one class or source - * entries for the same class it always would use the first entry of each type found on a classpath. + /** Returns only one entry for each name. + * + * If there's both a source and a class entry, it + * creates an entry containing both of them. If there would be more than one class or source + * entries for the same class it always would use the first entry of each type found on a classpath. + * + * A TASTy file with no class file entry will be chosen over a class file entry. This can happen if we load + * the Scala 2 library as it has one JAR containing the class files and one JAR containing the TASTy files. + * As classpath orders are not guaranteed to be deterministic we might end up having the TASTy in a later classpath entry. */ private def mergeClassesAndSources(entries: scala.collection.Seq[ClassRepresentation]): Seq[ClassRepresentation] = { // based on the implementation from MergedClassPath @@ -119,11 +124,18 @@ case class AggregateClassPath(aggregates: Seq[ClassPath]) extends ClassPath { if (indices.contains(name)) { val index = indices(name) val existing = mergedEntries(index) - - if (existing.binary.isEmpty && entry.binary.isDefined) - mergedEntries(index) = ClassAndSourceFilesEntry(entry.binary.get, existing.source.get) - if (existing.source.isEmpty && entry.source.isDefined) - mergedEntries(index) = ClassAndSourceFilesEntry(existing.binary.get, entry.source.get) + (entry, existing) match + case (entry: SourceFileEntry, existing: BinaryFileEntry) => + mergedEntries(index) = BinaryAndSourceFilesEntry(existing, entry) + case (entry: BinaryFileEntry, existing: SourceFileEntry) => + mergedEntries(index) = BinaryAndSourceFilesEntry(entry, existing) + case (entry: StandaloneTastyFileEntry, _: ClassFileEntry) => + // Here we do not create a TastyWithClassFileEntry because the TASTy and the classfile + // come from different classpaths. These may not have the same TASTy UUID. + mergedEntries(index) = entry + case (entry: StandaloneTastyFileEntry, BinaryAndSourceFilesEntry(_: ClassFileEntry, sourceEntry)) => + mergedEntries(index) = BinaryAndSourceFilesEntry(entry, sourceEntry) + case _ => } else { indices(name) = count diff --git a/compiler/src/dotty/tools/dotc/classpath/ClassPath.scala b/compiler/src/dotty/tools/dotc/classpath/ClassPath.scala index 176b6acf9c6c..3210c6221a78 100644 --- a/compiler/src/dotty/tools/dotc/classpath/ClassPath.scala +++ b/compiler/src/dotty/tools/dotc/classpath/ClassPath.scala @@ -3,6 +3,7 @@ */ package dotty.tools.dotc.classpath +import dotty.tools.dotc.classpath.FileUtils.isTasty import dotty.tools.io.AbstractFile import dotty.tools.io.ClassRepresentation @@ -14,14 +15,6 @@ object ClassPathEntries { val empty = ClassPathEntries(Seq.empty, Seq.empty) } -trait ClassFileEntry extends ClassRepresentation { - def file: AbstractFile -} - -trait SourceFileEntry extends ClassRepresentation { - def file: AbstractFile -} - case class PackageName(dottedString: String) { val dirPathTrailingSlashJar: String = FileUtils.dirPathInJar(dottedString) + "/" @@ -48,28 +41,50 @@ trait PackageEntry { def name: String } -private[dotty] case class ClassFileEntryImpl(file: AbstractFile) extends ClassFileEntry { +/** A TASTy file or classfile */ +sealed trait BinaryFileEntry extends ClassRepresentation { + def file: AbstractFile final def fileName: String = file.name - def name: String = FileUtils.stripClassExtension(file.name) // class name + final def name: String = FileUtils.stripClassExtension(file.name) // class name + final def source: Option[AbstractFile] = None +} +object BinaryFileEntry { + def apply(file: AbstractFile): BinaryFileEntry = + if file.isTasty then + if file.resolveSiblingWithExtension("class") != null then TastyWithClassFileEntry(file) + else StandaloneTastyFileEntry(file) + else + ClassFileEntry(file) +} + +/** A classfile or .sig that does not have an associated TASTy file */ +private[dotty] final case class ClassFileEntry(file: AbstractFile) extends BinaryFileEntry { def binary: Option[AbstractFile] = Some(file) - def source: Option[AbstractFile] = None } -private[dotty] case class SourceFileEntryImpl(file: AbstractFile) extends SourceFileEntry { +/** A TASTy file that has an associated class file */ +private[dotty] final case class TastyWithClassFileEntry(file: AbstractFile) extends BinaryFileEntry { + def binary: Option[AbstractFile] = Some(file) +} + +/** A TASTy file that does not have an associated class file */ +private[dotty] final case class StandaloneTastyFileEntry(file: AbstractFile) extends BinaryFileEntry { + def binary: Option[AbstractFile] = Some(file) +} + +private[dotty] final case class SourceFileEntry(file: AbstractFile) extends ClassRepresentation { final def fileName: String = file.name def name: String = FileUtils.stripSourceExtension(file.name) - def binary: Option[AbstractFile] = None def source: Option[AbstractFile] = Some(file) } -private[dotty] case class ClassAndSourceFilesEntry(classFile: AbstractFile, srcFile: AbstractFile) extends ClassRepresentation { - final def fileName: String = classFile.name - def name: String = FileUtils.stripClassExtension(classFile.name) - - def binary: Option[AbstractFile] = Some(classFile) - def source: Option[AbstractFile] = Some(srcFile) +private[dotty] final case class BinaryAndSourceFilesEntry(binaryEntry: BinaryFileEntry, sourceEntry: SourceFileEntry) extends ClassRepresentation { + final def fileName: String = binaryEntry.fileName + def name: String = binaryEntry.name + def binary: Option[AbstractFile] = binaryEntry.binary + def source: Option[AbstractFile] = sourceEntry.source } private[dotty] case class PackageEntryImpl(name: String) extends PackageEntry @@ -81,5 +96,5 @@ private[dotty] trait NoSourcePaths { private[dotty] trait NoClassPaths { def findClassFile(className: String): Option[AbstractFile] = None - private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = Seq.empty + private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = Seq.empty } diff --git a/compiler/src/dotty/tools/dotc/classpath/DirectoryClassPath.scala b/compiler/src/dotty/tools/dotc/classpath/DirectoryClassPath.scala index 26ed2734890e..c5b267bc774d 100644 --- a/compiler/src/dotty/tools/dotc/classpath/DirectoryClassPath.scala +++ b/compiler/src/dotty/tools/dotc/classpath/DirectoryClassPath.scala @@ -183,12 +183,12 @@ final class JrtClassPath(fs: java.nio.file.FileSystem) extends ClassPath with No override private[dotty] def packages(inPackage: PackageName): Seq[PackageEntry] = packageToModuleBases.keysIterator.filter(pack => packageContains(inPackage.dottedString, pack)).map(PackageEntryImpl(_)).toVector - private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = + private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = if (inPackage.isRoot) Nil else packageToModuleBases.getOrElse(inPackage.dottedString, Nil).flatMap(x => Files.list(x.resolve(inPackage.dirPathTrailingSlash)).iterator().asScala.filter(_.getFileName.toString.endsWith(".class"))).map(x => - ClassFileEntryImpl(x.toPlainFile)).toVector + ClassFileEntry(x.toPlainFile)).toVector override private[dotty] def list(inPackage: PackageName): ClassPathEntries = if (inPackage.isRoot) ClassPathEntries(packages(inPackage), Nil) @@ -246,12 +246,12 @@ final class CtSymClassPath(ctSym: java.nio.file.Path, release: Int) extends Clas override private[dotty] def packages(inPackage: PackageName): Seq[PackageEntry] = { packageIndex.keysIterator.filter(pack => packageContains(inPackage.dottedString, pack)).map(PackageEntryImpl(_)).toVector } - private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = { + private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = { if (inPackage.isRoot) Nil else { val sigFiles = packageIndex.getOrElse(inPackage.dottedString, Nil).iterator.flatMap(p => Files.list(p).iterator.asScala.filter(_.getFileName.toString.endsWith(".sig"))) - sigFiles.map(f => ClassFileEntryImpl(f.toPlainFile)).toVector + sigFiles.map(f => ClassFileEntry(f.toPlainFile)).toVector } } @@ -273,8 +273,9 @@ final class CtSymClassPath(ctSym: java.nio.file.Path, release: Int) extends Clas } } -case class DirectoryClassPath(dir: JFile) extends JFileDirectoryLookup[ClassFileEntryImpl] with NoSourcePaths { - override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl.apply +case class DirectoryClassPath(dir: JFile) extends JFileDirectoryLookup[BinaryFileEntry] with NoSourcePaths { + override def findClass(className: String): Option[ClassRepresentation] = + findClassFile(className).map(BinaryFileEntry(_)) def findClassFile(className: String): Option[AbstractFile] = { val relativePath = FileUtils.dirPath(className) @@ -282,24 +283,25 @@ case class DirectoryClassPath(dir: JFile) extends JFileDirectoryLookup[ClassFile if tastyFile.exists then Some(tastyFile.toPath.toPlainFile) else val classFile = new JFile(dir, relativePath + ".class") - if classFile.exists then Some(classFile.toPath.toPlainFile) + if classFile.exists then Some(classFile.toPath.toPlainFile) else None } - protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file) + protected def createFileEntry(file: AbstractFile): BinaryFileEntry = BinaryFileEntry(file) + protected def isMatchingFile(f: JFile): Boolean = f.isTasty || (f.isClass && f.classToTasty.isEmpty) - private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = files(inPackage) + private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = files(inPackage) } -case class DirectorySourcePath(dir: JFile) extends JFileDirectoryLookup[SourceFileEntryImpl] with NoClassPaths { +case class DirectorySourcePath(dir: JFile) extends JFileDirectoryLookup[SourceFileEntry] with NoClassPaths { def asSourcePathString: String = asClassPathString - protected def createFileEntry(file: AbstractFile): SourceFileEntryImpl = SourceFileEntryImpl(file) + protected def createFileEntry(file: AbstractFile): SourceFileEntry = SourceFileEntry(file) protected def isMatchingFile(f: JFile): Boolean = endsScalaOrJava(f.getName) - override def findClass(className: String): Option[ClassRepresentation] = findSourceFile(className) map SourceFileEntryImpl.apply + override def findClass(className: String): Option[ClassRepresentation] = findSourceFile(className).map(SourceFileEntry(_)) private def findSourceFile(className: String): Option[AbstractFile] = { val relativePath = FileUtils.dirPath(className) diff --git a/compiler/src/dotty/tools/dotc/classpath/VirtualDirectoryClassPath.scala b/compiler/src/dotty/tools/dotc/classpath/VirtualDirectoryClassPath.scala index f520cd97767e..93583c85fff7 100644 --- a/compiler/src/dotty/tools/dotc/classpath/VirtualDirectoryClassPath.scala +++ b/compiler/src/dotty/tools/dotc/classpath/VirtualDirectoryClassPath.scala @@ -7,7 +7,7 @@ import dotty.tools.io.{AbstractFile, VirtualDirectory} import FileUtils.* import java.net.{URI, URL} -case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath with DirectoryLookup[ClassFileEntryImpl] with NoSourcePaths { +case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath with DirectoryLookup[BinaryFileEntry] with NoSourcePaths { type F = AbstractFile // From AbstractFileClassLoader @@ -38,7 +38,8 @@ case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath wi def asURLs: Seq[URL] = Seq(new URI(dir.name).toURL) def asClassPathStrings: Seq[String] = Seq(dir.path) - override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl.apply + override def findClass(className: String): Option[ClassRepresentation] = + findClassFile(className).map(BinaryFileEntry(_)) def findClassFile(className: String): Option[AbstractFile] = { val pathSeq = FileUtils.dirPath(className).split(java.io.File.separator) @@ -49,9 +50,10 @@ case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath wi .orElse(Option(lookupPath(parentDir)(pathSeq.last + ".class" :: Nil, directory = false))) } - private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = files(inPackage) + private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = files(inPackage) + + protected def createFileEntry(file: AbstractFile): BinaryFileEntry = BinaryFileEntry(file) - protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file) protected def isMatchingFile(f: AbstractFile): Boolean = f.isTasty || (f.isClass && f.classToTasty.isEmpty) } diff --git a/compiler/src/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactory.scala b/compiler/src/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactory.scala index 0ca996db4812..dac156c5f647 100644 --- a/compiler/src/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactory.scala +++ b/compiler/src/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactory.scala @@ -41,22 +41,23 @@ sealed trait ZipAndJarFileLookupFactory { */ object ZipAndJarClassPathFactory extends ZipAndJarFileLookupFactory { private case class ZipArchiveClassPath(zipFile: File, override val release: Option[String]) - extends ZipArchiveFileLookup[ClassFileEntryImpl] + extends ZipArchiveFileLookup[BinaryFileEntry] with NoSourcePaths { override def findClassFile(className: String): Option[AbstractFile] = findClass(className).map(_.file) // This method is performance sensitive as it is used by SBT's ExtractDependencies phase. - override def findClass(className: String): Option[ClassFileEntryImpl] = { + override def findClass(className: String): Option[BinaryFileEntry] = { val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className) val binaries = files(PackageName(pkg), simpleClassName + ".tasty", simpleClassName + ".class") binaries.find(_.file.isTasty).orElse(binaries.find(_.file.isClass)) } - override private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = files(inPackage) + override private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = files(inPackage) + + override protected def createFileEntry(file: FileZipArchive#Entry): BinaryFileEntry = BinaryFileEntry(file) - override protected def createFileEntry(file: FileZipArchive#Entry): ClassFileEntryImpl = ClassFileEntryImpl(file) override protected def isRequiredFileType(file: AbstractFile): Boolean = file.isTasty || (file.isClass && file.classToTasty.isEmpty) } @@ -128,10 +129,10 @@ object ZipAndJarClassPathFactory extends ZipAndJarFileLookupFactory { subpackages.map(packageFile => PackageEntryImpl(inPackage.entryName(packageFile.name))) } - override private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] = cachedPackages.get(inPackage.dottedString) match { + override private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] = cachedPackages.get(inPackage.dottedString) match { case None => Seq.empty case Some(PackageFileInfo(pkg, _)) => - (for (file <- pkg if file.isClass) yield ClassFileEntryImpl(file)).toSeq + (for (file <- pkg if file.isClass) yield ClassFileEntry(file)).toSeq } override private[dotty] def hasPackage(pkg: PackageName) = cachedPackages.contains(pkg.dottedString) @@ -162,7 +163,7 @@ object ZipAndJarClassPathFactory extends ZipAndJarFileLookupFactory { */ object ZipAndJarSourcePathFactory extends ZipAndJarFileLookupFactory { private case class ZipArchiveSourcePath(zipFile: File) - extends ZipArchiveFileLookup[SourceFileEntryImpl] + extends ZipArchiveFileLookup[SourceFileEntry] with NoClassPaths { def release: Option[String] = None @@ -171,7 +172,7 @@ object ZipAndJarSourcePathFactory extends ZipAndJarFileLookupFactory { override private[dotty] def sources(inPackage: PackageName): Seq[SourceFileEntry] = files(inPackage) - override protected def createFileEntry(file: FileZipArchive#Entry): SourceFileEntryImpl = SourceFileEntryImpl(file) + override protected def createFileEntry(file: FileZipArchive#Entry): SourceFileEntry = SourceFileEntry(file) override protected def isRequiredFileType(file: AbstractFile): Boolean = file.isScalaOrJavaSource } diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index d1b91f77f933..85e6ebef751f 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -120,6 +120,7 @@ trait CommonScalaSettings: // -explain-types setting is necessary for cross compilation, since it is mentioned in sbt-tpolecat, for instance // it is otherwise subsumed by -explain, and should be dropped as soon as we can. val explainTypes: Setting[Boolean] = BooleanSetting("-explain-types", "Explain type errors in more detail (deprecated, use -explain instead).", aliases = List("--explain-types", "-explaintypes")) + val explainCyclic: Setting[Boolean] = BooleanSetting("-explain-cyclic", "Explain cyclic reference errors in more detail.", aliases = List("--explain-cyclic")) val unchecked: Setting[Boolean] = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.", initialValue = true, aliases = List("--unchecked")) val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.", aliases = List("--language")) val experimental: Setting[Boolean] = BooleanSetting("-experimental", "Annotate all top-level definitions with @experimental. This enables the use of experimental features anywhere in the project.") @@ -351,6 +352,7 @@ private sealed trait YSettings: val YdebugTypeError: Setting[Boolean] = BooleanSetting("-Ydebug-type-error", "Print the stack trace when a TypeError is caught", false) val YdebugError: Setting[Boolean] = BooleanSetting("-Ydebug-error", "Print the stack trace when any error is caught.", false) val YdebugUnpickling: Setting[Boolean] = BooleanSetting("-Ydebug-unpickling", "Print the stack trace when an error occurs when reading Tasty.", false) + val YdebugCyclic: Setting[Boolean] = BooleanSetting("-Ydebug-cyclic", "Print the stack trace when a cyclic reference error occurs.", false) val YtermConflict: Setting[String] = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error") val Ylog: Setting[List[String]] = PhasesSetting("-Ylog", "Log operations during") val YlogClasspath: Setting[Boolean] = BooleanSetting("-Ylog-classpath", "Output information about what classpath is being applied.") diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index 6be6ec94c1c3..da94226b34af 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -858,7 +858,8 @@ trait ConstraintHandling { addParamBound(bound) case _ => val pbound = avoidLambdaParams(bound) - kindCompatible(param, pbound) && addBoundTransitively(param, pbound, !fromBelow) + (pbound.isNothingType || kindCompatible(param, pbound)) + && addBoundTransitively(param, pbound, !fromBelow) finally canWidenAbstract = saved addConstraintInvocations -= 1 diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index ee288a08b53f..c5f04d18b7fb 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -95,7 +95,7 @@ object Contexts { inline def atPhaseNoEarlier[T](limit: Phase)(inline op: Context ?=> T)(using Context): T = op(using if !limit.exists || limit <= ctx.phase then ctx else ctx.withPhase(limit)) - inline def inMode[T](mode: Mode)(inline op: Context ?=> T)(using ctx: Context): T = + inline private def inMode[T](mode: Mode)(inline op: Context ?=> T)(using ctx: Context): T = op(using if mode != ctx.mode then ctx.fresh.setMode(mode) else ctx) inline def withMode[T](mode: Mode)(inline op: Context ?=> T)(using ctx: Context): T = diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index e08672c693b9..3cde29ee3d79 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -535,6 +535,10 @@ class Definitions { List(AnyType), EmptyScope) @tu lazy val SingletonType: TypeRef = SingletonClass.typeRef + @tu lazy val MaybeCapabilityAnnot: ClassSymbol = + completeClass(enterCompleteClassSymbol( + ScalaPackageClass, tpnme.maybeCapability, Final, List(StaticAnnotationClass.typeRef))) + @tu lazy val CollectionSeqType: TypeRef = requiredClassRef("scala.collection.Seq") @tu lazy val SeqType: TypeRef = requiredClassRef("scala.collection.immutable.Seq") @tu lazy val SeqModule: Symbol = requiredModule("scala.collection.immutable.Seq") @@ -1010,11 +1014,11 @@ class Definitions { @tu lazy val ProvisionalSuperClassAnnot: ClassSymbol = requiredClass("scala.annotation.internal.ProvisionalSuperClass") @tu lazy val DeprecatedAnnot: ClassSymbol = requiredClass("scala.deprecated") @tu lazy val DeprecatedOverridingAnnot: ClassSymbol = requiredClass("scala.deprecatedOverriding") + @tu lazy val DeprecatedInheritanceAnnot: ClassSymbol = requiredClass("scala.deprecatedInheritance") @tu lazy val ImplicitAmbiguousAnnot: ClassSymbol = requiredClass("scala.annotation.implicitAmbiguous") @tu lazy val ImplicitNotFoundAnnot: ClassSymbol = requiredClass("scala.annotation.implicitNotFound") @tu lazy val InlineParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InlineParam") @tu lazy val ErasedParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.ErasedParam") - @tu lazy val InvariantBetweenAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InvariantBetween") @tu lazy val MainAnnot: ClassSymbol = requiredClass("scala.main") @tu lazy val MappedAlternativeAnnot: ClassSymbol = requiredClass("scala.annotation.internal.MappedAlternative") @tu lazy val MigrationAnnot: ClassSymbol = requiredClass("scala.annotation.migration") @@ -1026,7 +1030,7 @@ class Definitions { @tu lazy val SourceFileAnnot: ClassSymbol = requiredClass("scala.annotation.internal.SourceFile") @tu lazy val ScalaSignatureAnnot: ClassSymbol = requiredClass("scala.reflect.ScalaSignature") @tu lazy val ScalaLongSignatureAnnot: ClassSymbol = requiredClass("scala.reflect.ScalaLongSignature") - @tu lazy val ScalaStrictFPAnnot: ClassSymbol = requiredClass("scala.annotation.strictfp") + // @tu lazy val ScalaStrictFPAnnot: ClassSymbol = requiredClass("scala.annotation.strictfp") @tu lazy val ScalaStaticAnnot: ClassSymbol = requiredClass("scala.annotation.static") @tu lazy val SerialVersionUIDAnnot: ClassSymbol = requiredClass("scala.SerialVersionUID") @tu lazy val TailrecAnnot: ClassSymbol = requiredClass("scala.annotation.tailrec") @@ -1054,10 +1058,10 @@ class Definitions { @tu lazy val FunctionalInterfaceAnnot: ClassSymbol = requiredClass("java.lang.FunctionalInterface") @tu lazy val TargetNameAnnot: ClassSymbol = requiredClass("scala.annotation.targetName") @tu lazy val VarargsAnnot: ClassSymbol = requiredClass("scala.annotation.varargs") - @tu lazy val SinceAnnot: ClassSymbol = requiredClass("scala.annotation.since") @tu lazy val ReachCapabilityAnnot = requiredClass("scala.annotation.internal.reachCapability") @tu lazy val RequiresCapabilityAnnot: ClassSymbol = requiredClass("scala.annotation.internal.requiresCapability") @tu lazy val RetainsAnnot: ClassSymbol = requiredClass("scala.annotation.retains") + @tu lazy val RetainsCapAnnot: ClassSymbol = requiredClass("scala.annotation.retainsCap") @tu lazy val RetainsByNameAnnot: ClassSymbol = requiredClass("scala.annotation.retainsByName") @tu lazy val PublicInBinaryAnnot: ClassSymbol = requiredClass("scala.annotation.publicInBinary") @@ -1172,19 +1176,18 @@ class Definitions { } } - object RefinedFunctionOf { + object RefinedFunctionOf: + /** Matches a refined `PolyFunction`/`FunctionN[...]`/`ContextFunctionN[...]`. * Extracts the method type type and apply info. */ - def unapply(tpe: RefinedType)(using Context): Option[MethodOrPoly] = { + def unapply(tpe: RefinedType)(using Context): Option[MethodOrPoly] = tpe.refinedInfo match case mt: MethodOrPoly - if tpe.refinedName == nme.apply - && (tpe.parent.derivesFrom(defn.PolyFunctionClass) || isFunctionNType(tpe.parent)) => - Some(mt) + if tpe.refinedName == nme.apply && isFunctionType(tpe.parent) => Some(mt) case _ => None - } - } + + end RefinedFunctionOf object PolyFunctionOf { @@ -2009,7 +2012,7 @@ class Definitions { @tu lazy val ccExperimental: Set[Symbol] = Set( CapsModule, CapsModule.moduleClass, PureClass, CapabilityAnnot, RequiresCapabilityAnnot, - RetainsAnnot, RetainsByNameAnnot) + RetainsAnnot, RetainsCapAnnot, RetainsByNameAnnot) // ----- primitive value class machinery ------------------------------------------ @@ -2138,7 +2141,8 @@ class Definitions { AnyValClass, NullClass, NothingClass, - SingletonClass) + SingletonClass, + MaybeCapabilityAnnot) @tu lazy val syntheticCoreClasses: List[Symbol] = syntheticScalaClasses ++ List( EmptyPackageVal, diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index 3608f16e3478..bd92fa814a6e 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -22,6 +22,7 @@ import config.Config import config.Printers.overload import util.common.* import typer.ProtoTypes.NoViewsAllowed +import reporting.Message import collection.mutable.ListBuffer import scala.compiletime.uninitialized @@ -954,7 +955,9 @@ object Denotations { } def staleSymbolError(using Context): Nothing = - throw new StaleSymbol(staleSymbolMsg) + if symbol.isPackageObject && ctx.run != null && ctx.run.nn.isCompilingSuspended + then throw StaleSymbolTypeError(symbol) + else throw StaleSymbolException(staleSymbolMsg) def staleSymbolMsg(using Context): String = { def ownerMsg = this match { @@ -1362,9 +1365,19 @@ object Denotations { else NoSymbol + trait StaleSymbol extends Exception + /** An exception for accessing symbols that are no longer valid in current run */ - class StaleSymbol(msg: => String) extends Exception { + class StaleSymbolException(msg: => String) extends Exception, StaleSymbol { util.Stats.record("stale symbol") override def getMessage(): String = msg } + + /** An exception that is at the same type a StaleSymbol and a TypeError. + * Sine it is a TypeError it can be reported as a nroaml error instead of crashing + * the compiler. + */ + class StaleSymbolTypeError(symbol: Symbol)(using Context) extends TypeError, StaleSymbol: + def toMessage(using Context) = + em"Cyclic macro dependency; macro refers to a toplevel symbol in ${symbol.source} from which the macro is called" } diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 8c1b715e3e30..be43cbc8dfcf 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -242,7 +242,7 @@ object Flags { val (AccessorOrSealed @ _, Accessor @ _, Sealed @ _) = newFlags(11, "<accessor>", "sealed") /** A mutable var, an open class */ - val (MutableOrOpen @ __, Mutable @ _, Open @ _) = newFlags(12, "mutable", "open") + val (MutableOrOpen @ _, Mutable @ _, Open @ _) = newFlags(12, "mutable", "open") /** Symbol is local to current class (i.e. private[this] or protected[this] * pre: Private or Protected are also set @@ -363,7 +363,7 @@ object Flags { val (Enum @ _, EnumVal @ _, _) = newFlags(40, "enum") /** An export forwarder */ - val (Exported @ _, _, _) = newFlags(41, "exported") + val (Exported @ _, ExportedTerm @ _, ExportedType @ _) = newFlags(41, "exported") /** Labeled with `erased` modifier (erased value or class) */ val (Erased @ _, _, _) = newFlags(42, "erased") @@ -532,8 +532,15 @@ object Flags { /** Flags that can apply to a module class */ val RetainedModuleClassFlags: FlagSet = RetainedModuleValAndClassFlags | Enum - /** Flags retained in export forwarders */ - val RetainedExportFlags = Given | Implicit | Inline | Transparent + /** Flags retained in term export forwarders */ + val RetainedExportTermFlags = Infix | Given | Implicit | Inline | Transparent | Erased | HasDefaultParams | NoDefaultParams | ExtensionMethod + + val MandatoryExportTermFlags = Exported | Method | Final + + /** Flags retained in type export forwarders */ + val RetainedExportTypeFlags = Infix + + val MandatoryExportTypeFlags = Exported | Final /** Flags that apply only to classes */ val ClassOnlyFlags = Sealed | Open | Abstract.toTypeFlags diff --git a/compiler/src/dotty/tools/dotc/core/Periods.scala b/compiler/src/dotty/tools/dotc/core/Periods.scala index 019c5932b3c9..60226eb59fe0 100644 --- a/compiler/src/dotty/tools/dotc/core/Periods.scala +++ b/compiler/src/dotty/tools/dotc/core/Periods.scala @@ -1,6 +1,10 @@ -package dotty.tools.dotc.core +package dotty.tools +package dotc +package core import Contexts.* +import printing.* +import Texts.* import Phases.unfusedPhases object Periods { @@ -35,7 +39,7 @@ object Periods { * * // Dmitry: sign == 0 isn't actually always true, in some cases phaseId == -1 is used for shifts, that easily creates code < 0 */ - class Period(val code: Int) extends AnyVal { + class Period(val code: Int) extends AnyVal with Showable { /** The run identifier of this period. */ def runId: RunId = code >>> (PhaseWidth * 2) @@ -97,7 +101,25 @@ object Periods { this.firstPhaseId min that.firstPhaseId, this.lastPhaseId max that.lastPhaseId) - override def toString: String = s"Period($firstPhaseId..$lastPhaseId, run = $runId)" + def toText(p: Printer): Text = + inContext(p.printerContext): + this match + case Nowhere => "Nowhere" + case InitialPeriod => "InitialPeriod" + case InvalidPeriod => "InvalidPeriod" + case Period(NoRunId, 0, PhaseMask) => s"Period(NoRunId.all)" + case Period(runId, 0, PhaseMask) => s"Period($runId.all)" + case Period(runId, p1, pn) if p1 == pn => s"Period($runId.$p1(${ctx.base.phases(p1)}))" + case Period(runId, p1, pn) => s"Period($runId.$p1(${ctx.base.phases(p1)})-$pn(${ctx.base.phases(pn)}))" + + override def toString: String = this match + case Nowhere => "Nowhere" + case InitialPeriod => "InitialPeriod" + case InvalidPeriod => "InvalidPeriod" + case Period(NoRunId, 0, PhaseMask) => s"Period(NoRunId.all)" + case Period(runId, 0, PhaseMask) => s"Period($runId.all)" + case Period(runId, p1, pn) if p1 == pn => s"Period($runId.$p1)" + case Period(runId, p1, pn) => s"Period($runId.$p1-$pn)" def ==(that: Period): Boolean = this.code == that.code def !=(that: Period): Boolean = this.code != that.code @@ -116,6 +138,17 @@ object Periods { /** The interval consisting of all periods of given run id */ def allInRun(rid: RunId): Period = apply(rid, 0, PhaseMask) + + def unapply(p: Period): Extractor = new Extractor(p.code) + + final class Extractor(private val code: Int) extends AnyVal { + private def p = new Period(code) + def isEmpty: false = false + def get: this.type = this + def _1 = p.runId + def _2 = p.firstPhaseId + def _3 = p.lastPhaseId + } } inline val NowhereCode = 0 diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala index 7df5a7fa3c09..d6387ea1fe46 100644 --- a/compiler/src/dotty/tools/dotc/core/Scopes.scala +++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala @@ -159,19 +159,28 @@ object Scopes { } /** The scope that keeps only those symbols from this scope that match the - * given predicates. If all symbols match, returns the scope itself, otherwise - * a copy with the matching symbols. + * given predicates, renamed with the given rename function. + * If renaming is not needed for a symbol, the rename function should return `null`. + * If all symbols match and none are renamed, returns the scope itself, otherwise + * a copy with the matching and renamed symbols. */ - final def filteredScope(p: Symbol => Boolean)(using Context): Scope = { + final def filteredScope( + keep: Symbol => Boolean, + rename: Symbol => Name | Null = _ => null)(using Context): Scope = var result: MutableScope | Null = null - for (sym <- iterator) - if (!p(sym)) { - if (result == null) result = cloneScope + for sym <- iterator do + def drop() = + if result == null then result = cloneScope result.nn.unlink(sym) - } + if keep(sym) then + val newName = rename(sym) + if newName != null then + drop() + result.nn.enter(newName, sym) + else + drop() // TODO: improve flow typing to handle this case - if (result == null) this else result.uncheckedNN - } + if result == null then this else result.uncheckedNN def implicitDecls(using Context): List[TermRef] = Nil diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 253a45ffd7a8..a2e78add1338 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -537,6 +537,7 @@ object StdNames { val ManifestFactory: N = "ManifestFactory" val manifestToTypeTag: N = "manifestToTypeTag" val map: N = "map" + val maybeCapability: N = "maybeCapability" val materializeClassTag: N = "materializeClassTag" val materializeWeakTypeTag: N = "materializeWeakTypeTag" val materializeTypeTag: N = "materializeTypeTag" @@ -583,6 +584,7 @@ object StdNames { val releaseFence : N = "releaseFence" val retains: N = "retains" val retainsByName: N = "retainsByName" + val retainsCap: N = "retainsCap" val rootMirror : N = "rootMirror" val run: N = "run" val runOrElse: N = "runOrElse" diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index b1e85f2b4f90..13eb5ce8b5ba 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -167,12 +167,17 @@ object SymDenotations { println(i"${" " * indent}completed $name in $owner") } } - else { - if (myFlags.is(Touched)) - throw CyclicReference(this)(using ctx.withOwner(symbol)) - myFlags |= Touched - atPhase(validFor.firstPhaseId)(completer.complete(this)) - } + else + val traceCycles = CyclicReference.isTraced + try + if traceCycles then + CyclicReference.pushTrace("compute the signature of ", symbol, "") + if myFlags.is(Touched) then + throw CyclicReference(this)(using ctx.withOwner(symbol)) + myFlags |= Touched + atPhase(validFor.firstPhaseId)(completer.complete(this)) + finally + if traceCycles then CyclicReference.popTrace() protected[dotc] def info_=(tp: Type): Unit = { /* // DEBUG @@ -1197,7 +1202,14 @@ object SymDenotations { * is defined in Scala 3 and is neither abstract nor open. */ final def isEffectivelySealed(using Context): Boolean = - isOneOf(FinalOrSealed) || isClass && !isOneOf(EffectivelyOpenFlags) + isOneOf(FinalOrSealed) + || isClass && (!isOneOf(EffectivelyOpenFlags) + || isLocalToCompilationUnit) + + final def isLocalToCompilationUnit(using Context): Boolean = + is(Private) + || owner.ownersIterator.exists(_.isTerm) + || accessBoundary(defn.RootClass).isContainedIn(symbol.topLevelClass) final def isTransparentClass(using Context): Boolean = is(TransparentType) @@ -2180,7 +2192,7 @@ object SymDenotations { Stats.record("basetype cache entries") if (!baseTp.exists) Stats.record("basetype cache NoTypes") } - if (!tp.isProvisional && !CapturingType.isUncachable(tp)) + if !(tp.isProvisional || CapturingType.isUncachable(tp) || ctx.gadt.isNarrowing) then btrCache(tp) = baseTp else btrCache.remove(tp) // Remove any potential sentinel value @@ -2971,7 +2983,10 @@ object SymDenotations { def apply(clsd: ClassDenotation)(implicit onBehalf: BaseData, ctx: Context) : (List[ClassSymbol], BaseClassSet) = { assert(isValid) + val traceCycles = CyclicReference.isTraced try + if traceCycles then + CyclicReference.pushTrace("compute the base classes of ", clsd.symbol, "") if (cache != null) cache.uncheckedNN else { if (locked) throw CyclicReference(clsd) @@ -2984,7 +2999,9 @@ object SymDenotations { else onBehalf.signalProvisional() computed } - finally addDependent(onBehalf) + finally + if traceCycles then CyclicReference.popTrace() + addDependent(onBehalf) } def sameGroup(p1: Phase, p2: Phase) = p1.sameParentsStartId == p2.sameParentsStartId diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index ddddaf9b07fb..32a2da8b46b6 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -19,9 +19,7 @@ import DenotTransformers.* import StdNames.* import NameOps.* import NameKinds.LazyImplicitName -import ast.tpd -import tpd.{Tree, TreeProvider, TreeOps} -import ast.TreeTypeMap +import ast.*, tpd.* import Constants.Constant import Variances.Variance import reporting.Message @@ -134,7 +132,7 @@ object Symbols extends SymUtils { final def lastKnownDenotation: SymDenotation = lastDenot - private[core] def defRunId: RunId = + private[dotc] def defRunId: RunId = lastDenot.validFor.runId private inline def associatedFileMatches(inline filter: AbstractFile => Boolean)(using Context): Boolean = @@ -325,13 +323,26 @@ object Symbols extends SymUtils { /** A symbol related to `sym` that is defined in source code. * - * @see enclosingSourceSymbols + * @see [[interactive.Interactive.enclosingSourceSymbols]] */ @annotation.tailrec final def sourceSymbol(using Context): Symbol = if (!denot.exists) this else if (denot.is(ModuleVal)) this.moduleClass.sourceSymbol // The module val always has a zero-extent position + else if denot.is(ExportedType) then + denot.info.dropAlias.finalResultType.typeConstructor match + case tp: NamedType => tp.symbol.sourceSymbol + case _ => this + else if denot.is(ExportedTerm) then + val root = denot.maybeOwner match + case cls: ClassSymbol => cls.rootTreeContaining(name.toString) + case _ => EmptyTree + val targets = root.collectSubTrees: + case tree: DefDef if tree.symbol == denot.symbol => methPart(tree.rhs).tpe + targets.match + case (tp: NamedType) :: _ => tp.symbol.sourceSymbol + case _ => this else if (denot.is(Synthetic)) { val linked = denot.linkedClass if (linked.exists && !linked.is(Synthetic)) diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 38f975a8dac8..b04978357508 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -2318,40 +2318,35 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling else if !tp2.exists || (tp2 eq WildcardType) then tp1 else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2 else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp1 - else tp2 match - case tp2: LazyRef => - glb(tp1, tp2.ref) - case _ => - tp1 match - case tp1: LazyRef => - glb(tp1.ref, tp2) - case _ => - val tp1a = dropIfSuper(tp1, tp2) - if tp1a ne tp1 then glb(tp1a, tp2) - else - val tp2a = dropIfSuper(tp2, tp1) - if tp2a ne tp2 then glb(tp1, tp2a) - else tp2 match // normalize to disjunctive normal form if possible. - case tp2 @ OrType(tp21, tp22) => - lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft) - case _ => - tp1 match - case tp1 @ OrType(tp11, tp12) => - lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft) - case tp1: ConstantType => - tp2 match - case tp2: ConstantType => - // Make use of the fact that the intersection of two constant types - // types which are not subtypes of each other is known to be empty. - // Note: The same does not apply to singleton types in general. - // E.g. we could have a pattern match against `x.type & y.type` - // which might succeed if `x` and `y` happen to be the same ref - // at run time. It would not work to replace that with `Nothing`. - // However, maybe we can still apply the replacement to - // types which are not explicitly written. - NothingType - case _ => andType(tp1, tp2) + else + def mergedGlb(tp1: Type, tp2: Type): Type = + val tp1a = dropIfSuper(tp1, tp2) + if tp1a ne tp1 then glb(tp1a, tp2) + else + val tp2a = dropIfSuper(tp2, tp1) + if tp2a ne tp2 then glb(tp1, tp2a) + else tp2 match // normalize to disjunctive normal form if possible. + case tp2 @ OrType(tp21, tp22) => + lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft) + case _ => + tp1 match + case tp1 @ OrType(tp11, tp12) => + lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft) + case tp1: ConstantType => + tp2 match + case tp2: ConstantType => + // Make use of the fact that the intersection of two constant types + // types which are not subtypes of each other is known to be empty. + // Note: The same does not apply to singleton types in general. + // E.g. we could have a pattern match against `x.type & y.type` + // which might succeed if `x` and `y` happen to be the same ref + // at run time. It would not work to replace that with `Nothing`. + // However, maybe we can still apply the replacement to + // types which are not explicitly written. + NothingType case _ => andType(tp1, tp2) + case _ => andType(tp1, tp2) + mergedGlb(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef)) } def widenInUnions(using Context): Boolean = @@ -2390,7 +2385,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling if ((tp1 ne tp1w) || (tp2 ne tp2w)) lub(tp1w, tp2w, canConstrain = canConstrain, isSoft = isSoft) else orType(tp1w, tp2w, isSoft = isSoft) // no need to check subtypes again } - mergedLub(tp1.stripLazyRef, tp2.stripLazyRef) + mergedLub(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef)) } /** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using @@ -2508,6 +2503,19 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling NoType } + /** There's a window of vulnerability between ElimByName and Erasure where some + * ExprTypes `=> T` that appear as parameters of function types are not yet converted + * to by-name functions `() ?=> T`. These would cause an assertion violation when + * used as operands of glb or lub. We fix this on the fly here. As explained in + * ElimByName, we can't fix it beforehand by mapping all occurrences of `=> T` to + * `() ?=> T` since that could lead to cycles. + */ + private def dropExpr(tp: Type): Type = tp match + case ExprType(rt) if (Phases.elimByNamePhase <= ctx.phase) && !ctx.erasedTypes => + defn.ByNameFunction(rt) + case _ => + tp + private def andTypeGen(tp1: Type, tp2: Type, op: (Type, Type) => Type, original: (Type, Type) => Type = _ & _, isErased: Boolean = ctx.erasedTypes): Type = trace(s"andTypeGen(${tp1.show}, ${tp2.show})", subtyping, show = true) { val t1 = distributeAnd(tp1, tp2) @@ -3436,7 +3444,8 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) { case MatchTypeCasePattern.BaseTypeTest(classType, argPatterns, needsConcreteScrut) => val cls = classType.classSymbol.asClass scrut.baseType(cls) match - case base @ AppliedType(baseTycon, baseArgs) if baseTycon =:= classType => + case base @ AppliedType(baseTycon, baseArgs) => + // #19445 Don't check the prefix of baseTycon here; it is handled by `scrut <:< instantiatedPat`. val innerScrutIsWidenedAbstract = scrutIsWidenedAbstract || (needsConcreteScrut && !isConcrete(scrut)) // no point in checking concreteness if it does not need to be concrete diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 48559787c6a1..0474aff4087a 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -725,14 +725,14 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst tr1 :: trs1.filterNot(_.isAnyRef) case nil => nil } - var erasedDecls = decls.filteredScope(sym => !sym.isType || sym.isClass).openForMutations - for dcl <- erasedDecls.iterator do - if dcl.lastKnownDenotation.unforcedAnnotation(defn.TargetNameAnnot).isDefined - && dcl.targetName != dcl.name - then - if erasedDecls eq decls then erasedDecls = erasedDecls.cloneScope - erasedDecls.unlink(dcl) - erasedDecls.enter(dcl.targetName, dcl) + val erasedDecls = decls.filteredScope( + keep = sym => !sym.isType || sym.isClass, + rename = sym => + if sym.lastKnownDenotation.unforcedAnnotation(defn.TargetNameAnnot).isDefined + && sym.targetName != sym.name + then sym.targetName + else null + ) val selfType1 = if cls.is(Module) then cls.sourceModule.termRef else NoType tp.derivedClassInfo(NoPrefix, erasedParents, erasedDecls, selfType1) // can't replace selftype by NoType because this would lose the sourceModule link @@ -814,7 +814,8 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst eraseResult(tp1.resultType) match case rt: MethodType => rt case rt => MethodType(Nil, Nil, rt) - case tp1 => this(tp1) + case tp1 => + this(tp1) private def eraseDerivedValueClass(tp: Type)(using Context): Type = { val cls = tp.classSymbol.asClass diff --git a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala index 76be98d9bd65..240bc4eebd84 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErrors.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErrors.scala @@ -12,7 +12,9 @@ import Denotations.* import Decorators.* import reporting.* import ast.untpd +import util.Property import config.Printers.{cyclicErrors, noPrinter} +import collection.mutable import scala.annotation.constructorOnly @@ -27,6 +29,7 @@ abstract class TypeError(using creationContext: Context) extends Exception(""): || ctx.settings.YdebugTypeError.value || ctx.settings.YdebugError.value || ctx.settings.YdebugUnpickling.value + || ctx.settings.YdebugCyclic.value override def fillInStackTrace(): Throwable = if computeStackTrace then super.fillInStackTrace().nn @@ -72,8 +75,7 @@ extends TypeError: def explanation: String = s"$op $details" private def recursions: List[RecursionOverflow] = { - import scala.collection.mutable.ListBuffer - val result = ListBuffer.empty[RecursionOverflow] + val result = mutable.ListBuffer.empty[RecursionOverflow] @annotation.tailrec def loop(throwable: Throwable): List[RecursionOverflow] = throwable match { case ro: RecursionOverflow => result += ro @@ -135,7 +137,10 @@ end handleRecursive * so it requires knowing denot already. * @param denot */ -class CyclicReference(val denot: SymDenotation)(using Context) extends TypeError: +class CyclicReference( + val denot: SymDenotation, + val optTrace: Option[Array[CyclicReference.TraceElement]])(using Context) +extends TypeError: var inImplicitSearch: Boolean = false val cycleSym = denot.symbol @@ -161,11 +166,11 @@ class CyclicReference(val denot: SymDenotation)(using Context) extends TypeError cx.tree match { case tree: untpd.ValOrDefDef if !tree.tpt.typeOpt.exists => if (inImplicitSearch) - TermMemberNeedsResultTypeForImplicitSearch(cycleSym) + TermMemberNeedsResultTypeForImplicitSearch(this) else if (isMethod) - OverloadedOrRecursiveMethodNeedsResultType(cycleSym) + OverloadedOrRecursiveMethodNeedsResultType(this) else if (isVal) - RecursiveValueNeedsResultType(cycleSym) + RecursiveValueNeedsResultType(this) else errorMsg(cx.outer) case _ => @@ -174,22 +179,38 @@ class CyclicReference(val denot: SymDenotation)(using Context) extends TypeError // Give up and give generic errors. else if (cycleSym.isOneOf(GivenOrImplicitVal, butNot = Method) && cycleSym.owner.isTerm) - CyclicReferenceInvolvingImplicit(cycleSym) + CyclicReferenceInvolvingImplicit(this) else - CyclicReferenceInvolving(denot) + CyclicReferenceInvolving(this) errorMsg(ctx) end toMessage object CyclicReference: + def apply(denot: SymDenotation)(using Context): CyclicReference = - val ex = new CyclicReference(denot) + val ex = new CyclicReference(denot, ctx.property(Trace).map(_.toArray)) if ex.computeStackTrace then cyclicErrors.println(s"Cyclic reference involving $denot") val sts = ex.getStackTrace.asInstanceOf[Array[StackTraceElement]] for (elem <- sts take 200) cyclicErrors.println(elem.toString) ex + + type TraceElement = (/*prefix:*/ String, Symbol, /*suffix:*/ String) + type Trace = mutable.ArrayBuffer[TraceElement] + val Trace = Property.Key[Trace] + + def isTraced(using Context) = + ctx.property(CyclicReference.Trace).isDefined + + def pushTrace(info: TraceElement)(using Context): Unit = + for buf <- ctx.property(CyclicReference.Trace) do + buf += info + + def popTrace()(using Context): Unit = + for buf <- ctx.property(CyclicReference.Trace) do + buf.dropRightInPlace(1) end CyclicReference class UnpicklingError(denot: Denotation, where: String, cause: Throwable)(using Context) extends TypeError: diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 2005aa702782..587c52688456 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -540,18 +540,6 @@ object TypeOps: val sym = tp.symbol forbidden.contains(sym) - /** We need to split the set into upper and lower approximations - * only if it contains a local element. The idea here is that at the - * time we perform an `avoid` all local elements are already accounted for - * and no further elements will be added afterwards. So we can just keep - * the set as it is. See comment by @linyxus on #16261. - */ - override def needsRangeIfInvariant(refs: CaptureSet): Boolean = - refs.elems.exists { - case ref: TermRef => toAvoid(ref) - case _ => false - } - override def apply(tp: Type): Type = tp match case tp: TypeVar if mapCtx.typerState.constraint.contains(tp) => val lo = TypeComparer.instanceType( diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index fba5f3f56648..b151dcdf8270 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -38,7 +38,7 @@ import config.Printers.{core, typr, matchTypes} import reporting.{trace, Message} import java.lang.ref.WeakReference import compiletime.uninitialized -import cc.{CapturingType, CaptureSet, derivedCapturingType, isBoxedCapturing, RetainingType, isCaptureChecking} +import cc.{CapturingType, CaptureSet, derivedCapturingType, isBoxedCapturing, isCaptureChecking, isRetains, isRetainsLike} import CaptureSet.{CompareResult, IdempotentCaptRefMap, IdentityCaptRefMap} import scala.annotation.internal.sharable @@ -197,7 +197,7 @@ object Types extends TypeUtils { */ def isRef(sym: Symbol, skipRefined: Boolean = true)(using Context): Boolean = this match { case this1: TypeRef => - this1.info match { // see comment in Namer#typeDefSig + this1.info match { // see comment in Namer#TypeDefCompleter#typeSig case TypeAlias(tp) => tp.isRef(sym, skipRefined) case _ => this1.symbol eq sym } @@ -657,6 +657,8 @@ object Types extends TypeUtils { tp.superType.baseClasses case tp: ClassInfo => tp.cls.classDenot.baseClasses + case tp: WildcardType => + tp.effectiveBounds.hi.baseClasses case _ => Nil catch case ex: Throwable => handleRecursive("base classes of", this.show, ex) @@ -843,7 +845,9 @@ object Types extends TypeUtils { safeIntersection = ctx.base.pendingMemberSearches.contains(name)) joint match case joint: SingleDenotation - if isRefinedMethod && rinfo <:< joint.info => + if isRefinedMethod + && (rinfo <:< joint.info + || name == nme.apply && defn.isFunctionType(tp.parent)) => // use `rinfo` to keep the right parameter names for named args. See i8516.scala. joint.derivedSingleDenotation(joint.symbol, rinfo, pre, isRefinedMethod) case _ => @@ -2196,7 +2200,11 @@ object Types extends TypeUtils { /** Is this a reach reference of the form `x*`? */ def isReach(using Context): Boolean = false // overridden in AnnotatedType + /** Is this a maybe reference of the form `x?`? */ + def isMaybe(using Context): Boolean = false // overridden in AnnotatedType + def stripReach(using Context): CaptureRef = this // overridden in AnnotatedType + def stripMaybe(using Context): CaptureRef = this // overridden in AnnotatedType /** Is this reference the generic root capability `cap` ? */ def isRootCapability(using Context): Boolean = false @@ -4023,7 +4031,7 @@ object Types extends TypeUtils { mapOver(tp) case AnnotatedType(parent, ann) if ann.refersToParamOf(thisLambdaType) => val parent1 = mapOver(parent) - if ann.symbol == defn.RetainsAnnot || ann.symbol == defn.RetainsByNameAnnot then + if ann.symbol.isRetainsLike then range( AnnotatedType(parent1, CaptureSet.empty.toRegularAnnotation(ann.symbol)), AnnotatedType(parent1, CaptureSet.universal.toRegularAnnotation(ann.symbol))) @@ -5035,7 +5043,7 @@ object Types extends TypeUtils { record("MatchType.reduce computed") if (myReduced != null) record("MatchType.reduce cache miss") myReduced = - trace(i"reduce match type $this $hashCode", matchTypes, show = true)(inMode(Mode.Type) { + trace(i"reduce match type $this $hashCode", matchTypes, show = true)(withMode(Mode.Type) { def matchCases(cmp: TrackingTypeComparer): Type = val saved = ctx.typerState.snapshot() try cmp.matchCases(scrutinee.normalized, cases.map(MatchTypeCaseSpec.analyze(_))) @@ -5313,10 +5321,10 @@ object Types extends TypeUtils { else if (clsd.is(Module)) givenSelf else if (ctx.erasedTypes) appliedRef else givenSelf.dealiasKeepAnnots match - case givenSelf1 @ AnnotatedType(tp, ann) if ann.symbol == defn.RetainsAnnot => - givenSelf1.derivedAnnotatedType(tp & appliedRef, ann) + case givenSelf1 @ AnnotatedType(tp, ann) if ann.symbol.isRetains => + givenSelf1.derivedAnnotatedType(AndType.make(tp, appliedRef), ann) case _ => - AndType(givenSelf, appliedRef) + AndType.make(givenSelf, appliedRef) } selfTypeCache.nn } @@ -5616,14 +5624,21 @@ object Types extends TypeUtils { } override def isTrackableRef(using Context) = - isReach && parent.isTrackableRef + (isReach || isMaybe) && parent.isTrackableRef /** Is this a reach reference of the form `x*`? */ override def isReach(using Context): Boolean = annot.symbol == defn.ReachCapabilityAnnot - override def stripReach(using Context): SingletonCaptureRef = - (if isReach then parent else this).asInstanceOf[SingletonCaptureRef] + /** Is this a reach reference of the form `x*`? */ + override def isMaybe(using Context): Boolean = + annot.symbol == defn.MaybeCapabilityAnnot + + override def stripReach(using Context): CaptureRef = + if isReach then parent.asInstanceOf[CaptureRef] else this + + override def stripMaybe(using Context): CaptureRef = + if isMaybe then parent.asInstanceOf[CaptureRef] else this override def normalizedRef(using Context): CaptureRef = if isReach then AnnotatedType(stripReach.normalizedRef, annot) else this @@ -6473,15 +6488,6 @@ object Types extends TypeUtils { tp.derivedLambdaType(tp.paramNames, formals, restpe) } - /** Overridden in TypeOps.avoid and in CheckCaptures.substParamsMap */ - protected def needsRangeIfInvariant(refs: CaptureSet): Boolean = true - - override def mapCapturingType(tp: Type, parent: Type, refs: CaptureSet, v: Int): Type = - if v == 0 && needsRangeIfInvariant(refs) then - range(mapCapturingType(tp, parent, refs, -1), mapCapturingType(tp, parent, refs, 1)) - else - super.mapCapturingType(tp, parent, refs, v) - protected def reapply(tp: Type): Type = apply(tp) } diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala index 6ad71c5fd1ce..7a2232891a83 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala @@ -73,7 +73,10 @@ object ClassfileConstants { inline val CONSTANT_METHODHANDLE = 15 inline val CONSTANT_METHODTYPE = 16 + inline val CONSTANT_DYNAMIC = 17 inline val CONSTANT_INVOKEDYNAMIC = 18 + inline val CONSTANT_MODULE = 19 + inline val CONSTANT_PACKAGE = 20 // tags describing the type of a literal in attribute values inline val BYTE_TAG = 'B' diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 93ebcfeee62a..894d430fe54b 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -106,13 +106,14 @@ object ClassfileParser { (in.nextByte.toInt: @switch) match { case CONSTANT_UTF8 | CONSTANT_UNICODE => in.skip(in.nextChar) - case CONSTANT_CLASS | CONSTANT_STRING | CONSTANT_METHODTYPE => + case CONSTANT_CLASS | CONSTANT_STRING | CONSTANT_METHODTYPE + | CONSTANT_MODULE | CONSTANT_PACKAGE => in.skip(2) case CONSTANT_METHODHANDLE => in.skip(3) case CONSTANT_FIELDREF | CONSTANT_METHODREF | CONSTANT_INTFMETHODREF | CONSTANT_NAMEANDTYPE | CONSTANT_INTEGER | CONSTANT_FLOAT - | CONSTANT_INVOKEDYNAMIC => + | CONSTANT_INVOKEDYNAMIC | CONSTANT_DYNAMIC => in.skip(4) case CONSTANT_LONG | CONSTANT_DOUBLE => in.skip(8) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index b7a25cb75613..b95e4df663a1 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -141,20 +141,25 @@ class TreeUnpickler(reader: TastyReader, val mode = ctx.mode val source = ctx.source def complete(denot: SymDenotation)(using Context): Unit = - def fail(ex: Throwable) = - def where = - val f = denot.symbol.associatedFile - if f == null then "" else s" in $f" - throw UnpicklingError(denot, where, ex) + def where = + val f = denot.symbol.associatedFile + if f == null then "" else s" in $f" + def fail(ex: Throwable) = throw UnpicklingError(denot, where, ex) treeAtAddr(currentAddr) = + val traceCycles = CyclicReference.isTraced try + if traceCycles then + CyclicReference.pushTrace("read the definition of ", denot.symbol, where) atPhaseBeforeTransforms { new TreeReader(reader).readIndexedDef()( using ctx.withOwner(owner).withModeBits(mode).withSource(source)) } catch + case ex: CyclicReference => throw ex case ex: AssertionError => fail(ex) case ex: Exception => fail(ex) + finally + if traceCycles then CyclicReference.popTrace() } class TreeReader(val reader: TastyReader) { diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index f876c87e8920..806f39ee0425 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -151,7 +151,6 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas assert(moduleRoot.isTerm) checkVersion(using ictx) - checkScala2Stdlib(using ictx) private val loadingMirror = defn(using ictx) // was: mirrorThatLoaded(classRoot) @@ -238,9 +237,6 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas " in " + source) } - private def checkScala2Stdlib(using Context): Unit = - assert(!ctx.settings.YcompileScala2Library.value, "No Scala 2 libraries should be unpickled under -Ycompile-scala2-library") - /** The `decls` scope associated with given symbol */ protected def symScope(sym: Symbol): Scope = symScopes.getOrElseUpdate(sym, newScope(0)) diff --git a/compiler/src/dotty/tools/dotc/coverage/Location.scala b/compiler/src/dotty/tools/dotc/coverage/Location.scala index 88893709b8bd..de1a3db710a3 100644 --- a/compiler/src/dotty/tools/dotc/coverage/Location.scala +++ b/compiler/src/dotty/tools/dotc/coverage/Location.scala @@ -31,9 +31,9 @@ object Location: val ownerDenot = ctx.owner.denot val enclosingClass = ownerDenot.enclosingClass - val packageName = ownerDenot.enclosingPackageClass.fullName.toSimpleName.toString - val className = enclosingClass.name.toSimpleName.toString - val methodName = ownerDenot.enclosingMethod.name.toSimpleName.toString + val packageName = ownerDenot.enclosingPackageClass.fullName.toSimpleName.show + val className = enclosingClass.name.toSimpleName.show + val methodName = ownerDenot.enclosingMethod.name.toSimpleName.show val classType: String = if enclosingClass.is(Trait) then "Trait" diff --git a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala index 4860913bdc63..230092898051 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala @@ -172,10 +172,10 @@ object Inlines: /** Try to inline a pattern with an inline unapply method. Fail with error if the maximal * inline depth is exceeded. * - * @param unapp The tree of the pattern to inline + * @param fun The function of an Unapply node * @return An `Unapply` with a `fun` containing the inlined call to the unapply */ - def inlinedUnapply(unapp: tpd.UnApply)(using Context): Tree = + def inlinedUnapplyFun(fun: tpd.Tree)(using Context): Tree = // We cannot inline the unapply directly, since the pattern matcher relies on unapply applications // as signposts what to do. On the other hand, we can do the inlining only in typer, not afterwards. // So the trick is to create a "wrapper" unapply in an anonymous class that has the inlined unapply @@ -189,7 +189,6 @@ object Inlines: // transforms the patterns into terms, the `inlinePatterns` phase removes this anonymous class by β-reducing // the call to the `unapply`. - val fun = unapp.fun val sym = fun.symbol val newUnapply = AnonClass(ctx.owner, List(defn.ObjectType), sym.coord) { cls => @@ -199,7 +198,7 @@ object Inlines: val unapplyInfo = fun.tpe.widen val unapplySym = newSymbol(cls, sym.name.toTermName, Synthetic | Method, unapplyInfo, coord = sym.coord).entered - val unapply = DefDef(unapplySym.asTerm, argss => fun.appliedToArgss(argss).withSpan(unapp.span)) + val unapply = DefDef(unapplySym.asTerm, argss => fun.appliedToArgss(argss).withSpan(fun.span)) if sym.is(Transparent) then // Inline the body and refine the type of the unapply method @@ -214,9 +213,8 @@ object Inlines: List(unapply) } - val newFun = newUnapply.select(sym.name).withSpan(unapp.span) - cpy.UnApply(unapp)(fun = newFun) - end inlinedUnapply + newUnapply.select(sym.name).withSpan(fun.span) + end inlinedUnapplyFun /** For a retained inline method, another method that keeps track of * the body that is kept at runtime. For instance, an inline method @@ -443,6 +441,9 @@ object Inlines: unrollTupleTypes(tail).map(head :: _) case tpe: TermRef if tpe.symbol == defn.EmptyTupleModule => Some(Nil) + case tpRef: TypeRef => tpRef.info match + case MatchAlias(alias) => unrollTupleTypes(alias.tryNormalize) + case _ => None case _ => None diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 6e91254c2d72..5237f19d19ae 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -1,6 +1,7 @@ package dotty.tools.dotc.interactive import dotty.tools.dotc.ast.untpd +import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.ast.NavigateAST import dotty.tools.dotc.config.Printers.interactiv import dotty.tools.dotc.core.Contexts.* @@ -19,6 +20,8 @@ import dotty.tools.dotc.core.TypeError import dotty.tools.dotc.core.Phases import dotty.tools.dotc.core.Types.{AppliedType, ExprType, MethodOrPoly, NameFilter, NoType, RefinedType, TermRef, Type, TypeProxy} import dotty.tools.dotc.parsing.Tokens +import dotty.tools.dotc.typer.Implicits.SearchSuccess +import dotty.tools.dotc.typer.Inferencing import dotty.tools.dotc.util.Chars import dotty.tools.dotc.util.SourcePosition @@ -28,6 +31,7 @@ import dotty.tools.dotc.core.ContextOps.localContext import dotty.tools.dotc.core.Names import dotty.tools.dotc.core.Types import dotty.tools.dotc.core.Symbols +import dotty.tools.dotc.core.Constants /** * One of the results of a completion query. @@ -42,15 +46,35 @@ case class Completion(label: String, description: String, symbols: List[Symbol]) object Completion: - import dotty.tools.dotc.ast.tpd.* - /** Get possible completions from tree at `pos` * * @return offset and list of symbols for possible completions */ def completions(pos: SourcePosition)(using Context): (Int, List[Completion]) = - val path: List[Tree] = Interactive.pathTo(ctx.compilationUnit.tpdTree, pos.span) - computeCompletions(pos, path)(using Interactive.contextOfPath(path).withPhase(Phases.typerPhase)) + val tpdPath = Interactive.pathTo(ctx.compilationUnit.tpdTree, pos.span) + val completionContext = Interactive.contextOfPath(tpdPath).withPhase(Phases.typerPhase) + inContext(completionContext): + val untpdPath = Interactive.resolveTypedOrUntypedPath(tpdPath, pos) + val mode = completionMode(untpdPath, pos) + val rawPrefix = completionPrefix(untpdPath, pos) + val completions = rawCompletions(pos, mode, rawPrefix, tpdPath, untpdPath) + + postProcessCompletions(untpdPath, completions, rawPrefix) + + /** Get possible completions from tree at `pos` + * This method requires manually computing the mode, prefix and paths. + * + * @return completion map of name to list of denotations + */ + def rawCompletions( + pos: SourcePosition, + mode: Mode, + rawPrefix: String, + tpdPath: List[tpd.Tree], + untpdPath: List[untpd.Tree] + )(using Context): CompletionMap = + val adjustedPath = typeCheckExtensionConstructPath(untpdPath, tpdPath, pos) + computeCompletions(pos, mode, rawPrefix, adjustedPath) /** * Inspect `path` to determine what kinds of symbols should be considered. @@ -63,20 +87,32 @@ object Completion: * Otherwise, provide no completion suggestion. */ def completionMode(path: List[untpd.Tree], pos: SourcePosition): Mode = - path match - case untpd.Ident(_) :: untpd.Import(_, _) :: _ => Mode.ImportOrExport - case untpd.Ident(_) :: (_: untpd.ImportSelector) :: _ => Mode.ImportOrExport - case (ref: untpd.RefTree) :: _ => - if (ref.name.isTermName) Mode.Term - else if (ref.name.isTypeName) Mode.Type - else Mode.None - case (sel: untpd.ImportSelector) :: _ => - if sel.imported.span.contains(pos.span) then Mode.ImportOrExport - else Mode.None // Can't help completing the renaming + val completionSymbolKind: Mode = + path match + case untpd.Ident(_) :: untpd.Import(_, _) :: _ => Mode.ImportOrExport + case untpd.Ident(_) :: (_: untpd.ImportSelector) :: _ => Mode.ImportOrExport + case untpd.Literal(Constants.Constant(_: String)) :: _ => Mode.Term // literal completions + case (ref: untpd.RefTree) :: _ => + if (ref.name.isTermName) Mode.Term + else if (ref.name.isTypeName) Mode.Type + else Mode.None + + case (sel: untpd.ImportSelector) :: _ => + if sel.imported.span.contains(pos.span) then Mode.ImportOrExport + else Mode.None // Can't help completing the renaming + + case (_: untpd.ImportOrExport) :: _ => Mode.ImportOrExport + case _ => Mode.None + + val completionKind: Mode = + path match + case Nil | (_: untpd.PackageDef) :: _ => Mode.None + case untpd.Ident(_) :: (_: untpd.ImportSelector) :: _ => Mode.Member + case (_: untpd.Select) :: _ => Mode.Member + case _ => Mode.Scope - case (_: untpd.ImportOrExport) :: _ => Mode.ImportOrExport - case _ => Mode.None + completionSymbolKind | completionKind /** When dealing with <errors> in varios palces we check to see if they are * due to incomplete backticks. If so, we ensure we get the full prefix @@ -99,12 +135,18 @@ object Completion: * returned prefix should be considered. */ def completionPrefix(path: List[untpd.Tree], pos: SourcePosition)(using Context): String = + def fallback: Int = + var i = pos.point - 1 + while i >= 0 && Chars.isIdentifierPart(pos.source.content()(i)) do i -= 1 + i + 1 + path match case (sel: untpd.ImportSelector) :: _ => completionPrefix(sel.imported :: Nil, pos) case untpd.Ident(_) :: (sel: untpd.ImportSelector) :: _ if !sel.isGiven => - completionPrefix(sel.imported :: Nil, pos) + if sel.isWildcard then pos.source.content()(pos.point - 1).toString + else completionPrefix(sel.imported :: Nil, pos) case (tree: untpd.ImportOrExport) :: _ => tree.selectors.find(_.span.contains(pos.span)).map: selector => @@ -119,34 +161,19 @@ object Completion: case (ident: untpd.Ident) :: _ if ident.name == nme.ERROR => checkBacktickPrefix(ident.source.content(), ident.span.start, ident.span.end) - case (ref: untpd.RefTree) :: _ => - if (ref.name == nme.ERROR) "" - else ref.name.toString.take(pos.span.point - ref.span.point) + case (tree: untpd.RefTree) :: _ if tree.name != nme.ERROR => + tree.name.toString.take(pos.span.point - tree.span.point) + + case _ => pos.source.content.slice(fallback, pos.point).mkString - case _ => "" end completionPrefix /** Inspect `path` to determine the offset where the completion result should be inserted. */ def completionOffset(untpdPath: List[untpd.Tree]): Int = - untpdPath match { + untpdPath match case (ref: untpd.RefTree) :: _ => ref.span.point case _ => 0 - } - - /** Some information about the trees is lost after Typer such as Extension method construct - * is expanded into methods. In order to support completions in those cases - * we have to rely on untyped trees and only when types are necessary use typed trees. - */ - def resolveTypedOrUntypedPath(tpdPath: List[Tree], pos: SourcePosition)(using Context): List[untpd.Tree] = - lazy val untpdPath: List[untpd.Tree] = NavigateAST - .pathTo(pos.span, List(ctx.compilationUnit.untpdTree), true).collect: - case untpdTree: untpd.Tree => untpdTree - - tpdPath match - case (_: Bind) :: _ => tpdPath - case (_: untpd.TypTree) :: _ => tpdPath - case _ => untpdPath /** Handle case when cursor position is inside extension method construct. * The extension method construct is then desugared into methods, and consturct parameters @@ -159,8 +186,8 @@ object Completion: * @return Typed path to the parameter of the extension construct if found or tpdPath */ private def typeCheckExtensionConstructPath( - untpdPath: List[untpd.Tree], tpdPath: List[Tree], pos: SourcePosition - )(using Context): List[Tree] = + untpdPath: List[untpd.Tree], tpdPath: List[tpd.Tree], pos: SourcePosition + )(using Context): List[tpd.Tree] = untpdPath.collectFirst: case untpd.ExtMethods(paramss, _) => val enclosingParam = paramss.flatten.find(_.span.contains(pos.span)) @@ -170,38 +197,41 @@ object Completion: Interactive.pathTo(typedEnclosingParam, pos.span) .flatten.getOrElse(tpdPath) - private def computeCompletions(pos: SourcePosition, tpdPath: List[Tree])(using Context): (Int, List[Completion]) = - val path0 = resolveTypedOrUntypedPath(tpdPath, pos) - val mode = completionMode(path0, pos) - val rawPrefix = completionPrefix(path0, pos) - + private def computeCompletions( + pos: SourcePosition, mode: Mode, rawPrefix: String, adjustedPath: List[tpd.Tree] + )(using Context): CompletionMap = val hasBackTick = rawPrefix.headOption.contains('`') val prefix = if hasBackTick then rawPrefix.drop(1) else rawPrefix - val completer = new Completer(mode, prefix, pos) - val adjustedPath = typeCheckExtensionConstructPath(path0, tpdPath, pos) - val completions = adjustedPath match - // Ignore synthetic select from `This` because in code it was `Ident` - // See example in dotty.tools.languageserver.CompletionTest.syntheticThis - case Select(qual @ This(_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions - case Select(qual, _) :: _ if qual.tpe.hasSimpleKind => completer.selectionCompletions(qual) - case Select(qual, _) :: _ => Map.empty - case (tree: ImportOrExport) :: _ => completer.directMemberCompletions(tree.expr) - case (_: untpd.ImportSelector) :: Import(expr, _) :: _ => completer.directMemberCompletions(expr) - case _ => completer.scopeCompletions - + val result = adjustedPath match + // Ignore synthetic select from `This` because in code it was `Ident` + // See example in dotty.tools.languageserver.CompletionTest.syntheticThis + case tpd.Select(qual @ tpd.This(_), _) :: _ if qual.span.isSynthetic => completer.scopeCompletions + case tpd.Select(qual, _) :: _ if qual.typeOpt.hasSimpleKind => completer.selectionCompletions(qual) + case tpd.Select(qual, _) :: _ => Map.empty + case (tree: tpd.ImportOrExport) :: _ => completer.directMemberCompletions(tree.expr) + case (_: untpd.ImportSelector) :: tpd.Import(expr, _) :: _ => completer.directMemberCompletions(expr) + case _ => completer.scopeCompletions + + interactiv.println(i"""completion info with pos = $pos, + | prefix = ${completer.prefix}, + | term = ${completer.mode.is(Mode.Term)}, + | type = ${completer.mode.is(Mode.Type)}, + | scope = ${completer.mode.is(Mode.Scope)}, + | member = ${completer.mode.is(Mode.Member)}""") + + result + + def postProcessCompletions(path: List[untpd.Tree], completions: CompletionMap, rawPrefix: String)(using Context): (Int, List[Completion]) = val describedCompletions = describeCompletions(completions) + val hasBackTick = rawPrefix.headOption.contains('`') val backtickedCompletions = describedCompletions.map(completion => backtickCompletions(completion, hasBackTick)) - val offset = completionOffset(path0) + interactiv.println(i"""completion resutls = $backtickedCompletions%, %""") - interactiv.println(i"""completion with pos = $pos, - | prefix = ${completer.prefix}, - | term = ${completer.mode.is(Mode.Term)}, - | type = ${completer.mode.is(Mode.Type)} - | results = $backtickedCompletions%, %""") + val offset = completionOffset(path) (offset, backtickedCompletions) def backtickCompletions(completion: Completion, hasBackTick: Boolean) = @@ -249,6 +279,16 @@ object Completion: if denot.isType then denot.symbol.showFullName else denot.info.widenTermRefExpr.show + given ScopeOrdering(using Context): Ordering[Seq[SingleDenotation]] with + val order = + List(defn.ScalaPredefModuleClass, defn.ScalaPackageClass, defn.JavaLangPackageClass) + + override def compare(x: Seq[SingleDenotation], y: Seq[SingleDenotation]): Int = + val owner0 = x.headOption.map(_.symbol.effectiveOwner).getOrElse(NoSymbol) + val owner1 = y.headOption.map(_.symbol.effectiveOwner).getOrElse(NoSymbol) + + order.indexOf(owner0) - order.indexOf(owner1) + /** Computes code completions depending on the context in which completion is requested * @param mode Should complete names of terms, types or both * @param prefix The prefix that all suggested completions should start with @@ -265,13 +305,22 @@ object Completion: * This mimics the logic for deciding what is ambiguous used by the compiler. * In general in case of a name clash symbols introduced in more deeply nested scopes * have higher priority and shadow previous definitions with the same name although: - * - imports with the same level of nesting cause an ambiguity + * - imports with the same level of nesting cause an ambiguity if they are in the same name space * - members and local definitions with the same level of nesting are allowed for overloading * - an import is ignored if there is a local definition or a member introduced in the same scope * (even if the import follows it syntactically) * - a more deeply nested import shadowing a member or a local definition causes an ambiguity */ def scopeCompletions(using context: Context): CompletionMap = + + /** Temporary data structure representing denotations with the same name introduced in a given scope + * as a member of a type, by a local definition or by an import clause + */ + case class ScopedDenotations private (denots: Seq[SingleDenotation], ctx: Context) + object ScopedDenotations: + def apply(denots: Seq[SingleDenotation], ctx: Context, includeFn: SingleDenotation => Boolean): ScopedDenotations = + ScopedDenotations(denots.filter(includeFn), ctx) + val mappings = collection.mutable.Map.empty[Name, List[ScopedDenotations]].withDefaultValue(List.empty) def addMapping(name: Name, denots: ScopedDenotations) = mappings(name) = mappings(name) :+ denots @@ -279,18 +328,18 @@ object Completion: ctx.outersIterator.foreach { case ctx @ given Context => if ctx.isImportContext then importedCompletions.foreach { (name, denots) => - addMapping(name, ScopedDenotations(denots, ctx)) + addMapping(name, ScopedDenotations(denots, ctx, include(_, name))) } else if ctx.owner.isClass then accessibleMembers(ctx.owner.thisType) .groupByName.foreach { (name, denots) => - addMapping(name, ScopedDenotations(denots, ctx)) + addMapping(name, ScopedDenotations(denots, ctx, include(_, name))) } else if ctx.scope ne EmptyScope then ctx.scope.toList.filter(symbol => include(symbol, symbol.name)) .flatMap(_.alternatives) .groupByName.foreach { (name, denots) => - addMapping(name, ScopedDenotations(denots, ctx)) + addMapping(name, ScopedDenotations(denots, ctx, include(_, name))) } } @@ -303,26 +352,22 @@ object Completion: def isSingleImport = denotss.length < 2 // import a.C // locally { import b.C } - def isImportedInDifferentScope = first.ctx.scope ne denotss(1).ctx.scope + def isImportedInDifferentScope = first.ctx.scope ne denotss(1).ctx.scope // import a.C // import a.C - def isSameSymbolImportedDouble = denotss.forall(_.denots == first.denots) - - def isScalaPackage(scopedDenots: ScopedDenotations) = - scopedDenots.denots.exists(_.info.typeSymbol.owner == defn.ScalaPackageClass) - - def isJavaLangPackage(scopedDenots: ScopedDenotations) = - scopedDenots.denots.exists(_.info.typeSymbol.owner == defn.JavaLangPackageClass) - - // For example - // import java.lang.annotation - // is shadowed by - // import scala.annotation - def isJavaLangAndScala = - try - denotss.forall(denots => isScalaPackage(denots) || isJavaLangPackage(denots)) - catch - case NonFatal(_) => false + def isSameSymbolImportedDouble = denotss.forall(_.denots == first.denots) + + // https://scala-lang.org/files/archive/spec/3.4/02-identifiers-names-and-scopes.html + // import java.lang.* + // { + // import scala.* + // { + // import Predef.* + // { /* source */ } + // } + // } + def notConflictingWithDefaults = // is imported symbol + denotss.filterNot(_.denots.exists(denot => Interactive.isImportedByDefault(denot.symbol))).size <= 1 denotss.find(!_.ctx.isImportContext) match { // most deeply nested member or local definition if not shadowed by an import @@ -331,13 +376,9 @@ object Completion: case None if isSingleImport || isImportedInDifferentScope || isSameSymbolImportedDouble => resultMappings += name -> first.denots - case None if isJavaLangAndScala => - denotss.foreach{ - denots => - if isScalaPackage(denots) then - resultMappings += name -> denots.denots - } - + case None if notConflictingWithDefaults => + val ordered = denotss.map(_.denots).sorted + resultMappings += name -> ordered.head case _ => } } @@ -347,8 +388,8 @@ object Completion: /** Widen only those types which are applied or are exactly nothing */ - def widenQualifier(qual: Tree)(using Context): Tree = - qual.tpe.widenDealias match + def widenQualifier(qual: tpd.Tree)(using Context): tpd.Tree = + qual.typeOpt.widenDealias match case widenedType if widenedType.isExactlyNothing => qual.withType(widenedType) case appliedType: AppliedType => qual.withType(appliedType) case _ => qual @@ -357,7 +398,7 @@ object Completion: * Direct members take priority over members from extensions * and so do members from extensions over members from implicit conversions */ - def selectionCompletions(qual: Tree)(using Context): CompletionMap = + def selectionCompletions(qual: tpd.Tree)(using Context): CompletionMap = val adjustedQual = widenQualifier(qual) implicitConversionMemberCompletions(adjustedQual) ++ @@ -367,11 +408,11 @@ object Completion: /** Completions for members of `qual`'s type. * These include inherited definitions but not members added by extensions or implicit conversions */ - def directMemberCompletions(qual: Tree)(using Context): CompletionMap = - if qual.tpe.isExactlyNothing then + def directMemberCompletions(qual: tpd.Tree)(using Context): CompletionMap = + if qual.typeOpt.isExactlyNothing then Map.empty else - accessibleMembers(qual.tpe).groupByName + accessibleMembers(qual.typeOpt).groupByName /** Completions introduced by imports directly in this context. * Completions from outer contexts are not included. @@ -414,17 +455,28 @@ object Completion: end importedCompletions /** Completions from implicit conversions including old style extensions using implicit classes */ - private def implicitConversionMemberCompletions(qual: Tree)(using Context): CompletionMap = - if qual.tpe.isExactlyNothing || qual.tpe.isNullType then + private def implicitConversionMemberCompletions(qual: tpd.Tree)(using Context): CompletionMap = + + def tryToInstantiateTypeVars(conversionTarget: SearchSuccess): Type = + try + val typingCtx = ctx.fresh + inContext(typingCtx): + val methodRefTree = tpd.ref(conversionTarget.ref, needLoad = false) + val convertedTree = ctx.typer.typedAheadExpr(untpd.Apply(untpd.TypedSplice(methodRefTree), untpd.TypedSplice(qual) :: Nil)) + Inferencing.fullyDefinedType(convertedTree.tpe, "", pos) + catch + case error => conversionTarget.tree.tpe // fallback to not fully defined type + + if qual.typeOpt.isExactlyNothing || qual.typeOpt.isNullType then Map.empty else implicitConversionTargets(qual)(using ctx.fresh.setExploreTyperState()) - .flatMap(accessibleMembers) + .flatMap { conversionTarget => accessibleMembers(tryToInstantiateTypeVars(conversionTarget)) } .toSeq .groupByName /** Completions from extension methods */ - private def extensionCompletions(qual: Tree)(using Context): CompletionMap = + private def extensionCompletions(qual: tpd.Tree)(using Context): CompletionMap = def asDefLikeType(tpe: Type): Type = tpe match case _: MethodOrPoly => tpe case _ => ExprType(tpe) @@ -432,7 +484,7 @@ object Completion: def tryApplyingReceiverToExtension(termRef: TermRef): Option[SingleDenotation] = ctx.typer.tryApplyingExtensionMethod(termRef, qual) .map { tree => - val tpe = asDefLikeType(tree.tpe.dealias) + val tpe = asDefLikeType(tree.typeOpt.dealias) termRef.denot.asSingleDenotation.mapInfo(_ => tpe) } @@ -453,16 +505,16 @@ object Completion: // 1. The extension method is visible under a simple name, by being defined or inherited or imported in a scope enclosing the reference. val termCompleter = new Completer(Mode.Term, prefix, pos) - val extMethodsInScope = termCompleter.scopeCompletions.toList.flatMap { - case (name, denots) => denots.collect { case d: SymDenotation if d.isTerm => (d.termRef, name.asTermName) } - } + val extMethodsInScope = termCompleter.scopeCompletions.toList.flatMap: + case (name, denots) => denots.collect: + case d: SymDenotation if d.isTerm && d.termRef.symbol.is(Extension) => (d.termRef, name.asTermName) // 2. The extension method is a member of some given instance that is visible at the point of the reference. val givensInScope = ctx.implicits.eligible(defn.AnyType).map(_.implicitRef.underlyingRef) val extMethodsFromGivensInScope = extractMemberExtensionMethods(givensInScope) // 3. The reference is of the form r.m and the extension method is defined in the implicit scope of the type of r. - val implicitScopeCompanions = ctx.run.nn.implicitScope(qual.tpe).companionRefs.showAsList + val implicitScopeCompanions = ctx.run.nn.implicitScope(qual.typeOpt).companionRefs.showAsList val extMethodsFromImplicitScope = extractMemberExtensionMethods(implicitScopeCompanions) // 4. The reference is of the form r.m and the extension method is defined in some given instance in the implicit scope of the type of r. @@ -472,7 +524,7 @@ object Completion: val availableExtMethods = extMethodsFromGivensInImplicitScope ++ extMethodsFromImplicitScope ++ extMethodsFromGivensInScope ++ extMethodsInScope val extMethodsWithAppliedReceiver = availableExtMethods.flatMap { case (termRef, termName) => - if termRef.symbol.is(ExtensionMethod) && !qual.tpe.isBottomType then + if termRef.symbol.is(ExtensionMethod) && !qual.typeOpt.isBottomType then tryApplyingReceiverToExtension(termRef) .map(denot => termName -> denot) else None @@ -551,21 +603,20 @@ object Completion: * @param qual The argument to which the implicit conversion should be applied. * @return The set of types after `qual` implicit conversion. */ - private def implicitConversionTargets(qual: Tree)(using Context): Set[Type] = { + private def implicitConversionTargets(qual: tpd.Tree)(using Context): Set[SearchSuccess] = { val typer = ctx.typer val conversions = new typer.ImplicitSearch(defn.AnyType, qual, pos.span).allImplicits - val targets = conversions.map(_.tree.tpe) + conversions.map(_.tree.typeOpt) - interactiv.println(i"implicit conversion targets considered: ${targets.toList}%, %") - targets + interactiv.println(i"implicit conversion targets considered: ${conversions.toList}%, %") + conversions } /** Filter for names that should appear when looking for completions. */ - private object completionsFilter extends NameFilter { + private object completionsFilter extends NameFilter: def apply(pre: Type, name: Name)(using Context): Boolean = !name.isConstructorName && name.toTermName.info.kind == SimpleNameKind def isStable = true - } extension (denotations: Seq[SingleDenotation]) def groupByName(using Context): CompletionMap = denotations.groupBy(_.name) @@ -576,11 +627,6 @@ object Completion: private type CompletionMap = Map[Name, Seq[SingleDenotation]] - /** Temporary data structure representing denotations with the same name introduced in a given scope - * as a member of a type, by a local definition or by an import clause - */ - private case class ScopedDenotations(denots: Seq[SingleDenotation], ctx: Context) - /** * The completion mode: defines what kinds of symbols should be included in the completion * results. @@ -602,3 +648,7 @@ object Completion: /** Both term and type symbols are allowed */ val ImportOrExport: Mode = new Mode(4) | Term | Type + val Scope: Mode = new Mode(8) + + val Member: Mode = new Mode(16) + diff --git a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala index 3f3e5e25f66e..16079125a434 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala @@ -250,7 +250,7 @@ object Interactive { * Note that if the given `pos` points out places for incomplete parses, * this method returns `errorTermTree` (`Literal(Consotant(null)`). * - * @see https://github.com/lampepfl/dotty/issues/15294 + * @see https://github.com/scala/scala3/issues/15294 */ def pathTo(trees: List[SourceTree], pos: SourcePosition)(using Context): List[Tree] = pathTo(trees.map(_.tree), pos.span) @@ -282,12 +282,10 @@ object Interactive { case nested :: encl :: rest => val outer = contextOfPath(encl :: rest) try encl match { - case tree @ PackageDef(pkg, stats) => - assert(tree.symbol.exists) + case tree @ PackageDef(pkg, stats) if tree.symbol.exists => if (nested `eq` pkg) outer else contextOfStat(stats, nested, pkg.symbol.moduleClass, outer.packageContext(tree, tree.symbol)) - case tree: DefDef => - assert(tree.symbol.exists) + case tree: DefDef if tree.symbol.exists => val localCtx = outer.localContext(tree, tree.symbol).setNewScope for params <- tree.paramss; param <- params do localCtx.enter(param.symbol) // Note: this overapproximates visibility a bit, since value parameters are only visible @@ -299,14 +297,14 @@ object Interactive { else outer case tree @ Block(stats, expr) => - val localCtx = outer.fresh.setNewScope + val localCtx = outer.localContext(tree, outer.owner).setNewScope stats.foreach { case stat: MemberDef => localCtx.enter(stat.symbol) case _ => } - contextOfStat(stats, nested, ctx.owner, localCtx) + contextOfStat(stats, nested, localCtx.owner, localCtx) case tree @ CaseDef(pat, _, _) => - val localCtx = outer.fresh.setNewScope + val localCtx = outer.localContext(tree, outer.owner).setNewScope pat.foreachSubTree { case bind: Bind => localCtx.enter(bind.symbol) case _ => @@ -422,6 +420,21 @@ object Interactive { false } + + /** Some information about the trees is lost after Typer such as Extension method construct + * is expanded into methods. In order to support completions in those cases + * we have to rely on untyped trees and only when types are necessary use typed trees. + */ + def resolveTypedOrUntypedPath(tpdPath: List[Tree], pos: SourcePosition)(using Context): List[untpd.Tree] = + lazy val untpdPath: List[untpd.Tree] = NavigateAST + .pathTo(pos.span, List(ctx.compilationUnit.untpdTree), true).collect: + case untpdTree: untpd.Tree => untpdTree + + tpdPath match + case (_: Bind) :: _ => tpdPath + case (_: untpd.TypTree) :: _ => tpdPath + case _ => untpdPath + /** * Is this tree using a renaming introduced by an import statement or an alias for `this`? * @@ -438,6 +451,20 @@ object Interactive { def sameName(n0: Name, n1: Name): Boolean = n0.stripModuleClassSuffix.toTermName eq n1.stripModuleClassSuffix.toTermName + /** https://scala-lang.org/files/archive/spec/3.4/02-identifiers-names-and-scopes.html + * import java.lang.* + * { + * import scala.* + * { + * import Predef.* + * { /* source */ } + * } + * } + */ + def isImportedByDefault(sym: Symbol)(using Context): Boolean = + val owner = sym.effectiveOwner + owner == defn.ScalaPredefModuleClass || owner == defn.ScalaPackageClass || owner == defn.JavaLangPackageClass + private[interactive] def safely[T](op: => List[T]): List[T] = try op catch { case ex: TypeError => Nil } } diff --git a/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala b/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala index b00cd1036018..8f42c62cb3b0 100644 --- a/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala +++ b/compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala @@ -47,14 +47,10 @@ class InteractiveDriver(val settings: List[String]) extends Driver { private val compiler: Compiler = new InteractiveCompiler - private val myOpenedFiles = new mutable.LinkedHashMap[URI, SourceFile] { - override def default(key: URI) = NoSource - } + private val myOpenedFiles = new mutable.LinkedHashMap[URI, SourceFile].withDefaultValue(NoSource) def openedFiles: Map[URI, SourceFile] = myOpenedFiles - private val myOpenedTrees = new mutable.LinkedHashMap[URI, List[SourceTree]] { - override def default(key: URI) = Nil - } + private val myOpenedTrees = new mutable.LinkedHashMap[URI, List[SourceTree]].withDefaultValue(Nil) def openedTrees: Map[URI, List[SourceTree]] = myOpenedTrees private val myCompilationUnits = new mutable.LinkedHashMap[URI, CompilationUnit] @@ -281,7 +277,7 @@ class InteractiveDriver(val settings: List[String]) extends Driver { if (t.symbol.exists && t.hasType) { if (!t.symbol.isCompleted) t.symbol.info = UnspecifiedErrorType t.symbol.annotations.foreach { annot => - /* In some cases annotations are are used on themself (possibly larger cycles). + /* In some cases annotations are used on themself (possibly larger cycles). * This is the case with the java.lang.annotation.Target annotation, would end * in an infinite loop while cleaning. The `seen` is added to ensure that those * trees are not cleand twice. diff --git a/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala b/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala index 5480d4a43043..b950d71eb045 100644 --- a/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala +++ b/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala @@ -33,7 +33,7 @@ case class SourceTree(tree: tpd.Import | tpd.NameTree, source: SourceFile) { } val position = { // FIXME: This is incorrect in some cases, like with backquoted identifiers, - // see https://github.com/lampepfl/dotty/pull/1634#issuecomment-257079436 + // see https://github.com/scala/scala3/pull/1634#issuecomment-257079436 val (start, end) = if (!treeSpan.isSynthetic) (treeSpan.point, treeSpan.point + nameLength) @@ -42,7 +42,12 @@ case class SourceTree(tree: tpd.Import | tpd.NameTree, source: SourceFile) { (treeSpan.end - nameLength, treeSpan.end) Span(start, end, start) } - source.atSpan(position) + // Don't widen the span, only narrow. + // E.g. The star in a wildcard export is 1 character, + // and that is the span of the type alias that results from it + // but the name may very well be larger, which we don't want. + val span1 = if treeSpan.contains(position) then position else treeSpan + source.atSpan(span1) } case _ => NoSourcePosition diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index f7ef86ee5cde..e98ff6c9d66d 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -854,13 +854,13 @@ object JavaParsers { val accessors = (for (name, (tpt, annots)) <- fieldsByName yield - DefDef(name, Nil, tpt, unimplementedExpr) + DefDef(name, List(Nil), tpt, unimplementedExpr) .withMods(Modifiers(Flags.JavaDefined | Flags.Method | Flags.Synthetic)) ).toList // generate the canonical constructor val canonicalConstructor = - DefDef(nme.CONSTRUCTOR, joinParams(tparams, List(header)), TypeTree(), EmptyTree) + DefDef(nme.CONSTRUCTOR, joinParams(Nil, List(header)), TypeTree(), EmptyTree) .withMods(Modifiers(Flags.JavaDefined | Flags.Synthetic, mods.privateWithin)) // return the trees @@ -872,7 +872,7 @@ object JavaParsers { tparams = tparams, needsDummyConstr = true ) - ).withMods(mods) + ).withMods(mods.withFlags(Flags.JavaDefined | Flags.Final)) } addCompanionObject(statics, recordTypeDef) end recordDecl diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 47b7ffbbc840..6892dfdd94ca 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -906,6 +906,7 @@ object Parsers { var braces = 0 while (true) { val token = lookahead.token + if (query != LARROW && token == XMLSTART) return false if (braces == 0) { if (token == query) return true if (stopScanTokens.contains(token) || lookahead.isNestedEnd) return false @@ -927,6 +928,7 @@ object Parsers { lookahead.nextToken() while (parens != 0 && lookahead.token != EOF) { val token = lookahead.token + if (token == XMLSTART) return true if (token == LPAREN) parens += 1 else if (token == RPAREN) parens -= 1 lookahead.nextToken() @@ -1763,12 +1765,11 @@ object Parsers { RefinedTypeTree(rejectWildcardType(t), refinement(indentOK = true)) }) else if Feature.ccEnabled && in.isIdent(nme.UPARROW) && isCaptureUpArrow then - val upArrowStart = in.offset - in.nextToken() - def cs = - if in.token == LBRACE then captureSet() - else atSpan(upArrowStart)(captureRoot) :: Nil - makeRetaining(t, cs, tpnme.retains) + atSpan(t.span.start): + in.nextToken() + if in.token == LBRACE + then makeRetaining(t, captureSet(), tpnme.retains) + else makeRetaining(t, Nil, tpnme.retainsCap) else t } @@ -2651,6 +2652,8 @@ object Parsers { parents match { case parent :: Nil if !in.isNestedStart => reposition(if (parent.isType) ensureApplied(wrapNew(parent)) else parent) + case tkn if in.token == INDENT => + New(templateBodyOpt(emptyConstructor, parents, Nil)) case _ => New(reposition(templateBodyOpt(emptyConstructor, parents, Nil))) } @@ -3151,7 +3154,8 @@ object Parsers { } if mods1.is(Local) then report.errorOrMigrationWarning( - em"""The [this] qualifier will be deprecated in the future; it should be dropped. + em"""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${rewriteNotice(`3.4-migration`)}""", in.sourcePos(), MigrationVersion.RemoveThisQualifier) @@ -3313,7 +3317,7 @@ object Parsers { /** ContextTypes ::= FunArgType {‘,’ FunArgType} */ def contextTypes(paramOwner: ParamOwner, numLeadParams: Int, impliedMods: Modifiers): List[ValDef] = - val tps = commaSeparated(funArgType) + val tps = commaSeparated(() => paramTypeOf(toplevelTyp)) var counter = numLeadParams def nextIdx = { counter += 1; counter } val paramFlags = if paramOwner.isClass then LocalParamAccessor else Param diff --git a/compiler/src/dotty/tools/dotc/printing/Formatting.scala b/compiler/src/dotty/tools/dotc/printing/Formatting.scala index 02f470324e8a..ac13f0161c70 100644 --- a/compiler/src/dotty/tools/dotc/printing/Formatting.scala +++ b/compiler/src/dotty/tools/dotc/printing/Formatting.scala @@ -24,6 +24,17 @@ object Formatting { object Shown: given [A: Show]: Conversion[A, Shown] = Show[A].show(_) + extension (s: Shown) + def runCtxShow(using Context): Shown = s match + case cs: CtxShow => cs.run + case _ => s + + def toStr(x: Shown)(using Context): String = x match + case seq: Seq[?] => seq.map(toStr).mkString("[", ", ", "]") + case res => res.tryToShow + + import Shown.runCtxShow + sealed abstract class Show[-T]: /** Show a value T by returning a "shown" result. */ def show(x: T): Shown @@ -31,10 +42,9 @@ object Formatting { trait CtxShow: def run(using Context): Shown - extension (s: Shown) - def ctxShow(using Context): Shown = s match - case cs: CtxShow => cs.run - case _ => s + private inline def CtxShow(inline x: Context ?=> Shown) = new CtxShow { def run(using Context) = x(using ctx) } + private def toStr[A: Show](x: A)(using Context): String = Shown.toStr(toShown(x)) + private def toShown[A: Show](x: A)(using Context): Shown = Show[A].show(x).runCtxShow /** The base implementation, passing the argument to StringFormatter which will try to `.show` it. */ object ShowAny extends Show[Any]: @@ -54,16 +64,26 @@ object Formatting { object Show extends ShowImplicits1: inline def apply[A](using inline z: Show[A]): Show[A] = z + given [X: Show]: Show[Option[X]] with + def show(x: Option[X]) = + CtxShow(x.map(toStr)) + end given + given [X: Show]: Show[Seq[X]] with - def show(x: Seq[X]) = new CtxShow: - def run(using Context) = x.map(show1) + def show(x: Seq[X]) = CtxShow(x.map(toStr)) + + given [K: Show, V: Show]: Show[Map[K, V]] with + def show(x: Map[K, V]) = + CtxShow(x.map((k, v) => s"${toStr(k)} => ${toStr(v)}")) + end given given [H: Show, T <: Tuple: Show]: Show[H *: T] with - def show(x: H *: T) = new CtxShow: - def run(using Context) = show1(x.head) *: Show[T].show(x.tail).ctxShow.asInstanceOf[Tuple] + def show(x: H *: T) = + CtxShow(toStr(x.head) *: toShown(x.tail).asInstanceOf[Tuple]) + end given given [X: Show]: Show[X | Null] with - def show(x: X | Null) = if x == null then "null" else Show[X].show(x.nn) + def show(x: X | Null) = if x == null then "null" else CtxShow(toStr(x.nn)) given Show[FlagSet] with def show(x: FlagSet) = x.flagsString @@ -79,7 +99,13 @@ object Formatting { case ast.TreeInfo.Impure => "PurityLevel.Impure" case ast.TreeInfo.PurePath => "PurityLevel.PurePath" case ast.TreeInfo.IdempotentPath => "PurityLevel.IdempotentPath" - case _ => s"PurityLevel(${x.x})" + case _ => s"PurityLevel(${x.x.toBinaryString})" + + given Show[Atoms] with + def show(x: Atoms) = x match + case Atoms.Unknown => "Unknown" + case Atoms.Range(lo, hi) => CtxShow(s"Range(${toStr(lo.toList)}, ${toStr(hi.toList)})") + end given given Show[Showable] = ShowAny given Show[Shown] = ShowAny @@ -101,11 +127,6 @@ object Formatting { given Show[util.Spans.Span] = ShowAny given Show[tasty.TreeUnpickler#OwnerTree] = ShowAny given Show[typer.ForceDegree.Value] = ShowAny - - private def show1[A: Show](x: A)(using Context) = show2(Show[A].show(x).ctxShow) - private def show2(x: Shown)(using Context): String = x match - case seq: Seq[?] => seq.map(show2).mkString("[", ", ", "]") - case res => res.tryToShow end Show end ShownDef export ShownDef.{ Show, Shown } @@ -122,7 +143,7 @@ object Formatting { class StringFormatter(protected val sc: StringContext) { protected def showArg(arg: Any)(using Context): String = arg.tryToShow - private def treatArg(arg: Shown, suffix: String)(using Context): (String, String) = arg.ctxShow match { + private def treatArg(arg: Shown, suffix: String)(using Context): (String, String) = arg.runCtxShow match { case arg: Seq[?] if suffix.indexOf('%') == 0 && suffix.indexOf('%', 1) != -1 => val end = suffix.indexOf('%', 1) val sep = StringContext.processEscapes(suffix.substring(1, end)) diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index 83e6a3b204c3..8fc0c568e125 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -15,7 +15,7 @@ import util.SourcePosition import scala.util.control.NonFatal import scala.annotation.switch import config.{Config, Feature} -import cc.{CapturingType, RetainingType, CaptureSet, ReachCapability, isBoxed, levelOwner, retainedElems} +import cc.{CapturingType, RetainingType, CaptureSet, ReachCapability, MaybeCapability, isBoxed, levelOwner, retainedElems} class PlainPrinter(_ctx: Context) extends Printer { @@ -404,6 +404,7 @@ class PlainPrinter(_ctx: Context) extends Printer { case tp: TermRef if tp.symbol == defn.captureRoot => Str("cap") case tp: SingletonType => toTextRef(tp) case ReachCapability(tp1) => toTextRef(tp1) ~ "*" + case MaybeCapability(tp1) => toTextRef(tp1) ~ "?" case _ => toText(tp) protected def isOmittablePrefix(sym: Symbol): Boolean = diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index de9e21aa4146..5d8b448e409c 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -27,7 +27,7 @@ import config.{Config, Feature} import dotty.tools.dotc.util.SourcePosition import dotty.tools.dotc.ast.untpd.{MemberDef, Modifiers, PackageDef, RefTree, Template, TypeDef, ValOrDefDef} -import cc.{CaptureSet, CapturingType, toCaptureSet, IllegalCaptureRef} +import cc.{CaptureSet, CapturingType, toCaptureSet, IllegalCaptureRef, isRetains} import dotty.tools.dotc.parsing.JavaParsers class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { @@ -643,7 +643,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { def toTextRetainsAnnot = try changePrec(GlobalPrec)(toText(arg) ~ "^" ~ toTextCaptureSet(captureSet)) catch case ex: IllegalCaptureRef => toTextAnnot - if annot.symbol.maybeOwner == defn.RetainsAnnot + if annot.symbol.maybeOwner.isRetains && Feature.ccEnabled && !printDebug && Phases.checkCapturesPhase.exists // might be missing on -Ytest-pickler then toTextRetainsAnnot @@ -764,7 +764,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { val spliceTypeText = (keywordStr("[") ~ toTextGlobal(tree.typeOpt) ~ keywordStr("]")).provided(printDebug && tree.typeOpt.exists) keywordStr("$") ~ spliceTypeText ~ { if args.isEmpty then keywordStr("{") ~ inPattern(toText(pattern)) ~ keywordStr("}") - else toText(pattern.symbol.name) ~ "(" ~ toTextGlobal(args, ", ") ~ ")" + else toText(pattern) ~ "(" ~ toTextGlobal(args, ", ") ~ ")" } case Hole(isTerm, idx, args, content) => val (prefix, postfix) = if isTerm then ("{{{", "}}}") else ("[[[", "]]]") diff --git a/compiler/src/dotty/tools/dotc/quoted/Interpreter.scala b/compiler/src/dotty/tools/dotc/quoted/Interpreter.scala index c124e12077fe..17e23ebcf014 100644 --- a/compiler/src/dotty/tools/dotc/quoted/Interpreter.scala +++ b/compiler/src/dotty/tools/dotc/quoted/Interpreter.scala @@ -353,11 +353,16 @@ object Interpreter: if !ctx.compilationUnit.isSuspendable then None else targetException match case _: NoClassDefFoundError | _: ClassNotFoundException => - val className = targetException.getMessage - if className eq null then None + val message = targetException.getMessage + if message eq null then None else - val sym = staticRef(className.toTypeName).symbol - if (sym.isDefinedInCurrentRun) Some(sym) else None + val className = message.replace('/', '.') + val sym = + if className.endsWith(str.MODULE_SUFFIX) then staticRef(className.toTermName).symbol.moduleClass + else staticRef(className.toTypeName).symbol + // If the symbol does not a a position we assume that it came from the current run and it has an error + if sym.isDefinedInCurrentRun || (sym.exists && !sym.srcPos.span.exists) then Some(sym) + else None case _ => None } } diff --git a/compiler/src/dotty/tools/dotc/report.scala b/compiler/src/dotty/tools/dotc/report.scala index 8e39afdd6e7d..a63b6569fefe 100644 --- a/compiler/src/dotty/tools/dotc/report.scala +++ b/compiler/src/dotty/tools/dotc/report.scala @@ -154,7 +154,7 @@ object report: | | An unhandled exception was thrown in the compiler. | Please file a crash report here: - | https://github.com/lampepfl/dotty/issues/new/choose + | https://github.com/scala/scala3/issues/new/choose | For non-enriched exceptions, compile with -Yno-enrich-error-messages. | |$info1 diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index f5e7f9d44f56..6011587a7100 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -206,6 +206,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe case PureUnitExpressionID // errorNumber: 190 case MatchTypeLegacyPatternID // errorNumber: 191 case UnstableInlineAccessorID // errorNumber: 192 + case VolatileOnValID // errorNumber: 193 def errorNumber = ordinal - 1 diff --git a/compiler/src/dotty/tools/dotc/reporting/Message.scala b/compiler/src/dotty/tools/dotc/reporting/Message.scala index 484789a7fe45..1ac5c6ecf407 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Message.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Message.scala @@ -57,8 +57,7 @@ object Message: def openLambda(tp: LambdaType): Unit = openedLambdas += tp - val seen = new collection.mutable.HashMap[SeenKey, List[Recorded]]: - override def default(key: SeenKey) = Nil + val seen = new collection.mutable.HashMap[SeenKey, List[Recorded]].withDefaultValue(Nil) var nonSensical = false @@ -77,8 +76,7 @@ object Message: * and following recordings get consecutive superscripts starting with 2. * @return The possibly superscripted version of `str`. */ - def record(str: String, isType: Boolean, entry: Recorded)(using Context): String = - if !recordOK then return str + def record(str: String, isType: Boolean, entry: Recorded)(using Context): String = if !recordOK then str else //println(s"recording $str, $isType, $entry") /** If `e1` is an alias of another class of the same name, return the other @@ -147,7 +145,7 @@ object Message: } def addendum(cat: String, info: Type): String = info match { - case bounds @ TypeBounds(lo, hi) if bounds ne TypeBounds.empty => + case bounds @ TypeBounds(lo, hi) if !(bounds =:= TypeBounds.empty) && !bounds.isErroneous => if (lo eq hi) i" which is an alias of $lo" else i" with $cat ${boundsStr(bounds)}" case _ => @@ -177,9 +175,8 @@ object Message: def needsExplanation(entry: Recorded) = entry match { case param: TypeParamRef => ctx.typerState.constraint.contains(param) case param: ParamRef => false - case skolem: SkolemType => true - case sym: Symbol => - ctx.gadt.contains(sym) && ctx.gadt.fullBounds(sym) != TypeBounds.empty + case skolem: SkolemType => true + case sym: Symbol => ctx.gadt.contains(sym) && ctx.gadt.fullBounds(sym) != TypeBounds.empty } val toExplain: List[(String, Recorded)] = seen.toList.flatMap { kvs => @@ -192,7 +189,7 @@ object Message: (tickedString, alt) } } - res // help the inferrencer out + res // help the inferencer out }.sortBy(_._1) def columnar(parts: List[(String, String)]): List[String] = { @@ -271,11 +268,11 @@ end Message * * Messages modify the rendendering of interpolated strings in several ways: * - * 1. The size of the printed code is limited with a MessafeLimiter. If the message + * 1. The size of the printed code is limited with a MessageLimiter. If the message * would get too large or too deeply nested, a `...` is printed instead. - * 2. References to module classes are prefixed with `object ` for better recogniability. + * 2. References to module classes are prefixed with `object` for better recognizability. * 3. A where clause is sometimes added which contains the following additional explanations: - * - Rerences are disambiguated: If a message contains occurrences of the same identifier + * - References are disambiguated: If a message contains occurrences of the same identifier * representing different symbols, the duplicates are printed with superscripts * and the where-clause explains where each symbol is located. * - Uninstantiated variables are explained in the where-clause with additional diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala index ca4114a82cdc..22500cbbaa48 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala @@ -172,19 +172,14 @@ abstract class Reporter extends interfaces.ReporterResult { end issueUnconfigured def issueIfNotSuppressed(dia: Diagnostic)(using Context): Unit = - def toErrorIfFatal(dia: Diagnostic) = dia match - case w: Warning if ctx.settings.silentWarnings.value => dia - case w: ConditionalWarning if w.isSummarizedConditional => dia - case w: Warning if ctx.settings.XfatalWarnings.value => w.toError - case _ => dia def go() = import Action.* dia match case w: Warning => WConf.parsed.action(dia) match case Error => issueUnconfigured(w.toError) - case Warning => issueUnconfigured(toErrorIfFatal(w)) - case Verbose => issueUnconfigured(toErrorIfFatal(w.setVerbose())) + case Warning => issueUnconfigured(w) + case Verbose => issueUnconfigured(w.setVerbose()) case Info => issueUnconfigured(w.toInfo) case Silent => case _ => issueUnconfigured(dia) @@ -214,6 +209,10 @@ abstract class Reporter extends interfaces.ReporterResult { def incomplete(dia: Diagnostic)(using Context): Unit = incompleteHandler(dia, ctx) + def finalizeReporting()(using Context) = + if (hasWarnings && ctx.settings.XfatalWarnings.value) + report(new Error("No warnings can be incurred under -Werror (or -Xfatal-warnings)", NoSourcePosition)) + /** Summary of warnings and errors */ def summary: String = { val b = new mutable.ListBuffer[String] diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 4c7cf003cbc9..c230e3b4d6d7 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -84,6 +84,23 @@ abstract class PatternMatchMsg(errorId: ErrorMessageID)(using Context) extends M abstract class CyclicMsg(errorId: ErrorMessageID)(using Context) extends Message(errorId): def kind = MessageKind.Cyclic + val ex: CyclicReference + protected def cycleSym = ex.denot.symbol + + protected def debugInfo = + if ctx.settings.YdebugCyclic.value then + "\n\nStacktrace:" ++ ex.getStackTrace().nn.mkString("\n ", "\n ", "") + else "\n\n Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace." + + protected def context: String = ex.optTrace match + case Some(trace) => + s"\n\nThe error occurred while trying to ${ + trace.map((prefix, sym, suffix) => i"$prefix$sym$suffix").mkString("\n which required to ") + }$debugInfo" + case None => + "\n\n Run with -explain-cyclic for more details." +end CyclicMsg + abstract class ReferenceMsg(errorId: ErrorMessageID)(using Context) extends Message(errorId): def kind = MessageKind.Reference @@ -1249,9 +1266,9 @@ class UnreducibleApplication(tycon: Type)(using Context) extends TypeMsg(Unreduc |Such applications are equivalent to existential types, which are not |supported in Scala 3.""" -class OverloadedOrRecursiveMethodNeedsResultType(cycleSym: Symbol)(using Context) +class OverloadedOrRecursiveMethodNeedsResultType(val ex: CyclicReference)(using Context) extends CyclicMsg(OverloadedOrRecursiveMethodNeedsResultTypeID) { - def msg(using Context) = i"""Overloaded or recursive $cycleSym needs return type""" + def msg(using Context) = i"""Overloaded or recursive $cycleSym needs return type$context""" def explain(using Context) = i"""Case 1: $cycleSym is overloaded |If there are multiple methods named $cycleSym and at least one definition of @@ -1263,29 +1280,29 @@ extends CyclicMsg(OverloadedOrRecursiveMethodNeedsResultTypeID) { |""" } -class RecursiveValueNeedsResultType(cycleSym: Symbol)(using Context) +class RecursiveValueNeedsResultType(val ex: CyclicReference)(using Context) extends CyclicMsg(RecursiveValueNeedsResultTypeID) { - def msg(using Context) = i"""Recursive $cycleSym needs type""" + def msg(using Context) = i"""Recursive $cycleSym needs type$context""" def explain(using Context) = i"""The definition of $cycleSym is recursive and you need to specify its type. |""" } -class CyclicReferenceInvolving(denot: SymDenotation)(using Context) +class CyclicReferenceInvolving(val ex: CyclicReference)(using Context) extends CyclicMsg(CyclicReferenceInvolvingID) { def msg(using Context) = - val where = if denot.exists then s" involving $denot" else "" - i"Cyclic reference$where" + val where = if ex.denot.exists then s" involving ${ex.denot}" else "" + i"Cyclic reference$where$context" def explain(using Context) = - i"""|$denot is declared as part of a cycle which makes it impossible for the - |compiler to decide upon ${denot.name}'s type. - |To avoid this error, try giving ${denot.name} an explicit type. + i"""|${ex.denot} is declared as part of a cycle which makes it impossible for the + |compiler to decide upon ${ex.denot.name}'s type. + |To avoid this error, try giving ${ex.denot.name} an explicit type. |""" } -class CyclicReferenceInvolvingImplicit(cycleSym: Symbol)(using Context) +class CyclicReferenceInvolvingImplicit(val ex: CyclicReference)(using Context) extends CyclicMsg(CyclicReferenceInvolvingImplicitID) { - def msg(using Context) = i"""Cyclic reference involving implicit $cycleSym""" + def msg(using Context) = i"""Cyclic reference involving implicit $cycleSym$context""" def explain(using Context) = i"""|$cycleSym is declared as part of a cycle which makes it impossible for the |compiler to decide upon ${cycleSym.name}'s type. @@ -2340,9 +2357,9 @@ class TypeTestAlwaysDiverges(scrutTp: Type, testTp: Type)(using Context) extends } // Relative of CyclicReferenceInvolvingImplicit and RecursiveValueNeedsResultType -class TermMemberNeedsResultTypeForImplicitSearch(cycleSym: Symbol)(using Context) +class TermMemberNeedsResultTypeForImplicitSearch(val ex: CyclicReference)(using Context) extends CyclicMsg(TermMemberNeedsNeedsResultTypeForImplicitSearchID) { - def msg(using Context) = i"""$cycleSym needs result type because its right-hand side attempts implicit search""" + def msg(using Context) = i"""$cycleSym needs result type because its right-hand side attempts implicit search$context""" def explain(using Context) = i"""|The right hand-side of $cycleSym's definition requires an implicit search at the highlighted position. |To avoid this error, give `$cycleSym` an explicit type. @@ -2415,9 +2432,14 @@ class UnqualifiedCallToAnyRefMethod(stat: untpd.Tree, method: Symbol)(using Cont def kind = MessageKind.PotentialIssue def msg(using Context) = i"Suspicious top-level unqualified call to ${hl(method.name.toString)}" def explain(using Context) = + val getClassExtraHint = + if method.name == nme.getClass_ && ctx.settings.classpath.value.contains("scala3-staging") then + i"""\n\n + |This class should not be used to get the classloader for `scala.quoted.staging.Compile.make`.""" + else "" i"""Top-level unqualified calls to ${hl("AnyRef")} or ${hl("Any")} methods such as ${hl(method.name.toString)} are |resolved to calls on ${hl("Predef")} or on imported methods. This might not be what - |you intended.""" + |you intended.$getClassExtraHint""" } class SynchronizedCallOnBoxedClass(stat: tpd.Tree)(using Context) @@ -2553,13 +2575,13 @@ class UnknownNamedEnclosingClassOrObject(name: TypeName)(using Context) """ } -class IllegalCyclicTypeReference(sym: Symbol, where: String, lastChecked: Type)(using Context) +class IllegalCyclicTypeReference(val ex: CyclicReference, sym: Symbol, where: String, lastChecked: Type)(using Context) extends CyclicMsg(IllegalCyclicTypeReferenceID) { def msg(using Context) = val lastCheckedStr = try lastChecked.show catch case ex: CyclicReference => "..." - i"illegal cyclic type reference: ${where} ${hl(lastCheckedStr)} of $sym refers back to the type itself" + i"illegal cyclic type reference: ${where} ${hl(lastCheckedStr)} of $sym refers back to the type itself$context" def explain(using Context) = "" } @@ -3128,3 +3150,8 @@ class UnstableInlineAccessor(accessed: Symbol, accessorTree: tpd.Tree)(using Con if accessor.owner.name.isPackageObjectName then accessor.owner.owner.name.stripModuleClassSuffix else accessor.owner.name.stripModuleClassSuffix } + +class VolatileOnVal()(using Context) +extends SyntaxMsg(VolatileOnValID): + protected def msg(using Context): String = "values cannot be volatile" + protected def explain(using Context): String = "" diff --git a/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala b/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala index 2586ad8604c3..305f61dfa177 100644 --- a/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala +++ b/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala @@ -15,7 +15,7 @@ import dotty.tools.dotc.reporting.CodeAction /** Handles rewriting of Scala2 files to Dotty */ object Rewrites { - private class PatchedFiles extends mutable.HashMap[SourceFile, Patches] + private type PatchedFiles = mutable.HashMap[SourceFile, Patches] private case class Patch(span: Span, replacement: String) { def delta = replacement.length - (span.end - span.start) diff --git a/compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala b/compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala index 6376fb86d6c5..50ea6ec48510 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala @@ -20,8 +20,7 @@ class SemanticSymbolBuilder: private val locals = mutable.HashMap[Symbol, Int]() /** The local symbol(s) starting at given offset */ - private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]](): - override def default(key: Int) = Set[Symbol]() + private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]]().withDefault(_ => Set[Symbol]()) def symbolName(sym: Symbol)(using Context): String = diff --git a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala index 26c94407f35b..6c74f302b65d 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala @@ -30,6 +30,9 @@ class CheckStatic extends MiniPhase { override def description: String = CheckStatic.description + override def runsAfter: Set[String] = Set(UncacheGivenAliases.name) + // UncachedGivenAliases eliminates static lazy vals, which are flagged as errors here + override def transformTemplate(tree: tpd.Template)(using Context): tpd.Tree = { val defns = tree.body.collect{case t: ValOrDefDef => t} var hadNonStaticField = false diff --git a/compiler/src/dotty/tools/dotc/transform/CountOuterAccesses.scala b/compiler/src/dotty/tools/dotc/transform/CountOuterAccesses.scala index b5c02347d5d2..e55c3d953ac2 100644 --- a/compiler/src/dotty/tools/dotc/transform/CountOuterAccesses.scala +++ b/compiler/src/dotty/tools/dotc/transform/CountOuterAccesses.scala @@ -43,9 +43,7 @@ class CountOuterAccesses extends MiniPhase: // LambdaLift can create outer paths. These need to be known in this phase. /** The number of times an outer accessor that might be dropped is accessed */ - val outerAccessCount = new mutable.HashMap[Symbol, Int] { - override def default(s: Symbol): Int = 0 - } + val outerAccessCount = new mutable.HashMap[Symbol, Int].withDefaultValue(0) private def markAccessed(tree: RefTree)(using Context): Tree = val sym = tree.symbol diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 8582420d64ee..9fdffb0ed537 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -2,6 +2,7 @@ package dotty.tools package dotc package transform +import ast.Trees import core.Phases.* import core.DenotTransformers.* import core.Denotations.* @@ -1044,7 +1045,21 @@ object Erasure { override def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(using Context): Tree = if cls.is(Flags.Erased) then erasedDef(cls) - else super.typedClassDef(cdef, cls) + else + val typedTree@TypeDef(name, impl @ Template(constr, _, self, _)) = super.typedClassDef(cdef, cls): @unchecked + // In the case where a trait extends a class, we need to strip any non trait class from the signature + // and accept the first one (see tests/run/mixins.scala) + val newTraits = impl.parents.tail.filterConserve: tree => + def isTraitConstructor = tree match + case Trees.Block(_, expr) => // Specific management for trait constructors (see tests/pos/i9213.scala) + expr.symbol.isConstructor && expr.symbol.owner.is(Flags.Trait) + case _ => tree.symbol.isConstructor && tree.symbol.owner.is(Flags.Trait) + tree.symbol.is(Flags.Trait) || isTraitConstructor + + val newParents = + if impl.parents.tail eq newTraits then impl.parents + else impl.parents.head :: newTraits + cpy.TypeDef(typedTree)(rhs = cpy.Template(impl)(parents = newParents)) override def typedAnnotated(tree: untpd.Annotated, pt: Type)(using Context): Tree = typed(tree.arg, pt) diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala index fa2492a261d5..9a6a04621074 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala @@ -25,8 +25,8 @@ import ValueClasses.* * This is necessary since private methods are not allowed to have the same name * as inherited public ones. * - * See discussion in https://github.com/lampepfl/dotty/pull/784 - * and https://github.com/lampepfl/dotty/issues/783 + * See discussion in https://github.com/scala/scala3/pull/784 + * and https://github.com/scala/scala3/issues/783 */ class ExpandPrivate extends MiniPhase with IdentityDenotTransformer { thisPhase => import ast.tpd.* diff --git a/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala b/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala index 2723f726f064..3ff72d61d41f 100644 --- a/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala +++ b/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala @@ -98,10 +98,10 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: start = pos.start, end = pos.end, // +1 to account for the line number starting at 1 - // the internal line number is 0-base https://github.com/lampepfl/dotty/blob/18ada516a85532524a39a962b2ddecb243c65376/compiler/src/dotty/tools/dotc/util/SourceFile.scala#L173-L176 + // the internal line number is 0-base https://github.com/scala/scala3/blob/18ada516a85532524a39a962b2ddecb243c65376/compiler/src/dotty/tools/dotc/util/SourceFile.scala#L173-L176 line = pos.line + 1, desc = sourceFile.content.slice(pos.start, pos.end).mkString, - symbolName = tree.symbol.name.toSimpleName.toString, + symbolName = tree.symbol.name.toSimpleName.show, treeName = tree.getClass.getSimpleName.nn, branch ) diff --git a/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala b/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala index dbc1639f4b55..939497caf31c 100644 --- a/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala +++ b/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala @@ -141,7 +141,7 @@ class MacroAnnotations(phase: IdentityDenotTransformer): def traverse(tree: tpd.Tree)(using Context): Unit = tree match case tdef @ TypeDef(_, template: Template) => val isSymbolInDecls = tdef.symbol.asClass.info.decls.toList.toSet - for tree <- template.body do + for tree <- template.body if tree.isDef do if tree.symbol.owner != tdef.symbol then report.error(em"Macro added a definition with the wrong owner - ${tree.symbol.owner} - ${tdef.symbol} in ${tree.source}", tree.srcPos) else if !isSymbolInDecls(tree.symbol) then diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 7b196692a9c9..bed29a122399 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -512,9 +512,7 @@ object PatternMatcher { } private class RefCounter extends PlanTransform { - val count = new mutable.HashMap[Symbol, Int] { - override def default(key: Symbol) = 0 - } + val count = new mutable.HashMap[Symbol, Int].withDefaultValue(0) } /** Reference counts for all labels */ diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index d847d14603a2..17298a45e01e 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -547,8 +547,24 @@ object TreeChecker { i"owner chain = ${tree.symbol.ownersIterator.toList}%, %, ctxOwners = ${ctx.outersIterator.map(_.owner).toList}%, %") } + private def checkParents(tree: untpd.TypeDef)(using Context): Unit = { + val TypeDef(_, impl: Template) = tree: @unchecked + assert(ctx.owner.isClass) + val sym = ctx.owner.asClass + if !sym.isPrimitiveValueClass then + val symbolParents = sym.classInfo.parents.map(_.dealias.typeSymbol) + val treeParents = impl.parents.map(_.tpe.dealias.typeSymbol) + assert(symbolParents == treeParents, + i"""Parents of class symbol differs from the parents in the tree for $sym + | + |Parents in symbol: $symbolParents + |Parents in tree: $treeParents + |""".stripMargin) + } + override def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(using Context): Tree = { assert(sym.info.isInstanceOf[ClassInfo | TypeBounds], i"wrong type, expect a template or type bounds for ${sym.fullName}, but found: ${sym.info}") + if sym.isClass then checkParents(tdef) super.typedTypeDef(tdef, sym) } @@ -561,6 +577,8 @@ object TreeChecker { checkOwner(impl) checkOwner(impl.constr) + checkParents(cdef) + def isNonMagicalMember(x: Symbol) = !x.isValueClassConvertMethod && !x.name.is(DocArtifactName) && @@ -812,7 +830,7 @@ object TreeChecker { else err.getStackTrace.nn.mkString(" ", " \n", "") report.error( - s"""Malformed tree was found while expanding macro with -Xcheck-macros. + em"""Malformed tree was found while expanding macro with -Xcheck-macros. |The tree does not conform to the compiler's tree invariants. | |Macro was: diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 0df81f756925..012f2affffc1 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -3,23 +3,13 @@ package dotc package transform package patmat -import core.* -import Types.* -import Contexts.* -import Flags.* -import ast.* -import Decorators.{ show => _, * } -import Symbols.* -import StdNames.* -import NameOps.* -import Constants.* -import typer.* -import Applications.* -import Inferencing.* -import ProtoTypes.* +import core.*, Constants.*, Contexts.*, Decorators.*, Flags.*, Names.*, NameOps.*, StdNames.*, Symbols.*, Types.* +import ast.*, tpd.* +import config.Printers.* +import printing.{ Printer, * }, Texts.* import reporting.* -import config.Printers.{exhaustivity => debug} -import util.{SrcPos, NoSourcePosition} +import typer.*, Applications.*, Inferencing.*, ProtoTypes.* +import util.* import scala.annotation.internal.sharable import scala.collection.mutable @@ -56,7 +46,7 @@ import SpaceEngine.* */ /** space definition */ -sealed trait Space: +sealed trait Space extends Showable: @sharable private val isSubspaceCache = mutable.HashMap.empty[Space, Boolean] @@ -67,9 +57,7 @@ sealed trait Space: if (a ne a2) || (b ne b2) then a2.isSubspace(b2) else if a == Empty then true else if b == Empty then false - else trace(s"isSubspace(${show(this)}, ${show(b)})", debug) { - isSubspaceCache.getOrElseUpdate(b, computeIsSubspace(a, b)) - } + else isSubspaceCache.getOrElseUpdate(b, computeIsSubspace(a, b)) @sharable private var mySimplified: Space | Null = null @@ -80,6 +68,13 @@ sealed trait Space: mySimplified = simplified simplified else simplified + + def toText(p: Printer): Text = inContext(p.printerContext)(this match { + case Empty => s"Empty" + case sp: Typ => s"Typ(${display(sp)})" + case sp: Prod => s"Prod(${display(sp)})" + case sp: Or => s"Or(${display(sp)})" + }) end Space /** Empty space */ @@ -114,15 +109,13 @@ case class Prod(tp: Type, unappTp: TermRef, params: List[Space]) extends Space case class Or(spaces: Seq[Space]) extends Space object SpaceEngine { - import tpd.* - def simplify(space: Space)(using Context): Space = space.simplify def isSubspace(a: Space, b: Space)(using Context): Boolean = a.isSubspace(b) def canDecompose(typ: Typ)(using Context): Boolean = typ.canDecompose def decompose(typ: Typ)(using Context): List[Typ] = typ.decompose /** Simplify space such that a space equal to `Empty` becomes `Empty` */ - def computeSimplify(space: Space)(using Context): Space = trace(s"simplify ${show(space)} --> ", debug, show)(space match { + def computeSimplify(space: Space)(using Context): Space = trace(i"simplify($space)")(space match { case Prod(tp, fun, spaces) => val sps = spaces.mapconserve(simplify) if sps.contains(Empty) then Empty @@ -173,7 +166,7 @@ object SpaceEngine { } /** Is `a` a subspace of `b`? Equivalent to `simplify(simplify(a) - simplify(b)) == Empty`, but faster */ - def computeIsSubspace(a: Space, b: Space)(using Context): Boolean = { + def computeIsSubspace(a: Space, b: Space)(using Context): Boolean = trace(i"isSubspace($a, $b)") { val a2 = simplify(a) val b2 = simplify(b) if (a ne a2) || (b ne b2) then isSubspace(a2, b2) @@ -202,7 +195,7 @@ object SpaceEngine { } /** Intersection of two spaces */ - def intersect(a: Space, b: Space)(using Context): Space = trace(s"${show(a)} & ${show(b)}", debug, show) { + def intersect(a: Space, b: Space)(using Context): Space = trace(i"intersect($a & $b)") { (a, b) match { case (Empty, _) | (_, Empty) => Empty case (_, Or(ss)) => Or(ss.map(intersect(a, _)).filter(_ ne Empty)) @@ -211,11 +204,11 @@ object SpaceEngine { if isSubType(tp1, tp2) then a else if isSubType(tp2, tp1) then b else intersectUnrelatedAtomicTypes(tp1, tp2)(a) - case (a @ Typ(tp1, _), Prod(tp2, fun, ss)) => + case (a @ Typ(tp1, _), b @ Prod(tp2, fun, ss)) => if isSubType(tp2, tp1) then b else if isSubType(tp1, tp2) then a // problematic corner case: inheriting a case class else intersectUnrelatedAtomicTypes(tp1, tp2)(b) - case (Prod(tp1, fun, ss), b @ Typ(tp2, _)) => + case (a @ Prod(tp1, fun, ss), b @ Typ(tp2, _)) => if isSubType(tp1, tp2) then a else if isSubType(tp2, tp1) then a // problematic corner case: inheriting a case class else intersectUnrelatedAtomicTypes(tp1, tp2)(a) @@ -227,7 +220,7 @@ object SpaceEngine { } /** The space of a not covered by b */ - def minus(a: Space, b: Space)(using Context): Space = trace(s"${show(a)} - ${show(b)}", debug, show) { + def minus(a: Space, b: Space)(using Context): Space = trace(i"minus($a - $b)") { (a, b) match { case (Empty, _) => Empty case (_, Empty) => a @@ -291,8 +284,8 @@ object SpaceEngine { /** Is the unapply or unapplySeq irrefutable? * @param unapp The unapply function tree */ - def isIrrefutable(unapp: tpd.Tree, argLen: Int)(using Context): Boolean = { - tpd.funPart(unapp).tpe match + def isIrrefutable(unapp: Tree, argLen: Int)(using Context): Boolean = { + funPart(unapp).tpe match case funRef: TermRef => isIrrefutable(funRef, argLen) case _: ErrorType => false } @@ -301,7 +294,7 @@ object SpaceEngine { * @param body The body of the quoted pattern * @param bodyPt The scrutinee body type */ - def isIrrefutableQuotePattern(pat: tpd.QuotePattern, pt: Type)(using Context): Boolean = { + def isIrrefutableQuotePattern(pat: QuotePattern, pt: Type)(using Context): Boolean = { if pat.body.isType then pat.bindings.isEmpty && pt =:= pat.tpe else pat.body match case _: SplicePattern | Typed(_: SplicePattern, _) => pat.bindings.isEmpty && pt <:< pat.tpe @@ -313,24 +306,24 @@ object SpaceEngine { * The types should be atomic (non-decomposable) and unrelated (neither * should be a subtype of the other). */ - def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type)(sp: Space)(using Context): Space = trace(i"atomic intersection: ${AndType(tp1, tp2)}", debug, show) { + def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type)(sp: Typ | Prod)(using Context): Space = trace(i"intersectUnrelatedAtomicTypes($tp1, $tp2)(${sp.className})") { // Precondition: !isSubType(tp1, tp2) && !isSubType(tp2, tp1). + def intersection = sp match + case sp: Prod => sp.copy(AndType(tp1, tp2)) + case sp: Typ => sp.copy(AndType(tp1, tp2)) if !ctx.mode.is(Mode.SafeNulls) && (tp1.isNullType || tp2.isNullType) then // Since projections of types don't include null, intersection with null is empty. Empty - else - val intersection = sp match - case sp: Prod => sp.copy(AndType(tp1, tp2)) - case _ => Typ(AndType(tp1, tp2), decomposed = false) + else if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then // unrelated numeric value classes can equal each other, so let's not consider type space intersection empty - if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then intersection - else if isPrimToBox(tp1, tp2) || isPrimToBox(tp2, tp1) then intersection - else if TypeComparer.provablyDisjoint(tp1, tp2) then Empty - else intersection + intersection + else if isPrimToBox(tp1, tp2) || isPrimToBox(tp2, tp1) then intersection + else if TypeComparer.provablyDisjoint(tp1, tp2) then Empty + else intersection } /** Return the space that represents the pattern `pat` */ - def project(pat: Tree)(using Context): Space = trace(i"project($pat ${pat.className} ${pat.tpe})", debug, show)(pat match { + def project(pat: Tree)(using Context): Space = trace(i"project($pat ${pat.className} ${pat.tpe})")(pat match { case Literal(c) => if (c.value.isInstanceOf[Symbol]) Typ(c.value.asInstanceOf[Symbol].termRef, decomposed = false) @@ -447,7 +440,10 @@ object SpaceEngine { * This is needed to avoid spurious unreachable warnings. See tests/patmat/i6197.scala. */ private def erase(tp: Type, inArray: Boolean = false, isValue: Boolean = false, isTyped: Boolean = false)(using Context): Type = - trace(i"erase($tp${if inArray then " inArray" else ""}${if isValue then " isValue" else ""}${if isTyped then " isTyped" else ""})", debug)(tp match { + val inArr = if inArray then " inArray" else "" + val isVal = if isValue then " isValue" else "" + val isTyp = if isTyped then " isTyped" else "" + trace(i"erase($tp ${tp.className}$inArr$isVal$isTyp)")(tp match { case tp @ AppliedType(tycon, args) if tycon.typeSymbol.isPatternBound => WildcardType @@ -496,7 +492,7 @@ object SpaceEngine { tp.isPrimitiveValueType && (defn.boxedType(tp).classSymbol eq pt.classSymbol) /** Is `tp1` a subtype of `tp2`? */ - def isSubType(tp1: Type, tp2: Type)(using Context): Boolean = trace(i"$tp1 <:< $tp2", debug, show = true) { + def isSubType(tp1: Type, tp2: Type)(using Context): Boolean = trace(i"$tp1 <:< $tp2") { if tp1 == ConstantType(Constant(null)) && !ctx.mode.is(Mode.SafeNulls) then tp2 == ConstantType(Constant(null)) else if tp1.isTupleXXLExtract(tp2) then true // See isTupleXXLExtract, fixes TupleXXL parameter type @@ -520,11 +516,9 @@ object SpaceEngine { /** Return term parameter types of the extractor `unapp`. * Parameter types of the case class type `tp`. Adapted from `unapplyPlan` in patternMatcher */ - def signature(unapp: TermRef, scrutineeTp: Type, argLen: Int)(using Context): List[Type] = { + def signature(unapp: TermRef, scrutineeTp: Type, argLen: Int)(using Context): List[Type] = trace(i"signature($unapp, $scrutineeTp, $argLen)") { val unappSym = unapp.symbol - // println("scrutineeTp = " + scrutineeTp.show) - val mt: MethodType = unapp.widen match { case mt: MethodType => mt case pt: PolyType => @@ -583,8 +577,6 @@ object SpaceEngine { } } - debug.println(s"signature of ${unappSym.showFullName} ----> ${sig.map(_.show).mkString(", ")}") - sig.map(_.annotatedToRepeated) } @@ -602,7 +594,7 @@ object SpaceEngine { } /** Decompose a type into subspaces -- assume the type can be decomposed */ - def decompose(tp: Type)(using Context): List[Type] = trace(i"decompose($tp)", debug) { + def decompose(tp: Type)(using Context): List[Type] = trace(i"decompose($tp)") { def rec(tp: Type, mixins: List[Type]): List[Type] = tp.dealias match case AndType(tp1, tp2) => var tpB = tp2 @@ -619,7 +611,7 @@ object SpaceEngine { case OrType(tp1, tp2) => List(tp1, tp2) case tp if tp.isRef(defn.BooleanClass) => List(ConstantType(Constant(true)), ConstantType(Constant(false))) case tp if tp.isRef(defn.UnitClass) => ConstantType(Constant(())) :: Nil - case tp @ NamedType(Parts(parts), _) => parts.map(tp.derivedSelect) + case tp @ NamedType(Parts(parts), _) => if parts.exists(_ eq tp) then ListOfNoType else parts.map(tp.derivedSelect) case _: SingletonType => ListOfNoType case tp if tp.classSymbol.isAllOf(JavaEnum) => tp.classSymbol.children.map(_.termRef) // the class of a java enum value is the enum class, so this must follow SingletonType to not loop infinitely @@ -640,13 +632,11 @@ object SpaceEngine { else if (child.is(Private) || child.is(Sealed)) && child.isOneOf(AbstractOrTrait) then getChildren(child) else List(child) } - val children = getChildren(tp.classSymbol) - debug.println(i"candidates for $tp : $children") + val children = trace(i"getChildren($tp)")(getChildren(tp.classSymbol)) val parts = children.map { sym => val sym1 = if (sym.is(ModuleClass)) sym.sourceModule else sym - val refined = TypeOps.refineUsingParent(tp, sym1, mixins) - debug.println(i"$sym1 refined to $refined") + val refined = trace(i"refineUsingParent($tp, $sym1, $mixins)")(TypeOps.refineUsingParent(tp, sym1, mixins)) def inhabited(tp: Type): Boolean = tp.dealias match case AndType(tp1, tp2) => !TypeComparer.provablyDisjoint(tp1, tp2) @@ -658,7 +648,6 @@ object SpaceEngine { if inhabited(refined) then refined else NoType }.filter(_.exists) - debug.println(i"$tp decomposes to $parts") parts case _ => ListOfNoType @@ -668,17 +657,15 @@ object SpaceEngine { } extension (tp: Type) - /** A type is decomposable to children if it has a simple kind, it's sealed, - * abstract (or a trait) - so its not a sealed concrete class that can be instantiated on its own, - * has no anonymous children, which we wouldn't be able to name as counter-examples, - * but does have children. - * - * A sealed trait with no subclasses is considered not decomposable and thus is treated as an opaque type. - * A sealed trait with subclasses that then get removed after `refineUsingParent`, decomposes to the empty list. - * So that's why we consider whether a type has children. */ def isDecomposableToChildren(using Context): Boolean = - val cls = tp.classSymbol - tp.hasSimpleKind && cls.is(Sealed) && cls.isOneOf(AbstractOrTrait) && !cls.hasAnonymousChild && cls.children.nonEmpty + val sym = tp.typeSymbol // e.g. Foo[List[Int]] = type Foo (i19275) + val cls = tp.classSymbol // e.g. Foo[List[Int]] = class List + tp.hasSimpleKind // can't decompose higher-kinded types + && cls.is(Sealed) + && cls.isOneOf(AbstractOrTrait) // ignore sealed non-abstract classes + && !cls.hasAnonymousChild // can't name anonymous classes as counter-examples + && cls.children.nonEmpty // can't decompose without children + && !sym.isOpaqueAlias // can't instantiate subclasses to conform to an opaque type (i19275) val ListOfNoType = List(NoType) val ListOfTypNoType = ListOfNoType.map(Typ(_, decomposed = true)) @@ -693,49 +680,13 @@ object SpaceEngine { * * E.g. C.this.B --> B if current owner is C * C.this.x.T --> x.T if current owner is C - * X[T] --> X * C --> C if current owner is C !!! - * */ - def showType(tp: Type, showTypeArgs: Boolean = false)(using Context): String = { + private class LocalPrinter(_ctx: Context) extends RefinedPrinter(_ctx): val enclosingCls = ctx.owner.enclosingClass - - def isOmittable(sym: Symbol) = - sym.isEffectiveRoot || sym.isAnonymousClass || sym.name.isReplWrapperName || - ctx.definitions.unqualifiedOwnerTypes.exists(_.symbol == sym) || - sym.showFullName.startsWith("scala.") || - sym == enclosingCls || sym == enclosingCls.sourceModule - - def refinePrefix(tp: Type): String = tp match { - case NoPrefix => "" - case tp: NamedType if isOmittable(tp.symbol) => "" - case tp: ThisType => refinePrefix(tp.tref) - case tp: RefinedType => refinePrefix(tp.parent) - case tp: NamedType => tp.name.show.stripSuffix("$") - case tp: TypeVar => refinePrefix(tp.instanceOpt) - case _ => tp.show - } - - def refine(tp: Type): String = tp.stripped match { - case tp: RefinedType => refine(tp.parent) - case tp: AppliedType => - refine(tp.typeConstructor) + ( - if (showTypeArgs) tp.argInfos.map(refine).mkString("[", ",", "]") - else "" - ) - case tp: ThisType => refine(tp.tref) - case tp: NamedType => - val pre = refinePrefix(tp.prefix) - if (tp.name == tpnme.higherKinds) pre - else if (pre.isEmpty) tp.name.show.stripSuffix("$") - else pre + "." + tp.name.show.stripSuffix("$") - case tp: OrType => refine(tp.tp1) + " | " + refine(tp.tp2) - case _: TypeBounds => "_" - case _ => tp.show.stripSuffix("$") - } - - refine(tp) - } + override def isOmittablePrefix(sym: Symbol) = + super.isOmittablePrefix(sym) + || sym == enclosingCls || sym == enclosingCls.sourceModule /** Whether the counterexample is satisfiable. The space is flattened and non-empty. */ def satisfiable(sp: Space)(using Context): Boolean = { @@ -769,10 +720,8 @@ object SpaceEngine { checkConstraint(genConstraint(sp))(using ctx.fresh.setNewTyperState()) } - def showSpaces(ss: Seq[Space])(using Context): Seq[String] = ss.map(show) - - /** Display spaces */ - def show(s: Space)(using Context): String = { + /** Display spaces. Used for printing uncovered spaces in the in-exhaustive error message. */ + def display(s: Space)(using Context): String = inContext(ctx.fresh.setPrinterFn(LocalPrinter(_))) { def params(tp: Type): List[Type] = tp.classSymbol.primaryConstructor.info.firstParamTypes /** does the companion object of the given symbol have custom unapply */ @@ -789,39 +738,38 @@ object SpaceEngine { if (flattenList && tp <:< defn.NilType) "" else tp.symbol.showName case Typ(tp, decomposed) => - - val sym = tp.classSymbol - - if (ctx.definitions.isTupleNType(tp)) + val cls = tp.classSymbol + if ctx.definitions.isTupleNType(tp) then params(tp).map(_ => "_").mkString("(", ", ", ")") - else if (defn.ListType.isRef(sym)) - if (flattenList) "_*" else "_: List" - else if (defn.ConsType.isRef(sym)) - if (flattenList) "_, _*" else "List(_, _*)" - else if (tp.classSymbol.is(Sealed) && tp.classSymbol.hasAnonymousChild) - "_: " + showType(tp) + " (anonymous)" - else if (tp.classSymbol.is(CaseClass) && !hasCustomUnapply(tp.classSymbol)) - // use constructor syntax for case class - showType(tp) + params(tp).map(_ => "_").mkString("(", ", ", ")") - else if (decomposed) "_: " + showType(tp, showTypeArgs = true) - else "_" + else if defn.ListType.isRef(cls) then + if flattenList then "_*" else "_: List" + else if (defn.ConsType.isRef(cls)) + if flattenList then "_, _*" else "List(_, _*)" + else if cls.hasAnonymousChild then + s"_: ${tp.typeConstructor.show} (anonymous)" + else if cls.is(CaseClass) && !hasCustomUnapply(cls) then + // use constructor syntax for case class + tp.typeConstructor.show + params(tp).map(_ => "_").mkString("(", ", ", ")") + else if !decomposed then "_" + else "_: " + tp.show case Prod(tp, fun, params) => - if (ctx.definitions.isTupleNType(tp)) + if ctx.definitions.isTupleNType(tp) then "(" + params.map(doShow(_)).mkString(", ") + ")" - else if (tp.isRef(defn.ConsType.symbol)) - if (flattenList) params.map(doShow(_, flattenList)).filter(_.nonEmpty).mkString(", ") - else params.map(doShow(_, flattenList = true)).filter(!_.isEmpty).mkString("List(", ", ", ")") - else { - val sym = fun.symbol - val isUnapplySeq = sym.name.eq(nme.unapplySeq) + else if tp.isRef(defn.ConsType.symbol) then + val body = params.map(doShow(_, flattenList = true)).filter(_.nonEmpty).mkString(", ") + if flattenList then body else s"List($body)" + else + val isUnapplySeq = fun.symbol.name eq nme.unapplySeq val paramsStr = params.map(doShow(_, flattenList = isUnapplySeq)).mkString("(", ", ", ")") - showType(fun.prefix) + paramsStr - } + val prefix = fun.prefix match + case pre: TermRef => pre.symbol.typeRef + case pre => pre + prefix.typeConstructor.show + paramsStr case Or(ss) => ss.map(doShow(_, flattenList)).mkString(" | ") } - doShow(s, flattenList = false) + doShow(s) } private def exhaustivityCheckable(sel: Tree)(using Context): Boolean = { @@ -845,13 +793,11 @@ object SpaceEngine { else true // recursive case class: return true and other members can still fail the check } - val res = !sel.tpe.hasAnnotation(defn.UncheckedAnnot) && { + !sel.tpe.hasAnnotation(defn.UncheckedAnnot) + && { ctx.settings.YcheckAllPatmat.value || isCheckable(sel.tpe) } - - debug.println(s"exhaustivity checkable: ${sel.show} = $res") - res } /** Whether counter-examples should be further checked? True for GADTs. */ @@ -866,7 +812,7 @@ object SpaceEngine { /** Return the underlying type of non-module, non-constant, non-enum case singleton types. * Also widen ExprType to its result type, and rewrap any annotation wrappers. * For example, with `val opt = None`, widen `opt.type` to `None.type`. */ - def toUnderlying(tp: Type)(using Context): Type = trace(i"toUnderlying($tp)", show = true)(tp match { + def toUnderlying(tp: Type)(using Context): Type = trace(i"toUnderlying($tp)")(tp match { case _: ConstantType => tp case tp: TermRef if tp.symbol.is(Module) => tp case tp: TermRef if tp.symbol.isAllOf(EnumCase) => tp @@ -876,27 +822,25 @@ object SpaceEngine { case _ => tp }) - def checkExhaustivity(m: Match)(using Context): Unit = trace(i"checkExhaustivity($m)", debug) { + def checkExhaustivity(m: Match)(using Context): Unit = trace(i"checkExhaustivity($m)") { val selTyp = toUnderlying(m.selector.tpe).dealias - debug.println(i"selTyp = $selTyp") + val targetSpace = trace(i"targetSpace($selTyp)")(project(selTyp)) val patternSpace = Or(m.cases.foldLeft(List.empty[Space]) { (acc, x) => - val space = if (x.guard.isEmpty) project(x.pat) else Empty - debug.println(s"${x.pat.show} ====> ${show(space)}") + val space = if x.guard.isEmpty then trace(i"project(${x.pat})")(project(x.pat)) else Empty space :: acc }) val checkGADTSAT = shouldCheckExamples(selTyp) val uncovered = - flatten(simplify(minus(project(selTyp), patternSpace))).filter({ s => + flatten(simplify(minus(targetSpace, patternSpace))).filter({ s => s != Empty && (!checkGADTSAT || satisfiable(s)) }) - if uncovered.nonEmpty then val deduped = dedup(uncovered) - report.warning(PatternMatchExhaustivity(showSpaces(deduped), m), m.selector) + report.warning(PatternMatchExhaustivity(deduped.map(display), m), m.selector) } private def reachabilityCheckable(sel: Tree)(using Context): Boolean = @@ -909,17 +853,16 @@ object SpaceEngine { && !sel.tpe.widen.isRef(defn.QuotedExprClass) && !sel.tpe.widen.isRef(defn.QuotedTypeClass) - def checkReachability(m: Match)(using Context): Unit = trace(i"checkReachability($m)", debug) { + def checkReachability(m: Match)(using Context): Unit = trace(i"checkReachability($m)") { val cases = m.cases.toIndexedSeq val selTyp = toUnderlying(m.selector.tpe).dealias - debug.println(i"selTyp = $selTyp") val isNullable = selTyp.classSymbol.isNullableClass - val targetSpace = if isNullable + val targetSpace = trace(i"targetSpace($selTyp)")(if isNullable then project(OrType(selTyp, ConstantType(Constant(null)), soft = false)) else project(selTyp) - debug.println(s"targetSpace: ${show(targetSpace)}") + ) var i = 0 val len = cases.length @@ -929,16 +872,11 @@ object SpaceEngine { while (i < len) { val CaseDef(pat, guard, _) = cases(i) - debug.println(i"case pattern: $pat") - - val curr = project(pat) - debug.println(i"reachable? ${show(curr)}") + val curr = trace(i"project($pat)")(project(pat)) - val prev = simplify(Or(prevs)) - debug.println(s"prev: ${show(prev)}") + val covered = trace("covered")(simplify(intersect(curr, targetSpace))) - val covered = simplify(intersect(curr, targetSpace)) - debug.println(s"covered: ${show(covered)}") + val prev = trace("prev")(simplify(Or(prevs))) if prev == Empty && covered == Empty then // defer until a case is reachable deferred ::= pat diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 004b21ce4fb5..8a1db87a4f92 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -34,6 +34,7 @@ import Denotations.SingleDenotation import annotation.threadUnsafe import scala.util.control.NonFatal +import dotty.tools.dotc.inlines.Inlines object Applications { import tpd.* @@ -1408,6 +1409,50 @@ trait Applications extends Compatibility { } } + /** Inlines the unapply function before the dummy argument + * + * A call `P.unapply[...](using l1, ..)(`dummy`)(using t1, ..)` becomes + * ``` + * { + * class $anon { + * def unapply(s: S)(using t1: T1, ..): R = + * ... // inlined code for: P.unapply[...](using l1, ..)(s)(using t1, ..) + * } + * new $anon + * }.unapply(`dummy`)(using t1, ..) + * ``` + */ + def inlinedUnapplyFnAndApp(dummyArg: Tree, unapplyAppCall: Tree): (Tree, Tree) = + def rec(unapp: Tree): (Tree, Tree) = + unapp match + case DynamicUnapply(_) => + report.error(em"Structural unapply is not supported", unapplyFn.srcPos) + (unapplyFn, unapplyAppCall) + case Apply(fn, `dummyArg` :: Nil) => + val inlinedUnapplyFn = Inlines.inlinedUnapplyFun(fn) + (inlinedUnapplyFn, inlinedUnapplyFn.appliedToArgs(`dummyArg` :: Nil)) + case Apply(fn, args) => + val (fn1, app) = rec(fn) + (fn1, tpd.cpy.Apply(unapp)(app, args)) + + if unapplyAppCall.symbol.isAllOf(Transparent | Inline) then rec(unapplyAppCall) + else (unapplyFn, unapplyAppCall) + end inlinedUnapplyFnAndApp + + def unapplyImplicits(dummyArg: Tree, unapp: Tree): List[Tree] = + val res = List.newBuilder[Tree] + def loop(unapp: Tree): Unit = unapp match + case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); res ++= args2 + case Apply(unapply, `dummyArg` :: Nil) => + case Inlined(u, _, _) => loop(u) + case DynamicUnapply(_) => report.error(em"Structural unapply is not supported", unapplyFn.srcPos) + case Apply(fn, args) => assert(args.nonEmpty); loop(fn); res ++= args + case _ => ().assertingErrorsReported + + loop(unapp) + res.result() + end unapplyImplicits + /** Add a `Bind` node for each `bound` symbol in a type application `unapp` */ def addBinders(unapp: Tree, bound: List[Symbol]) = unapp match { case TypeApply(fn, args) => @@ -1446,20 +1491,10 @@ trait Applications extends Compatibility { unapplyArgType val dummyArg = dummyTreeOfType(ownType) - val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil))) - def unapplyImplicits(unapp: Tree): List[Tree] = { - val res = List.newBuilder[Tree] - def loop(unapp: Tree): Unit = unapp match { - case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); res ++= args2 - case Apply(unapply, `dummyArg` :: Nil) => - case Inlined(u, _, _) => loop(u) - case DynamicUnapply(_) => report.error(em"Structural unapply is not supported", unapplyFn.srcPos) - case Apply(fn, args) => assert(args.nonEmpty); loop(fn); res ++= args - case _ => ().assertingErrorsReported - } - loop(unapp) - res.result() - } + val (newUnapplyFn, unapplyApp) = + val unapplyAppCall = withMode(Mode.NoInline): + typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil))) + inlinedUnapplyFnAndApp(dummyArg, unapplyAppCall) var argTypes = unapplyArgs(unapplyApp.tpe, unapplyFn, args, tree.srcPos) for (argType <- argTypes) assert(!isBounds(argType), unapplyApp.tpe.show) @@ -1475,7 +1510,7 @@ trait Applications extends Compatibility { List.fill(argTypes.length - args.length)(WildcardType) } val unapplyPatterns = bunchedArgs.lazyZip(argTypes) map (typed(_, _)) - val result = assignType(cpy.UnApply(tree)(unapplyFn, unapplyImplicits(unapplyApp), unapplyPatterns), ownType) + val result = assignType(cpy.UnApply(tree)(newUnapplyFn, unapplyImplicits(dummyArg, unapplyApp), unapplyPatterns), ownType) unapp.println(s"unapply patterns = $unapplyPatterns") if (ownType.stripped eq selType.stripped) || ownType.isError then result else tryWithTypeTest(Typed(result, TypeTree(ownType)), selType) @@ -2088,34 +2123,27 @@ trait Applications extends Compatibility { else resolveMapped(alts1, _.widen.appliedTo(targs1.tpes), pt1) case pt => - val compat0 = pt.dealias match - case defn.FunctionNOf(args, resType, _) => - narrowByTypes(alts, args, resType) - case _ => - Nil - if (compat0.isEmpty) then - val compat = alts.filterConserve(normalizedCompatible(_, pt, keepConstraint = false)) - if (compat.isEmpty) - /* - * the case should not be moved to the enclosing match - * since SAM type must be considered only if there are no candidates - * For example, the second f should be chosen for the following code: - * def f(x: String): Unit = ??? - * def f: java.io.OutputStream = ??? - * new java.io.ObjectOutputStream(f) - */ - pt match { - case SAMType(mtp, _) => - narrowByTypes(alts, mtp.paramInfos, mtp.resultType) - case _ => - // pick any alternatives that are not methods since these might be convertible - // to the expected type, or be used as extension method arguments. - val convertible = alts.filterNot(alt => - normalize(alt, IgnoredProto(pt)).widenSingleton.isInstanceOf[MethodType]) - if convertible.length == 1 then convertible else compat - } - else compat - else compat0 + val compat = alts.filterConserve(normalizedCompatible(_, pt, keepConstraint = false)) + if compat.isEmpty then + pt match + case SAMType(mtp, _) => + // If we have a SAM type as expected type, treat it as if the expression was eta-expanded + // Note 1: No need to do that for function types, the previous normalizedCompatible test already + // handles those. + // Note 2: This case should not be moved to the enclosing match + // since fSAM types must be considered only if there are no candidates. + // For example, the second f should be chosen for the following code: + // def f(x: String): Unit = ??? + // def f: java.io.OutputStream = ??? + // new java.io.ObjectOutputStream(f) + narrowByTypes(alts, mtp.paramInfos, mtp.resultType) + case _ => + // pick any alternatives that are not methods since these might be convertible + // to the expected type, or be used as extension method arguments. + val convertible = alts.filterNot(alt => + normalize(alt, IgnoredProto(pt)).widenSingleton.isInstanceOf[MethodType]) + if convertible.length == 1 then convertible else compat + else compat } /** The type of alternative `alt` after instantiating its first parameter diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 81375fe73549..5fc63f4575e3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -38,7 +38,7 @@ import config.Feature.sourceVersion import config.SourceVersion.* import config.MigrationVersion import printing.Formatting.hlAsKeyword -import cc.isCaptureChecking +import cc.{isCaptureChecking, isRetainsLike} import collection.mutable import reporting.* @@ -332,8 +332,14 @@ object Checking { || sym.owner.isContainedIn(prefix.cls) // sym reachable through member references ) case prefix: NamedType => - (!sym.is(Private) && prefix.derivesFrom(sym.owner)) || - (!prefix.symbol.moduleClass.isStaticOwner && isInteresting(prefix.prefix)) + !sym.is(Private) && prefix.derivesFrom(sym.owner) + || { + val pcls = prefix.symbol.moduleClass + if pcls.isStaticOwner then + pcls.span.exists && pcls.defRunId == ctx.runId // cheaper approximation to isDefinedInCurrentRun + else + isInteresting(prefix.prefix) + } case SuperType(thistp, _) => isInteresting(thistp) case AndType(tp1, tp2) => isInteresting(tp1) || isInteresting(tp2) case OrType(tp1, tp2) => isInteresting(tp1) && isInteresting(tp2) @@ -342,15 +348,27 @@ object Checking { case _ => false } - if (isInteresting(pre)) { - val pre1 = this(pre, false, false) - if (locked.contains(tp) || tp.symbol.infoOrCompleter.isInstanceOf[NoCompleter]) - throw CyclicReference(tp.symbol) - locked += tp - try if (!tp.symbol.isClass) checkInfo(tp.info) - finally locked -= tp - tp.withPrefix(pre1) - } + if isInteresting(pre) then + val traceCycles = CyclicReference.isTraced + try + if traceCycles then + CyclicReference.pushTrace("explore ", tp.symbol, " for cyclic references") + val pre1 = this(pre, false, false) + if locked.contains(tp) + || tp.symbol.infoOrCompleter.isInstanceOf[NoCompleter] + then + throw CyclicReference(tp.symbol) + locked += tp + try + if tp.symbol.isOpaqueAlias then + checkInfo(TypeAlias(tp.translucentSuperType)) + else if !tp.symbol.isClass then + checkInfo(tp.info) + finally + locked -= tp + tp.withPrefix(pre1) + finally + if traceCycles then CyclicReference.popTrace() else tp } catch { @@ -387,11 +405,15 @@ object Checking { */ def checkNonCyclic(sym: Symbol, info: Type, reportErrors: Boolean)(using Context): Type = { val checker = withMode(Mode.CheckCyclic)(new CheckNonCyclicMap(sym, reportErrors)) - try checker.checkInfo(info) + try + val toCheck = info match + case info: RealTypeBounds if sym.isOpaqueAlias => TypeAlias(sym.opaqueAlias) + case _ => info + checker.checkInfo(toCheck) catch { case ex: CyclicReference => if (reportErrors) - errorType(IllegalCyclicTypeReference(sym, checker.where, checker.lastChecked), sym.srcPos) + errorType(IllegalCyclicTypeReference(ex, sym, checker.where, checker.lastChecked), sym.srcPos) else info } } @@ -683,8 +705,7 @@ object Checking { declaredParents = tp.declaredParents.map(p => transformedParent(apply(p))) ) - case tp @ AnnotatedType(underlying, annot) - if annot.symbol == defn.RetainsAnnot || annot.symbol == defn.RetainsByNameAnnot => + case tp @ AnnotatedType(underlying, annot) if annot.symbol.isRetainsLike => val underlying1 = this(underlying) val saved = inCaptureSet inCaptureSet = true @@ -1158,9 +1179,7 @@ trait Checking { /** Check that class does not declare same symbol twice */ def checkNoDoubleDeclaration(cls: Symbol)(using Context): Unit = { - val seen = new mutable.HashMap[Name, List[Symbol]] { - override def default(key: Name) = Nil - } + val seen = new mutable.HashMap[Name, List[Symbol]].withDefaultValue(Nil) typr.println(i"check no double declarations $cls") def checkDecl(decl: Symbol): Unit = { @@ -1169,7 +1188,8 @@ trait Checking { def javaFieldMethodPair = decl.is(JavaDefined) && other.is(JavaDefined) && decl.is(Method) != other.is(Method) - if (decl.matches(other) && !javaFieldMethodPair) { + def staticNonStaticPair = decl.isScalaStatic != other.isScalaStatic + if (decl.matches(other) && !javaFieldMethodPair && !staticNonStaticPair) { def doubleDefError(decl: Symbol, other: Symbol): Unit = if (!decl.info.isErroneous && !other.info.isErroneous) report.error(DoubleDefinition(decl, other, cls), decl.srcPos) diff --git a/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala b/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala index 91303b00618c..c22d03ca77d7 100644 --- a/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala @@ -32,10 +32,16 @@ class CrossVersionChecks extends MiniPhase: checkMigration(sym, pos, xMigrationValue) end checkUndesiredProperties - /** If @deprecated is present, and the point of reference is not enclosed - * in either a deprecated member or a scala bridge method, issue a warning. - */ - private def checkDeprecated(sym: Symbol, pos: SrcPos)(using Context): Unit = + /**Skip warnings for synthetic members of case classes during declaration and + * scan the chain of outer declaring scopes from the current context + * a deprecation warning will be skipped if one the following holds + * for a given declaring scope: + * - the symbol associated with the scope is also deprecated. + * - if and only if `sym` is an enum case, the scope is either + * a module that declares `sym`, or the companion class of the + * module that declares `sym`. + */ + def skipWarning(sym: Symbol)(using Context): Boolean = /** is the owner an enum or its companion and also the owner of sym */ def isEnumOwner(owner: Symbol)(using Context) = @@ -46,26 +52,22 @@ class CrossVersionChecks extends MiniPhase: def isDeprecatedOrEnum(owner: Symbol)(using Context) = // pre: sym is an enumcase - owner.isDeprecated - || isEnumOwner(owner) - - /**Skip warnings for synthetic members of case classes during declaration and - * scan the chain of outer declaring scopes from the current context - * a deprecation warning will be skipped if one the following holds - * for a given declaring scope: - * - the symbol associated with the scope is also deprecated. - * - if and only if `sym` is an enum case, the scope is either - * a module that declares `sym`, or the companion class of the - * module that declares `sym`. - */ - def skipWarning(using Context): Boolean = - (ctx.owner.is(Synthetic) && sym.is(CaseClass)) - || ctx.owner.ownersIterator.exists(if sym.isEnumCase then isDeprecatedOrEnum else _.isDeprecated) + owner.isDeprecated || isEnumOwner(owner) + + (ctx.owner.is(Synthetic) && sym.is(CaseClass)) + || ctx.owner.ownersIterator.exists(if sym.isEnumCase then isDeprecatedOrEnum else _.isDeprecated) + end skipWarning + + + /** If @deprecated is present, and the point of reference is not enclosed + * in either a deprecated member or a scala bridge method, issue a warning. + */ + private def checkDeprecated(sym: Symbol, pos: SrcPos)(using Context): Unit = // Also check for deprecation of the companion class for synthetic methods val toCheck = sym :: (if sym.isAllOf(SyntheticMethod) then sym.owner.companionClass :: Nil else Nil) for sym <- toCheck; annot <- sym.getAnnotation(defn.DeprecatedAnnot) do - if !skipWarning then + if !skipWarning(sym) then val msg = annot.argumentConstant(0).map(": " + _.stringValue).getOrElse("") val since = annot.argumentConstant(1).map(" since " + _.stringValue).getOrElse("") report.deprecationWarning(em"${sym.showLocated} is deprecated${since}${msg}", pos) @@ -107,6 +109,18 @@ class CrossVersionChecks extends MiniPhase: } } + /** ??? */ + def checkDeprecatedInheritance(parents: List[Tree])(using Context): Unit = { + for parent <- parents + psym = parent.tpe.classSymbol + annot <- psym.getAnnotation(defn.DeprecatedInheritanceAnnot) + if !skipWarning(psym) + do + val msg = annot.argumentConstantString(0).map(msg => s": $msg").getOrElse("") + val since = annot.argumentConstantString(1).map(version => s" (since: $version)").getOrElse("") + report.deprecationWarning(em"inheritance from $psym is deprecated$since$msg", parent.srcPos) + } + override def transformValDef(tree: ValDef)(using Context): ValDef = checkDeprecatedOvers(tree) checkExperimentalAnnots(tree.symbol) @@ -122,6 +136,10 @@ class CrossVersionChecks extends MiniPhase: checkExperimentalAnnots(tree.symbol) tree + override def transformTemplate(tree: tpd.Template)(using Context): tpd.Tree = + checkDeprecatedInheritance(tree.parents) + tree + override def transformIdent(tree: Ident)(using Context): Ident = { checkUndesiredProperties(tree.symbol, tree.srcPos) tree @@ -141,10 +159,12 @@ class CrossVersionChecks extends MiniPhase: val tpe = tree.tpe tpe.foreachPart { case TypeRef(_, sym: Symbol) => - checkDeprecated(sym, tree.srcPos) + if tree.span.isSourceDerived then + checkDeprecated(sym, tree.srcPos) checkExperimentalRef(sym, tree.srcPos) case TermRef(_, sym: Symbol) => - checkDeprecated(sym, tree.srcPos) + if tree.span.isSourceDerived then + checkDeprecated(sym, tree.srcPos) checkExperimentalRef(sym, tree.srcPos) case _ => } diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 389669beff01..c3bf2dd822c9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1074,7 +1074,7 @@ trait Implicits: if (argument.isEmpty) i"missing implicit parameter of type $pt after typer at phase ${ctx.phase.phaseName}" else i"type error: ${argument.tpe} does not conform to $pt${err.whyNoMatchStr(argument.tpe, pt)}") - val usableForInference = !pt.unusableForInference + val usableForInference = pt.exists && !pt.unusableForInference && (argument.isEmpty || !argument.tpe.unusableForInference) val result0 = if usableForInference then diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 7e35b8be8caa..ed37a869d612 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -205,7 +205,7 @@ object Inferencing { private def instantiate(tvar: TypeVar, fromBelow: Boolean): Boolean = if fromBelow && force.canImprove(tvar) then val inst = tvar.typeToInstantiateWith(fromBelow = true) - if apply(true, inst) then + if isFullyDefined(inst, ForceDegree.none) then // need to recursively check before improving, since improving adds type vars // which should not be instantiated at this point val better = improve(tvar)(inst) @@ -383,8 +383,9 @@ object Inferencing { def isSkolemFree(tp: Type)(using Context): Boolean = !tp.existsPart(_.isInstanceOf[SkolemType]) - /** The list of uninstantiated type variables bound by some prefix of type `T` which - * occur in at least one formal parameter type of a prefix application. + /** The list of uninstantiated type variables bound by some prefix of type `T` or + * by arguments of an application prefix, which occur at least once as a formal type parameter + * of an application either from a prefix or an argument of an application node. * Considered prefixes are: * - The function `f` of an application node `f(e1, .., en)` * - The function `f` of a type application node `f[T1, ..., Tn]` @@ -392,8 +393,10 @@ object Inferencing { * - The result expression `e` of a block `{s1; .. sn; e}`. */ def tvarsInParams(tree: Tree, locked: TypeVars)(using Context): List[TypeVar] = { - @tailrec def boundVars(tree: Tree, acc: List[TypeVar]): List[TypeVar] = tree match { - case Apply(fn, _) => boundVars(fn, acc) + def boundVars(tree: Tree, acc: List[TypeVar]): List[TypeVar] = tree match { + case Apply(fn, args) => + val argTpVars = args.flatMap(boundVars(_, Nil)) + boundVars(fn, acc ++ argTpVars) case TypeApply(fn, targs) => val tvars = targs.filter(_.isInstanceOf[InferredTypeTree]).tpes.collect { case tvar: TypeVar @@ -406,16 +409,18 @@ object Inferencing { case Block(_, expr) => boundVars(expr, acc) case _ => acc } - @tailrec def occurring(tree: Tree, toTest: List[TypeVar], acc: List[TypeVar]): List[TypeVar] = + def occurring(tree: Tree, toTest: List[TypeVar], acc: List[TypeVar]): List[TypeVar] = if (toTest.isEmpty) acc else tree match { - case Apply(fn, _) => + case Apply(fn, args) => + val argsOcc = args.flatMap(occurring(_, toTest, Nil)) + val argsNocc = toTest.filterNot(argsOcc.contains) fn.tpe.widen match { case mtp: MethodType => - val (occ, nocc) = toTest.partition(tvar => mtp.paramInfos.exists(tvar.occursIn)) - occurring(fn, nocc, occ ::: acc) + val (occ, nocc) = argsNocc.partition(tvar => mtp.paramInfos.exists(tvar.occursIn)) + occurring(fn, nocc, occ ::: argsOcc ::: acc) case _ => - occurring(fn, toTest, acc) + occurring(fn, argsNocc, argsOcc ::: acc) } case TypeApply(fn, targs) => occurring(fn, toTest, acc) case Select(pre, _) => occurring(pre, toTest, acc) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index f8ced1c6599a..3af87d311d9d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -22,6 +22,7 @@ import parsing.JavaParsers.JavaParser import parsing.Parsers.Parser import Annotations.* import Inferencing.* +import Nullables.* import transform.ValueClasses.* import TypeErasure.erasure import reporting.* @@ -784,12 +785,19 @@ class Namer { typer: Typer => protected def localContext(owner: Symbol): FreshContext = ctx.fresh.setOwner(owner).setTree(original) + /** Stores the latest NotNullInfos (updated by `setNotNullInfos`) */ + private var myNotNullInfos: List[NotNullInfo] | Null = null + /** The context with which this completer was created */ - given creationContext: Context = ictx + given creationContext[Dummy_so_its_a_def]: Context = + if myNotNullInfos == null then ictx else ictx.withNotNullInfos(myNotNullInfos.nn) // make sure testing contexts are not captured by completers assert(!ictx.reporter.isInstanceOf[ExploringReporter]) + def setNotNullInfos(infos: List[NotNullInfo]): Unit = + myNotNullInfos = infos + protected def typeSig(sym: Symbol): Type = original match case original: ValDef => if (sym.is(Module)) moduleValSig(sym) @@ -871,6 +879,10 @@ class Namer { typer: Typer => * with a user-defined method in the same scope with a matching type. */ private def invalidateIfClashingSynthetic(denot: SymDenotation): Unit = + + def isJavaRecord(owner: Symbol) = + owner.is(JavaDefined) && owner.derivesFrom(defn.JavaRecordClass) + def isCaseClassOrCompanion(owner: Symbol) = owner.isClass && { if (owner.is(Module)) owner.linkedClass.is(CaseClass) @@ -894,9 +906,9 @@ class Namer { typer: Typer => && (definesMember || inheritsConcreteMember) ) || - // remove synthetic constructor of a java Record if it clashes with a non-synthetic constructor - (denot.isConstructor - && denot.owner.is(JavaDefined) && denot.owner.derivesFrom(defn.JavaRecordClass) + // remove synthetic constructor or method of a java Record if it clashes with a non-synthetic constructor + (isJavaRecord(denot.owner) + && denot.is(Method) && denot.owner.unforcedDecls.lookupAll(denot.name).exists(c => c != denot.symbol && c.info.matches(denot.info)) ) ) @@ -1191,7 +1203,7 @@ class Namer { typer: Typer => target = target.etaExpand(target.typeParams) newSymbol( cls, forwarderName, - Exported | Final, + MandatoryExportTypeFlags | (sym.flags & RetainedExportTypeFlags), TypeAlias(target), coord = span) // Note: This will always create unparameterzied aliases. So even if the original type is @@ -1237,16 +1249,19 @@ class Namer { typer: Typer => then addPathMethodParams(pathMethod.info, mbr.info.widenExpr) else mbr.info.ensureMethodic (EmptyFlags, mbrInfo) - var flagMask = RetainedExportFlags - if sym.isTerm then flagMask |= HasDefaultParams | NoDefaultParams - var mbrFlags = Exported | Method | Final | maybeStable | sym.flags & flagMask - if sym.is(ExtensionMethod) || pathMethod.exists then - mbrFlags |= ExtensionMethod + var mbrFlags = MandatoryExportTermFlags | maybeStable | (sym.flags & RetainedExportTermFlags) + if pathMethod.exists then mbrFlags |= ExtensionMethod val forwarderName = checkNoConflict(alias, isPrivate = false, span) newSymbol(cls, forwarderName, mbrFlags, mbrInfo, coord = span) forwarder.info = avoidPrivateLeaks(forwarder) - forwarder.addAnnotations(sym.annotations.filterConserve(_.symbol != defn.BodyAnnot)) + forwarder.addAnnotations(sym.annotations.filterConserve { annot => + annot.symbol != defn.BodyAnnot + && annot.symbol != defn.TailrecAnnot + && annot.symbol != defn.MainAnnot + && !annot.symbol.derivesFrom(defn.MacroAnnotationClass) + && !annot.symbol.derivesFrom(defn.MainAnnotationClass) + }) if forwarder.isType then buf += tpd.TypeDef(forwarder.asType).withSpan(span) @@ -1719,8 +1734,9 @@ class Namer { typer: Typer => val tpe = (paramss: @unchecked) match case TypeSymbols(tparams) :: TermSymbols(vparams) :: Nil => tpFun(tparams, vparams) case TermSymbols(vparams) :: Nil => tpFun(Nil, vparams) + val rhsCtx = prepareRhsCtx(ctx.fresh, paramss) if (isFullyDefined(tpe, ForceDegree.none)) tpe - else typedAheadExpr(mdef.rhs, tpe).tpe + else typedAheadExpr(mdef.rhs, tpe)(using rhsCtx).tpe case TypedSplice(tpt: TypeTree) if !isFullyDefined(tpt.tpe, ForceDegree.none) => mdef match { @@ -1918,14 +1934,7 @@ class Namer { typer: Typer => var rhsCtx = ctx.fresh.addMode(Mode.InferringReturnType) if sym.isInlineMethod then rhsCtx = rhsCtx.addMode(Mode.InlineableBody) if sym.is(ExtensionMethod) then rhsCtx = rhsCtx.addMode(Mode.InExtensionMethod) - val typeParams = paramss.collect { case TypeSymbols(tparams) => tparams }.flatten - if (typeParams.nonEmpty) { - // we'll be typing an expression from a polymorphic definition's body, - // so we must allow constraining its type parameters - // compare with typedDefDef, see tests/pos/gadt-inference.scala - rhsCtx.setFreshGADTBounds - rhsCtx.gadtState.addToConstraint(typeParams) - } + rhsCtx = prepareRhsCtx(rhsCtx, paramss) def typedAheadRhs(pt: Type) = PrepareInlineable.dropInlineIfError(sym, @@ -1970,4 +1979,15 @@ class Namer { typer: Typer => lhsType orElse WildcardType } end inferredResultType + + /** Prepare a GADT-aware context used to type the RHS of a ValOrDefDef. */ + def prepareRhsCtx(rhsCtx: FreshContext, paramss: List[List[Symbol]])(using Context): FreshContext = + val typeParams = paramss.collect { case TypeSymbols(tparams) => tparams }.flatten + if typeParams.nonEmpty then + // we'll be typing an expression from a polymorphic definition's body, + // so we must allow constraining its type parameters + // compare with typedDefDef, see tests/pos/gadt-inference.scala + rhsCtx.setFreshGADTBounds + rhsCtx.gadtState.addToConstraint(typeParams) + rhsCtx } diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 6b72f3a8b56e..53ae7438d381 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -126,7 +126,7 @@ object ProtoTypes { constrainResult(mt, pt) } } else { - // Best-effort to fix https://github.com/lampepfl/dotty/issues/9685 in the 3.3.x series + // Best-effort to fix https://github.com/scala/scala3/issues/9685 in the 3.3.x series // while preserving source compatibility as much as possible val methodMatchedType = constrainResult(mt, wildApprox(pt)) meth.is(Transparent) || methodMatchedType diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index fb692446f1df..f0914a9f6664 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -1001,6 +1001,10 @@ object RefChecks { report.error(em"private $sym cannot override ${other.showLocated}", sym.srcPos) end checkNoPrivateOverrides + def checkVolatile(sym: Symbol)(using Context): Unit = + if sym.isVolatile && !sym.is(Mutable) then + report.warning(VolatileOnVal(), sym.srcPos) + /** Check that unary method definition do not receive parameters. * They can only receive inferred parameters such as type parameters and implicit parameters. */ @@ -1183,6 +1187,7 @@ class RefChecks extends MiniPhase { thisPhase => if tree.symbol.exists then checkNoPrivateOverrides(tree) val sym = tree.symbol + checkVolatile(sym) if (sym.exists && sym.owner.isTerm) { tree.rhs match { case Ident(nme.WILDCARD) => report.error(UnboundPlaceholderParameter(), sym.srcPos) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index fe2a6f92eb97..f1db302e958c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -48,7 +48,7 @@ import staging.StagingLevel import reporting.* import Nullables.* import NullOpsDecorator.* -import cc.CheckCaptures +import cc.{CheckCaptures, isRetainsLike} import config.Config import config.MigrationVersion @@ -944,7 +944,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer * (x: T) to (x @ (w: T)). This is either `_` or `_*`. */ def cases(ifPat: => Tree, ifExpr: => Tree, wildName: TermName) = tree.expr match { - case id: untpd.Ident if (ctx.mode is Mode.Pattern) && untpd.isVarPattern(id) => + case id: untpd.Ident if (ctx.mode is Mode.Pattern) => if (id.name == nme.WILDCARD || id.name == nme.WILDCARD_STAR) ifPat else { import untpd.* @@ -1738,8 +1738,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer // Replace the underspecified expected type by one based on the closure method type defn.PartialFunctionOf(mt.firstParamTypes.head, mt.resultType) else - report.error(em"result type of lambda is an underspecified SAM type $samParent", tree.srcPos) - samParent + errorType(em"result type of lambda is an underspecified SAM type $samParent", tree.srcPos) TypeTree(targetTpe) case _ => if (mt.isParamDependent) @@ -1938,7 +1937,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if (bounds != null) sym.info = bounds } b - case t: UnApply if t.symbol.is(Inline) => Inlines.inlinedUnapply(t) + case t: UnApply if t.symbol.is(Inline) => + assert(!t.symbol.is(Transparent)) + cpy.UnApply(t)(fun = Inlines.inlinedUnapplyFun(t.fun)) // TODO inline these in the inlining phase (see #19382) case t => t } } @@ -2547,10 +2548,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer def canBeInvalidated(sym: Symbol): Boolean = sym.is(Synthetic) && (desugar.isRetractableCaseClassMethodName(sym.name) || - (sym.isConstructor && sym.owner.derivesFrom(defn.JavaRecordClass))) + (sym.owner.is(JavaDefined) && sym.owner.derivesFrom(defn.JavaRecordClass) && sym.is(Method))) if !sym.info.exists then - // it's a discarded method (synthetic case class method or synthetic java record constructor), drop it + // it's a discarded method (synthetic case class method or synthetic java record constructor or overriden member), drop it assert(canBeInvalidated(sym)) sym.owner.info.decls.openForMutations.unlink(sym) return EmptyTree @@ -2939,9 +2940,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val arg1 = typed(tree.arg, pt) if (ctx.mode is Mode.Type) { val cls = annot1.symbol.maybeOwner - if Feature.ccEnabled - && (cls == defn.RetainsAnnot || cls == defn.RetainsByNameAnnot) - then + if Feature.ccEnabled && cls.isRetainsLike then CheckCaptures.checkWellformed(arg1, annot1) if arg1.isType then assignType(cpy.Annotated(tree)(arg1, annot1), arg1, annot1) @@ -3362,12 +3361,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer mdef.getAttachment(SymOfTree) match { case Some(sym) => sym.infoOrCompleter match { case completer: Namer#Completer => - if (completer.creationContext.notNullInfos ne ctx.notNullInfos) + if completer.creationContext.notNullInfos ne ctx.notNullInfos then // The RHS of a val def should know about not null facts established // in preceding statements (unless the DefTree is completed ahead of time, // then it is impossible). - sym.info = Completer(completer.original)( - completer.creationContext.withNotNullInfos(ctx.notNullInfos)) + completer.setNotNullInfos(ctx.notNullInfos) true case _ => // If it has been completed, then it must be because there is a forward reference @@ -4300,8 +4298,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case _ => } - /** Convert constructor proxy reference to a new expression */ - def newExpr = + /** If `tree` is a constructor proxy reference, convert it to a `new` expression, + * otherwise return EmptyTree. + */ + def newExpr(tree: Tree): Tree = + val ctorResultType = applyProxyResultType(tree) + if !ctorResultType.exists then return EmptyTree val qual = qualifier(tree) val tpt = qual match case Ident(name) => @@ -4312,7 +4314,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer cpy.Ident(qual)(qual.symbol.name.sourceModuleName.toTypeName) case _ => errorTree(tree, em"cannot convert from $tree to an instance creation expression") - val tycon = tree.tpe.widen.finalResultType.underlyingClassRef(refinementOK = false) + val tycon = ctorResultType.underlyingClassRef(refinementOK = false) typed( untpd.Select( untpd.New(untpd.TypedSplice(tpt.withType(tycon))), @@ -4320,9 +4322,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer pt) .showing(i"convert creator $tree -> $result", typr) - def isApplyProxy(tree: Tree) = tree match - case Select(_, nme.apply) => tree.symbol.isAllOf(ApplyProxyFlags) - case _ => false + /** If `tree` is a constructor proxy reference, return the type it constructs, + * otherwise return NoType. + */ + def applyProxyResultType(tree: Tree): Type = tree match + case Select(_, nme.apply) => + // can't use tree.symbol and tree.tpe.widen.finalResultType, because when overloaded + // tree.symbol is NoSymbol (via MultiDenotation.symbol) and tree.tpe won't widen. + tree.denot.altsWith(_.isAllOf(ApplyProxyFlags)) match + case denot :: _ => + // any of the constructors will do, in order to get the result type, so using the first one + denot.info.widen.finalResultType + case _ => NoType + case _ => NoType tree match { case _: MemberDef | _: PackageDef | _: Import | _: WithoutTypeOrPos[?] | _: Closure => tree @@ -4336,7 +4348,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if needsTupledDual(ref, pt) && Feature.autoTuplingEnabled => adapt(tree, pt.tupledDual, locked) case _ => - adaptOverloaded(ref) + newExpr(tree).orElse(adaptOverloaded(ref)) } case poly: PolyType if !(ctx.mode is Mode.Type) && dummyTreeOfType.unapply(tree).isEmpty => @@ -4345,22 +4357,21 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer // Test case was but i18695.scala, but it got fixed by a different tweak in #18719. // We leave test for this condition in as a defensive measure in case // it arises somewhere else. - if isApplyProxy(tree) then newExpr - else if pt.isInstanceOf[PolyProto] then tree - else - var typeArgs = tree match - case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo.map(TypeTree(_)) - case _ => Nil - if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree)) - convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs))) + newExpr(tree).orElse: + if pt.isInstanceOf[PolyProto] then tree + else + var typeArgs = tree match + case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo.map(TypeTree(_)) + case _ => Nil + if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree)) + convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs))) case wtp => val isStructuralCall = wtp.isValueType && isStructuralTermSelectOrApply(tree) if (isStructuralCall) readaptSimplified(handleStructural(tree)) else pt match { case pt: FunProto => - if isApplyProxy(tree) then newExpr - else adaptToArgs(wtp, pt) + newExpr(tree).orElse(adaptToArgs(wtp, pt)) case pt: PolyProto if !wtp.isImplicitMethod => tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply case _ => diff --git a/compiler/src/dotty/tools/dotc/util/Signatures.scala b/compiler/src/dotty/tools/dotc/util/Signatures.scala index ce05cfb40294..9131f4f761a2 100644 --- a/compiler/src/dotty/tools/dotc/util/Signatures.scala +++ b/compiler/src/dotty/tools/dotc/util/Signatures.scala @@ -1,13 +1,18 @@ package dotty.tools.dotc package util +import dotty.tools.dotc.ast.NavigateAST +import dotty.tools.dotc.ast.Positioned +import dotty.tools.dotc.ast.untpd +import dotty.tools.dotc.core.NameOps.* +import dotty.tools.dotc.core.StdNames.nme +import dotty.tools.dotc.core.Symbols.defn + import ast.Trees.* import ast.tpd -import core.Constants.Constant import core.Contexts.* import core.Denotations.{SingleDenotation, Denotation} import core.Flags -import core.NameOps.isUnapplyName import core.Names.* import core.NameKinds import core.Types.* @@ -31,54 +36,56 @@ object Signatures { */ case class Signature( name: String, - tparams: List[String], paramss: List[List[Param]], returnType: Option[String], doc: Option[String] = None, denot: Option[SingleDenotation] = None ) + sealed trait Param: + def show: String + val doc: Option[String] = None + /** * Represent a method's parameter. * - * @param name The name of the parameter - * @param tpe The type of the parameter - * @param doc The documentation of this parameter - * @param isImplicit Is this parameter implicit? + * @param name The name of the parameter + * @param tpe The type of the parameter + * @param doc The documentation of this parameter + * @param isImplicit Is this parameter implicit? + * @param isReordered Is the parameter reordered in its parameter list? */ - case class Param(name: String, tpe: String, doc: Option[String] = None, isImplicit: Boolean = false) { - def show: String = if name.nonEmpty then s"$name: $tpe" else tpe - } + case class MethodParam( + name: String, + tpe: String, + override val doc: Option[String] = None, + isImplicit: Boolean = false, + isReordered: Boolean = false + ) extends Param: + def show: String = if name.nonEmpty && !isReordered then s"$name: $tpe" + else if name.nonEmpty then s"[$name: $tpe]" + else tpe /** - * Extract (current parameter index, function index, functions) method call for given position. - * - * @param path The path to the function application - * @param pos The position of the cursor + * Represent a type parameter. * - * @return A triple containing the index of the parameter being edited, the index of functeon - * being called, the list of overloads of this function). + * @param tpe The type of the parameter + * @param doc The documentation of this parameter */ - def signatureHelp(path: List[tpd.Tree], pos: Span)(using Context): (Int, Int, List[Signature]) = - computeSignatureHelp(path, pos) + case class TypeParam(tpe: String, override val doc: Option[String] = None) extends Param: + def show = tpe /** - * Extract (current parameter index, function index, functions) out of a method call. + * Extract (current parameter index, function index, functions) method call for given position. * * @param path The path to the function application - * @param span The position of the cursor + * @param pos The position of the cursor * - * @return A triple containing the index of the parameter being edited, the index of the function + * @return A triple containing the index of the parameter being edited, the index of function * being called, the list of overloads of this function). */ - @deprecated( - """This method is deprecated in favor of `signatureHelp`. - Returned denotation cannot be distinguished if its unapply or apply context""", - "3.1.3" - ) - def callInfo(path: List[tpd.Tree], span: Span)(using Context): (Int, Int, List[SingleDenotation]) = - val (paramN, funN, signatures) = computeSignatureHelp(path, span) - (paramN, funN, signatures.flatMap(_.denot)) + def signatureHelp(path: List[tpd.Tree], pos: Span)(using Context): (Int, Int, List[Signature]) = + computeSignatureHelp(path, pos) /** * Computes call info (current parameter index, function index, functions) for a method call. @@ -91,10 +98,10 @@ object Signatures { */ def computeSignatureHelp(path: List[tpd.Tree], span: Span)(using Context): (Int, Int, List[Signature]) = findEnclosingApply(path, span) match - case Apply(fun, params) => applyCallInfo(span, params, fun) + case Apply(fun, params) => applyCallInfo(span, params, fun, false) case UnApply(fun, _, patterns) => unapplyCallInfo(span, fun, patterns) - case appliedTypeTree @ AppliedTypeTree(_, types) => appliedTypeTreeCallInfo(appliedTypeTree, types) - case tp @ TypeApply(fun, types) => applyCallInfo(span, types, fun, true) + case appliedTypeTree @ AppliedTypeTree(_, types) => appliedTypeTreeCallInfo(span, appliedTypeTree, types) + case tp @ TypeApply(fun, types) => applyCallInfo(span, types, fun, isTypeApply = true) case _ => (0, 0, Nil) @@ -136,7 +143,6 @@ object Signatures { val enclosingTree = enclosingFunction.getOrElse(expr) findEnclosingApply(Interactive.pathTo(enclosingTree, span), span) - case direct :: enclosing :: _ if isClosingSymbol(direct.source(span.end -1)) => enclosing case direct :: _ => direct @@ -149,17 +155,31 @@ object Signatures { * @param fun Function tree which is being applied */ private def appliedTypeTreeCallInfo( + span: Span, fun: tpd.Tree, types: List[tpd.Tree] )(using Context): (Int, Int, List[Signature]) = val typeName = fun.symbol.name.show - val typeParams = fun.symbol.typeRef.typeParams.map(_.paramName.show) + val typeParams = fun.symbol.typeRef.typeParams.map(_.paramName.show).map(TypeParam.apply(_)) val denot = fun.denot.asSingleDenotation - val activeParameter = (types.length - 1) max 0 + val activeParameter = findCurrentParamIndex(types, span, typeParams.length - 1) - val signature = Signature(typeName, typeParams, Nil, Some(typeName) , None, Some(denot)) + val signature = Signature(typeName, List(typeParams), Some(typeName) , None, Some(denot)) (activeParameter, 0, List(signature)) + private def findOutermostCurriedApply(untpdPath: List[untpd.Tree]): Option[untpd.GenericApply] = + val trimmedPath = untpdPath.dropWhile(!_.isInstanceOf[untpd.GenericApply]) + val maybeCurriedTrees = (trimmedPath zip trimmedPath.drop(1)).takeWhile: + case (currentTree: untpd.GenericApply, nextTree: untpd.GenericApply) => + nextTree.fun == currentTree + case _ => false + .map(_._2) + + maybeCurriedTrees.lastOption.orElse: + trimmedPath.headOption + .collect: + case genericApply: untpd.GenericApply => genericApply + /** * Extracts call information for a function application and type application. * @@ -183,9 +203,10 @@ object Signatures { case Select(qual, _) => qual case _ => tree + val paramssListIndex = findParamssIndex(fun) val (alternativeIndex, alternatives) = fun.tpe match case err: ErrorType => - val (alternativeIndex, alternatives) = alternativesFromError(err, params) match + val (alternativeIndex, alternatives) = alternativesFromError(err, params, paramssListIndex) match // if we have no alternatives from error, we have to fallback to function denotation // Check `partialyFailedCurriedFunctions` test for example case (_, Nil) => @@ -204,21 +225,74 @@ object Signatures { (alternativeIndex, alternatives) if alternativeIndex < alternatives.length then - val curriedArguments = countParams(fun, alternatives(alternativeIndex)) - // We have to shift all arguments by number of type parameters to properly show activeParameter index - val typeParamsShift = if !isTypeApply then fun.symbol.denot.paramSymss.flatten.filter(_.isType).length else 0 - val paramIndex = params.indexWhere(_.span.contains(span)) match - case -1 => (params.length - 1 max 0) + curriedArguments + typeParamsShift - case n => n + curriedArguments + typeParamsShift + val alternativeSymbol = alternatives(alternativeIndex).symbol + val safeParamssListIndex = paramssListIndex min (alternativeSymbol.paramSymss.length - 1) + val previousArgs = alternativeSymbol.paramSymss.take(safeParamssListIndex).foldLeft(0)(_ + _.length) + + val untpdPath: List[untpd.Tree] = NavigateAST + .untypedPath(fun, false).collect { case untpdTree: untpd.Tree => untpdTree } + + val untpdArgs = untpdPath match + case (Ident(_) | Select(_, _)) :: New(_) :: Select(_, name) :: untpd.Apply(untpdFun, args) :: _ + if name.isConstructorName => args + case _ :: untpd.Apply(_, args) :: _ => args + case _ :: untpd.TypeApply(_, args) :: _ => args + case _ => Nil + + val currentParamsIndex = + findCurrentParamIndex(untpdArgs, span, alternativeSymbol.paramSymss(safeParamssListIndex).length - 1) val pre = treeQualifier(fun) val alternativesWithTypes = alternatives.map(_.asSeenFrom(pre.tpe.widenTermRefExpr)) - val alternativeSignatures = alternativesWithTypes.flatMap(toApplySignature) + val alternativeSignatures = alternativesWithTypes + .flatMap(toApplySignature(_, findOutermostCurriedApply(untpdPath), safeParamssListIndex)) - (paramIndex, alternativeIndex, alternativeSignatures) + val finalParamIndex = currentParamsIndex + previousArgs + (finalParamIndex, alternativeIndex, alternativeSignatures) else (0, 0, Nil) + /** Finds current parameter index + * @param args List of currently applied arguments + * @param span The position of the cursor + * @param maxIndex The maximum index of the parameter in the current apply list + * + * @return Index of the current parameter + */ + private def findCurrentParamIndex(args: List[Positioned], span: Span, maxIndex: Int)(using Context): Int = + (args.indexWhere(_.span.contains(span)) match + case -1 if args.isEmpty => 0 + case -1 => + commaIndex(args, span) match + // comma is before CURSOR, so we are in parameter b example: test("a", CURSOR) + case Some(index) if index <= span.end => args.takeWhile(_.span.end < span.start).length + // comma is after CURSOR, so we are in parameter a example: test("a" CURSOR,) + case Some(index) => args.takeWhile(_.span.start < span.end).length - 1 + // we are either in first or last parameter + case None => + if args.head.span.start >= span.end then 0 + else args.length - 1 max 0 + + case n => n + ) min maxIndex + + /** Parser ignores chars between arguments, we have to manually find the index of comma + * @param untpdArgs List of applied untyped arguments + * @param span The position of the cursor + * + * @return None if we are in first or last parameter, comma index otherwise + */ + private def commaIndex(untpdArgs: List[Positioned], span: Span)(using Context): Option[Int] = + val previousArgIndex = untpdArgs.lastIndexWhere(_.span.end < span.end) + for + previousArg <- untpdArgs.lift(previousArgIndex) + nextArg = untpdArgs.lift(previousArgIndex + 1) + text = ctx.source.content.slice(previousArg.span.end - 1, nextArg.map(_.span.start).getOrElse(span.end)) + commaIndex = text.indexOf(',') + if commaIndex != -1 + yield + commaIndex + previousArg.span.end + /** * Extracts call informatioin for function in unapply context. * @@ -235,13 +309,12 @@ object Signatures { patterns: List[tpd.Tree] )(using Context): (Int, Int, List[Signature]) = val resultType = unapplyMethodResult(fun) - val isUnapplySeq = fun.denot.name == core.Names.termName("unapplySeq") val denot = fun.denot.mapInfo(_ => resultType) val paramTypes = extractParamTypess(resultType, denot, patterns.size).flatten.map(stripAllAnnots) val paramNames = extractParamNamess(resultType, denot).flatten - val activeParameter = unapplyParameterIndex(patterns, span, paramTypes.length) + val activeParameter = findCurrentParamIndex(patterns, span, paramTypes.length - 1) val unapplySignature = toUnapplySignature(denot.asSingleDenotation, paramNames, paramTypes).toList (activeParameter, 0, unapplySignature) @@ -303,27 +376,22 @@ object Signatures { case other => other.stripAnnots /** - * Get index of currently edited parameter in unapply context. - * - * @param patterns Currently applied patterns for unapply method - * @param span The position of the cursor - * @param maximumParams Number of parameters taken by unapply method - * @return Index of currently edited parameter - */ - private def unapplyParameterIndex(patterns: List[tpd.Tree], span: Span, maximumParams: Int)(using Context): Int = - val patternPosition = patterns.indexWhere(_.span.contains(span)) - (patternPosition, patterns.length) match - case (-1, 0) => 0 // there are no patterns yet so it must be first one - case (-1, pos) => -1 // there are patterns, we must be outside range so we set no active parameter - case _ => (maximumParams - 1) min patternPosition max 0 // handle unapplySeq to always highlight Seq[A] on elements - - /** - * Checks if tree is valid for signatureHelp. Skipped trees are either tuple type or function type + * Checks if tree is valid for signatureHelp. Skipped trees are either tuple or function applies * * @param tree tree to validate */ private def isValid(tree: tpd.Tree)(using Context): Boolean = - !ctx.definitions.isTupleNType(tree.tpe) && !ctx.definitions.isFunctionNType(tree.tpe) + val isTupleApply = + tree.symbol.name == nme.apply + && tree.symbol.exists + && ctx.definitions.isTupleClass(tree.symbol.owner.companionClass) + + val isFunctionNApply = + tree.symbol.name == nme.apply + && tree.symbol.exists + && ctx.definitions.isFunctionSymbol(tree.symbol.owner) + + !isTupleApply && !isFunctionNApply /** * Get unapply method result type omiting unknown types and another method calls. @@ -397,85 +465,136 @@ object Signatures { * * @return Signature if denot is a function, None otherwise */ - private def toApplySignature(denot: SingleDenotation)(using Context): Option[Signature] = { + private def toApplySignature( + denot: SingleDenotation, + untpdFun: Option[untpd.GenericApply], + paramssIndex: Int + )(using Context): Option[Signature] = { val symbol = denot.symbol val docComment = ParsedComment.docOf(symbol) def isDummyImplicit(res: MethodType): Boolean = res.resultType.isParameterless && res.isImplicitMethod && - res.paramInfos.forall(info => - info.classSymbol.derivesFrom(ctx.definitions.DummyImplicitClass)) - - def toParamss(tp: Type)(using Context): List[List[Param]] = - val rest = tp.resultType match - case res: MethodType => if isDummyImplicit(res) then Nil else toParamss(res) - case _ => Nil - - val currentParams = (tp.paramNamess, tp.paramInfoss) match - case (params :: _, infos :: _) => params zip infos - case _ => Nil - - val params = currentParams.map { (name, info) => - Signatures.Param( - name.show, - info.widenTermRefExpr.show, - docComment.flatMap(_.paramDoc(name)), - isImplicit = tp.isImplicitMethod - ) - } - - (params :: rest) + ( + res.paramNames.forall(name => + name.startsWith(NameKinds.ContextBoundParamName.separator) || + name.startsWith(NameKinds.ContextFunctionParamName.separator)) || + res.paramInfos.forall(info => + info.classSymbol.derivesFrom(ctx.definitions.DummyImplicitClass)) + ) + + def toApplyList(tree: untpd.GenericApply): List[untpd.GenericApply] = + tree match + case untpd.GenericApply(fun: untpd.GenericApply, args) => toApplyList(fun) :+ tree + case _ => List(tree) + + def toMethodTypeList(tpe: Type): List[Type] = + tpe.resultType match + case res: MethodOrPoly => toMethodTypeList(res) :+ tpe + case res => List(tpe) def isSyntheticEvidence(name: String) = if !name.startsWith(NameKinds.ContextBoundParamName.separator) then false else symbol.paramSymss.flatten.find(_.name.show == name).exists(_.flags.is(Flags.Implicit)) - denot.info.stripPoly match - case tpe: (MethodType | AppliedType | TypeRef | TypeParamRef) => - val paramss = toParamss(tpe).map(_.filterNot(param => isSyntheticEvidence(param.name))) - val evidenceParams = (tpe.paramNamess.flatten zip tpe.paramInfoss.flatten).flatMap { - case (name, AppliedType(tpe, (ref: TypeParamRef) :: _)) if isSyntheticEvidence(name.show) => - Some(ref.paramName -> tpe) - case _ => None - } - - val typeParams = denot.info match - case poly: PolyType => - val tparams = poly.paramNames.zip(poly.paramInfos) - tparams.map { (name, info) => - evidenceParams.find((evidenceName: TypeName, _: Type) => name == evidenceName).flatMap { - case (_, tparam) => tparam.show.split('.').lastOption - } match { - case Some(evidenceTypeName) => s"${name.show}: ${evidenceTypeName}" - case None => name.show + info.show - } - } + def toTypeParam(tpe: PolyType): List[Param] = + val evidenceParams = (tpe.paramNamess.flatten zip tpe.paramInfoss.flatten).flatMap: + case (name, AppliedType(tpe, (ref: TypeParamRef) :: _)) if isSyntheticEvidence(name.show) => + Some(ref.paramName -> tpe) + case _ => None + + val tparams = tpe.paramNames.zip(tpe.paramInfos) + tparams.map: (name, info) => + evidenceParams.find((evidenceName: TypeName, _: Type) => name == evidenceName).flatMap: + case (_, tparam) => tparam.show.split('.').lastOption + match + case Some(evidenceTypeName) => TypeParam(s"${name.show}: ${evidenceTypeName}") + case None => TypeParam(name.show + info.show) + + def toParamss(tp: Type, fun: Option[untpd.GenericApply])(using Context): List[List[Param]] = + val paramSymss = symbol.paramSymss + + def reduceToParamss(applies: List[untpd.Tree], types: List[Type], paramList: Int = 0): List[List[Param]] = + applies -> types match + case ((_: untpd.TypeApply) :: restTrees, (poly: PolyType) :: restTypes) => + toTypeParam(poly) :: reduceToParamss(restTrees, restTypes, paramList + 1) + case (restTrees, (poly: PolyType) :: restTypes) => + toTypeParam(poly) :: reduceToParamss(restTrees, restTypes, paramList + 1) + case ((apply: untpd.GenericApply) :: other, tpe :: otherType) => + toParams(tpe, Some(apply), paramList) :: reduceToParamss(other, otherType, paramList + 1) + case (other, (tpe @ MethodTpe(names, _, _)) :: otherType) if !isDummyImplicit(tpe) => + toParams(tpe, None, paramList) :: reduceToParamss(other, otherType, paramList + 1) case _ => Nil - val (name, returnType) = - if (symbol.isConstructor) then - (symbol.owner.name.show, None) - else - (denot.name.show, Some(tpe.finalResultType.widenTermRefExpr.show)) - Some(Signatures.Signature(name, typeParams, paramss, returnType, docComment.map(_.mainDoc), Some(denot))) - case other => None - } - @deprecated("Deprecated in favour of `signatureHelp` which now returns Signature along SingleDenotation", "3.1.3") - def toSignature(denot: SingleDenotation)(using Context): Option[Signature] = { - if denot.name.isUnapplyName then - val resultType = denot.info.stripPoly.finalResultType match - case methodType: MethodType => methodType.resultType.widen - case other => other + def toParams(tp: Type, apply: Option[untpd.GenericApply], paramList: Int)(using Context): List[Param] = + val currentParams = (paramSymss.lift(paramList), tp.paramInfoss.headOption) match + case (Some(params), Some(infos)) => params zip infos + case _ => Nil - // We can't get already applied patterns so we won't be able to get proper signature in case when - // it can be both name-based or single match extractor. See test `nameBasedTest` - val paramTypes = extractParamTypess(resultType, denot, 0).flatten.map(stripAllAnnots) - val paramNames = extractParamNamess(resultType, denot).flatten + val params = currentParams.map: (symbol, info) => + // TODO after we migrate ShortenedTypePrinter into the compiler, it should rely on its api + val name = if symbol.isAllOf(Flags.Given | Flags.Param) && symbol.name.startsWith("x$") then nme.EMPTY else symbol.name.asTermName - toUnapplySignature(denot.asSingleDenotation, paramNames, paramTypes) - else - toApplySignature(denot) + Signatures.MethodParam( + name.show, + info.widenTermRefExpr.show, + docComment.flatMap(_.paramDoc(name)), + isImplicit = tp.isImplicitMethod, + ) + + val finalParams = apply.map: apply => + apply.args match + case Nil => params + case n if n.length > params.length => params + case _ => + // map argument order with their corresponding order so + // def foo(a: Int, b: Int, c: Int, d: Int) + // foo(b = 0, a = 0, d = 0, c = 0) order is List(1, 0, 3, 2) + // and if there are missing arguments, they are set to -1 so for the same method: + // foo(b= 0, d = 0, ) order is List(1, 3, -1, -1) + val argsWithOriginalIndices = apply.args.map: + case untpd.NamedArg(name, _) => + params.indexWhere(_.name == name.toString) + case param => -1 + .padTo(params.length, -1) + + var remainingParams = params.zipWithIndex.filter: (param, index) => + !argsWithOriginalIndices.contains(index) + .map(_._1) + + val result = argsWithOriginalIndices.map: + case -1 => + val h = remainingParams.head + remainingParams = remainingParams.tail + h + case n => params(n) + + val isReordered = params != result + val (ordered, reordered) = params.zip(result).span: (definitionMember, reorderedMember) => + definitionMember == reorderedMember + + ordered.map(_._2) ++ reordered.map(_._2.copy(isReordered = isReordered)) + + + finalParams.getOrElse(params) + end toParams + + val applies = untpdFun.map(toApplyList).getOrElse(Nil) + val types = toMethodTypeList(tp).reverse + + reduceToParamss(applies, types) + + val paramss = toParamss(denot.info, untpdFun) + val (name, returnType) = + if (symbol.isConstructor) then + (symbol.owner.name.show, None) + else + denot.symbol.defTree match + // if there is an error in denotation type, we will fallback to source tree + case defn: tpd.DefDef if denot.info.isErroneous => (denot.name.show, Some(defn.tpt.show)) + case _ => (denot.name.show, Some(denot.info.finalResultType.widenTermRefExpr.show)) + Some(Signatures.Signature(name, paramss, returnType, docComment.map(_.mainDoc), Some(denot))) } /** @@ -493,34 +612,31 @@ object Signatures { */ private def toUnapplySignature(denot: SingleDenotation, paramNames: List[Name], paramTypes: List[Type])(using Context): Option[Signature] = val params = if paramNames.length == paramTypes.length then - (paramNames zip paramTypes).map((name, info) => Param(name.show, info.show)) + (paramNames zip paramTypes).map((name, info) => MethodParam(name.show, info.show)) else - paramTypes.map(info => Param("", info.show)) + // even if we only show types of arguments, they are still method params + paramTypes.map(info => MethodParam("", info.show)) - if params.nonEmpty then - Some(Signature("", Nil, List(params), None, None, Some(denot))) - else - None + if params.nonEmpty then Some(Signature("", List(params), None, None, Some(denot))) + else None /** - * The number of parameters before `tree` application. It is necessary to properly show - * parameter number for erroneous applications before current one. - * - * This handles currying, so for an application such as `foo(1, 2)(3)`, the result of - * `countParams` should be 3. It also takes into considerations unapplied arguments so for `foo(1)(3)` - * we will still get 3, as first application `foo(1)` takes 2 parameters with currently only 1 applied. + * The number of params lists before `tree` application. + * It handles currying, so for an application such as `foo(1, 2)(3)`, the result of + * `findParamssIndex` should be 1. * * @param tree The tree to inspect. - * @param denot Denotation of function we are trying to apply * @param alreadyCurried Number of subsequent Apply trees before current tree * - * @return The number of parameters that are passed. + * @return The index of paramss we are currently in. */ - private def countParams(tree: tpd.Tree, denot: SingleDenotation, alreadyCurried: Int = 0)(using Context): Int = + private def findParamssIndex(tree: tpd.Tree, alreadyCurried: Int = 0)(using Context): Int = tree match - case Apply(fun, params) => - countParams(fun, denot, alreadyCurried + 1) + denot.symbol.paramSymss(alreadyCurried).length - case _ => 0 + case GenericApply(fun, params) + if params.nonEmpty && params.forall(_.isInstanceOf[untpd.SearchFailureIdent]) => + findParamssIndex(fun, alreadyCurried) + case GenericApply(fun, params) => findParamssIndex(fun, alreadyCurried + 1) + case _ => alreadyCurried /** * Inspect `err` to determine, if it is an error related to application of an overloaded @@ -530,35 +646,32 @@ object Signatures { * given the parameters `params`: The alternative that has the most formal parameters * matching the given arguments is chosen. * - * @param err The error message to inspect. - * @param params The parameters that were given at the call site. + * @param err The error message to inspect. + * @param params The parameters that were given at the call site. + * @param alreadyCurried Index of paramss we are currently in. * * @return A pair composed of the index of the best alternative (0 if no alternatives * were found), and the list of alternatives. */ - private def alternativesFromError(err: ErrorType, params: List[tpd.Tree])(using Context): (Int, List[SingleDenotation]) = { + private def alternativesFromError(err: ErrorType, params: List[tpd.Tree], paramssIndex: Int)(using Context): (Int, List[SingleDenotation]) = { val alternatives = err.msg match case msg: AmbiguousOverload => msg.alternatives case msg: NoMatchingOverload => msg.alternatives case _ => Nil - // If the user writes `foo(bar, <cursor>)`, the typer will insert a synthetic - // `null` parameter: `foo(bar, null)`. This may influence what's the "best" - // alternative, so we discard it. - val userParams = params match - case xs :+ (nul @ Literal(Constant(null))) if nul.span.isZeroExtent => xs - case _ => params - val userParamsTypes = userParams.map(_.tpe) + val userParamsTypes = params.map(_.tpe) // Assign a score to each alternative (how many parameters are correct so far), and // use that to determine what is the current active signature. val alternativesScores = alternatives.map { alt => + val alreadyCurriedBonus = if (alt.symbol.paramSymss.length > paramssIndex) 1 else 0 alt.info.stripPoly match - case tpe: MethodType => + case tpe: MethodType => alreadyCurriedBonus + userParamsTypes.zip(tpe.paramInfos).takeWhile{ case (t0, t1) => t0 <:< t1 }.size case _ => 0 } + val bestAlternative = if (alternativesScores.isEmpty) 0 else alternativesScores.zipWithIndex.maxBy(_._1)._2 diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index 750a799a9f0a..2f4e3bd9cb4f 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -19,9 +19,7 @@ import collection.mutable @volatile private var stack: List[String] = Nil - val hits: mutable.HashMap[String, Int] = new mutable.HashMap[String, Int] { - override def default(key: String): Int = 0 - } + val hits: mutable.Map[String, Int] = new mutable.HashMap[String, Int].withDefaultValue(0) inline def record(inline fn: String, inline n: Int = 1, inline skip: Boolean = timerOnly): Unit = if (enabled && !skip) doRecord(fn, n) diff --git a/compiler/src/dotty/tools/io/AbstractFile.scala b/compiler/src/dotty/tools/io/AbstractFile.scala index a7dcb7d396e8..243dc2953d2e 100644 --- a/compiler/src/dotty/tools/io/AbstractFile.scala +++ b/compiler/src/dotty/tools/io/AbstractFile.scala @@ -258,6 +258,9 @@ abstract class AbstractFile extends Iterable[AbstractFile] { final def resolveSibling(name: String): AbstractFile | Null = container.lookupName(name, directory = false) + final def resolveSiblingWithExtension(extension: String): AbstractFile | Null = + resolveSibling(name.stripSuffix(this.extension) + extension) + private def fileOrSubdirectoryNamed(name: String, isDir: Boolean): AbstractFile = lookupName(name, isDir) match { case null => diff --git a/compiler/src/dotty/tools/io/ClassPath.scala b/compiler/src/dotty/tools/io/ClassPath.scala index 8df4015a53c2..5344e2cf7e35 100644 --- a/compiler/src/dotty/tools/io/ClassPath.scala +++ b/compiler/src/dotty/tools/io/ClassPath.scala @@ -26,7 +26,7 @@ trait ClassPath { final def hasPackage(pkg: String): Boolean = hasPackage(PackageName(pkg)) final def packages(inPackage: String): Seq[PackageEntry] = packages(PackageName(inPackage)) - final def classes(inPackage: String): Seq[ClassFileEntry] = classes(PackageName(inPackage)) + final def classes(inPackage: String): Seq[BinaryFileEntry] = classes(PackageName(inPackage)) final def sources(inPackage: String): Seq[SourceFileEntry] = sources(PackageName(inPackage)) final def list(inPackage: String): ClassPathEntries = list(PackageName(inPackage)) @@ -43,7 +43,7 @@ trait ClassPath { private[dotty] def hasPackage(pkg: PackageName): Boolean private[dotty] def packages(inPackage: PackageName): Seq[PackageEntry] - private[dotty] def classes(inPackage: PackageName): Seq[ClassFileEntry] + private[dotty] def classes(inPackage: PackageName): Seq[BinaryFileEntry] private[dotty] def sources(inPackage: PackageName): Seq[SourceFileEntry] /** diff --git a/compiler/src/dotty/tools/io/ZipArchive.scala b/compiler/src/dotty/tools/io/ZipArchive.scala index 3a4d32614c82..9af935690ffc 100644 --- a/compiler/src/dotty/tools/io/ZipArchive.scala +++ b/compiler/src/dotty/tools/io/ZipArchive.scala @@ -160,7 +160,7 @@ final class FileZipArchive(jpath: JPath, release: Option[String]) extends ZipArc override def sizeOption: Option[Int] = Some(zipEntry.getSize.toInt) } - @volatile lazy val (root, allDirs): (DirEntry, collection.Map[String, DirEntry]) = { + lazy val (root, allDirs): (DirEntry, collection.Map[String, DirEntry]) = { val root = new DirEntry("/", null) val dirs = mutable.HashMap[String, DirEntry]("/" -> root) val zipFile = openZipFile() diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 51f133c972b4..04d8d7bc51a0 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1030,7 +1030,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def apply(call: Option[Tree], bindings: List[Definition], expansion: Term): Inlined = withDefaultPos(tpd.Inlined(call.getOrElse(tpd.EmptyTree), bindings.map { case b: tpd.MemberDef => b }, xCheckMacroValidExpr(expansion))) def copy(original: Tree)(call: Option[Tree], bindings: List[Definition], expansion: Term): Inlined = - tpd.Inlined(call.getOrElse(tpd.EmptyTree), bindings.asInstanceOf[List[tpd.MemberDef]], xCheckMacroValidExpr(expansion)).withSpan(original.span).withType(original.tpe) + original match + case original: Inlined => + tpd.cpy.Inlined(original)(call.getOrElse(tpd.EmptyTree), bindings.asInstanceOf[List[tpd.MemberDef]], xCheckMacroValidExpr(expansion)) + case original => + throw new IllegalArgumentException(i"Expected argument `original` to be an `Inlined` but was: ${original.show}") def unapply(x: Inlined): (Option[Tree /* Term | TypeTree */], List[Definition], Term) = (optional(x.call), x.bindings, x.body) end Inlined diff --git a/compiler/test-resources/repl/rewrite-messages b/compiler/test-resources/repl/rewrite-messages index a63a72195019..d7bcbe5d3a90 100644 --- a/compiler/test-resources/repl/rewrite-messages +++ b/compiler/test-resources/repl/rewrite-messages @@ -1,17 +1,20 @@ //> using options -source:future-migration -deprecation -Werror scala> import scala.util._ --- Error: ---------------------------------------------------------------------- +-- Migration Warning: ---------------------------------------------------------- 1 | import scala.util._ | ^ | `_` is no longer supported for a wildcard import; use `*` instead - +No warnings can be incurred under -Werror (or -Xfatal-warnings) +1 warning found +1 error found scala> extension (x: Int) def foo(y: Int) = x + y def foo(x: Int)(y: Int): Int - scala> 2 foo 4 --- Error: ---------------------------------------------------------------------- +-- Migration Warning: ---------------------------------------------------------- 1 | 2 foo 4 | ^^^ |Alphanumeric method foo is not declared infix; it should not be used as infix operator. |Instead, use method syntax .foo(...) or backticked identifier `foo`. -1 error found +No warnings can be incurred under -Werror (or -Xfatal-warnings) +1 warning found +1 error found \ No newline at end of file diff --git a/compiler/test/dotty/Properties.scala b/compiler/test/dotty/Properties.scala index 4bb3628722ad..e085b0de4875 100644 --- a/compiler/test/dotty/Properties.scala +++ b/compiler/test/dotty/Properties.scala @@ -87,6 +87,9 @@ object Properties { /** If we are using the scala-library TASTy jar */ def usingScalaLibraryTasty: Boolean = scalaLibraryTasty.isDefined + /** If we are using the scala-library TASTy jar */ + + def usingScalaLibraryCCTasty: Boolean = scalaLibraryTasty.exists(_.contains("scala2-library-cc-tasty")) /** scala-asm jar */ def scalaAsm: String = sys.props("dotty.tests.classes.scalaAsm") diff --git a/compiler/test/dotty/tools/backend/jvm/ClassfileParserTest.scala b/compiler/test/dotty/tools/backend/jvm/ClassfileParserTest.scala new file mode 100644 index 000000000000..9263103f1712 --- /dev/null +++ b/compiler/test/dotty/tools/backend/jvm/ClassfileParserTest.scala @@ -0,0 +1,57 @@ +package dotty.tools.backend.jvm + +// painful to do Java reflection stuff without this +import scala.language.unsafeNulls + +import org.junit.Assert.assertEquals +import org.junit.Test + +import java.lang.reflect.Member + +class ClassfileParserTest { + @Test + def noConstantPoolLag(): Unit = { + def constNames(ms: List[Member]) = ms.collect { + case f if f.getName.startsWith("CONSTANT_") => f.getName + }.sorted + + val toDotc = Map( + "CONSTANT_INTERFACE_METHODREF" -> "CONSTANT_INTFMETHODREF", + "CONSTANT_INVOKE_DYNAMIC" -> "CONSTANT_INVOKEDYNAMIC", + "CONSTANT_METHOD_HANDLE" -> "CONSTANT_METHODHANDLE", + "CONSTANT_METHOD_TYPE" -> "CONSTANT_METHODTYPE", + "CONSTANT_NAME_AND_TYPE" -> "CONSTANT_NAMEANDTYPE", + ).withDefault(x => x) + + val asmConsts = constNames(Class.forName("scala.tools.asm.Symbol").getDeclaredFields.toList) + .map(_.stripSuffix("_TAG")) + .map(toDotc) + .::("CONSTANT_UNICODE") + .sorted + // in the Scala 2 version of this test, we also use Java reflection to get the constant + // names out of ClassfileConstants. in Dotty, the constants are `inline val`s, invisible + // to Java reflection, so we hardcode them here + assertEquals(asmConsts, List( + // do not add to this list without also making the corresponding change + // in ClassfileConstants! that would defeat the purpose of the test + "CONSTANT_CLASS", + "CONSTANT_DOUBLE", + "CONSTANT_DYNAMIC", + "CONSTANT_FIELDREF", + "CONSTANT_FLOAT", + "CONSTANT_INTEGER", + "CONSTANT_INTFMETHODREF", + "CONSTANT_INVOKEDYNAMIC", + "CONSTANT_LONG", + "CONSTANT_METHODHANDLE", + "CONSTANT_METHODREF", + "CONSTANT_METHODTYPE", + "CONSTANT_MODULE", + "CONSTANT_NAMEANDTYPE", + "CONSTANT_PACKAGE", + "CONSTANT_STRING", + "CONSTANT_UNICODE", + "CONSTANT_UTF8", + )) + } +} diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 120b7373f7cc..64c2bd3b8807 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -45,9 +45,9 @@ class CompilationTests { compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init", "-Ylegacy-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.posLazyValsAllowlist)), compileDir("tests/pos-special/java-param-names", defaultOptions.withJavacOnlyOptions("-parameters")), ) ::: ( - // FIXME: This fails due to a bug involving self types and capture checking - if Properties.usingScalaLibraryTasty then Nil - else List(compileDir("tests/pos-special/stdlib", allowDeepSubtypes)) + // TODO create a folder for capture checking tests with the stdlib, or use tests/pos-custom-args/captures under this mode? + if Properties.usingScalaLibraryCCTasty then List(compileDir("tests/pos-special/stdlib", allowDeepSubtypes)) + else Nil ) if scala.util.Properties.isJavaAtLeast("16") then @@ -215,9 +215,8 @@ class CompilationTests { // initialization tests @Test def checkInitGlobal: Unit = { implicit val testGroup: TestGroup = TestGroup("checkInitGlobal") - val options = defaultOptions.and("-Ysafe-init-global", "-Xfatal-warnings") - compileFilesInDir("tests/init-global/neg", options, FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyBlacklisted)).checkExpectedErrors() - compileFilesInDir("tests/init-global/pos", options, FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyBlacklisted)).checkCompile() + compileFilesInDir("tests/init-global/warn", defaultOptions.and("-Ysafe-init-global"), FileFilter.exclude(TestSources.negInitGlobalScala2LibraryTastyBlacklisted)).checkWarnings() + compileFilesInDir("tests/init-global/pos", defaultOptions.and("-Ysafe-init-global", "-Xfatal-warnings"), FileFilter.exclude(TestSources.posInitGlobalScala2LibraryTastyBlacklisted)).checkCompile() } // initialization tests @@ -225,6 +224,7 @@ class CompilationTests { implicit val testGroup: TestGroup = TestGroup("checkInit") val options = defaultOptions.and("-Ysafe-init", "-Xfatal-warnings") compileFilesInDir("tests/init/neg", options).checkExpectedErrors() + compileFilesInDir("tests/init/warn", defaultOptions.and("-Ysafe-init")).checkWarnings() compileFilesInDir("tests/init/pos", options).checkCompile() compileFilesInDir("tests/init/crash", options.without("-Xfatal-warnings")).checkCompile() // The regression test for i12128 has some atypical classpath requirements. diff --git a/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala b/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala index c13ef0532348..d7b2fd6a5173 100644 --- a/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala +++ b/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala @@ -27,12 +27,12 @@ class SpaceEngineTest: val a = Prod(tp, unappTp, params) val b = Empty - val res1 = isSubspace(a, b) + val res1 = a.isSubspace(b) - val a2 = simplify(a) - val b2 = simplify(b) + val a2 = a.simplify + val b2 = b.simplify val rem1 = minus(a2, b2) - val rem2 = simplify(rem1) + val rem2 = rem1.simplify val res2 = rem2 == Empty assertEquals( @@ -46,19 +46,12 @@ class SpaceEngineTest: |simplify(rem1) == Empty |rem2 == Empty | - |a = ${show(a)} - |b = ${show(b)} - |a2 = ${show(a2)} - |b2 = ${show(b2)} - |rem1 = ${show(rem1)} - |rem2 = ${show(rem2)} - | - |a = ${a.toString} - |b = ${b.toString} - |a2 = ${a2.toString} - |b2 = ${b2.toString} - |rem1 = ${rem1.toString} - |rem2 = ${rem2.toString} + |a = $a + |b = $b + |a2 = $a2 + |b2 = $b2 + |rem1 = $rem1 + |rem2 = $rem2 | |""".stripMargin, res1, res2) } diff --git a/compiler/test/dotty/tools/io/PathTest.scala b/compiler/test/dotty/tools/io/PathTest.scala index 731d29cee8e6..a3755e0ea7dc 100644 --- a/compiler/test/dotty/tools/io/PathTest.scala +++ b/compiler/test/dotty/tools/io/PathTest.scala @@ -3,7 +3,7 @@ package dotty.tools.io import org.junit.Test class PathTest { - // Ref https://github.com/lampepfl/dotty/issues/11644#issuecomment-792457275 + // Ref https://github.com/scala/scala3/issues/11644#issuecomment-792457275 @Test def parent(): Unit = { testParent(Path(""), Directory("..")) testParent(Path("."), Directory("..")) diff --git a/compiler/test/dotty/tools/vulpix/FileDiff.scala b/compiler/test/dotty/tools/vulpix/FileDiff.scala index 5e882be6425a..80fb2bf43534 100644 --- a/compiler/test/dotty/tools/vulpix/FileDiff.scala +++ b/compiler/test/dotty/tools/vulpix/FileDiff.scala @@ -12,10 +12,13 @@ import java.nio.charset.StandardCharsets object FileDiff { + def diffCommand(expectFile: String, actualFile: String): String = + s"git diff --no-index -- $expectFile $actualFile" + def diffMessage(expectFile: String, actualFile: String): String = s"""Test output dumped in: $actualFile - | See diff of the checkfile (`brew install icdiff` for colored diff) - | > diff $expectFile $actualFile + | See diff of the checkfile (`--color=always` for colored diff) + | > ${FileDiff.diffCommand(expectFile, actualFile)} | Replace checkfile with current output | > mv $actualFile $expectFile """.stripMargin diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index e93a0435987b..59d5d3d542fd 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -290,15 +290,25 @@ trait ParallelTesting extends RunnerOrchestration { self => /** This callback is executed once the compilation of this test source finished */ private final def onComplete(testSource: TestSource, reportersOrCrash: Try[Seq[TestReporter]], logger: LoggedRunnable): Unit = - reportersOrCrash match { - case TryFailure(exn) => onFailure(testSource, Nil, logger, Some(s"Fatal compiler crash when compiling: ${testSource.title}:\n${exn.getMessage}${exn.getStackTrace.map("\n\tat " + _).mkString}")) - case TrySuccess(reporters) if !reporters.exists(_.skipped) => - maybeFailureMessage(testSource, reporters) match { - case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty)) - case None => onSuccess(testSource, reporters, logger) + try + reportersOrCrash match + case TryFailure(exn) => onFailure(testSource, Nil, logger, Some(s"Fatal compiler crash when compiling: ${testSource.title}:\n${exn.getMessage}${exn.getStackTrace.map("\n\tat " + _).mkString}")) + case TrySuccess(reporters) if !reporters.exists(_.skipped) => + maybeFailureMessage(testSource, reporters) match { + case Some(msg) => onFailure(testSource, reporters, logger, Option(msg).filter(_.nonEmpty)) + case None => onSuccess(testSource, reporters, logger) + } + case _ => + catch case ex: Throwable => + echo(s"Exception thrown onComplete (probably by a reporter) in $testSource: ${ex.getClass}") + Try(ex.printStackTrace()) + .recover{ _ => + val trace = ex.getStackTrace.map(_.toString) // compute this first in case getStackTrace throws an exception + echo(s"${ex.getClass.getName} message could not be printed due to an exception while computing the message.") + if trace.nonEmpty then trace.foreach(echo) else echo(s"${ex.getClass.getName} stack trace is empty.") } - case _ => - } + .getOrElse(echo(s"${ex.getClass.getName} stack trace could not be printed due to an exception while printing the stack trace.")) + failTestSource(testSource) /** * Based on the reporters obtained after the compilation, determines if this test has failed. @@ -776,7 +786,7 @@ trait ParallelTesting extends RunnerOrchestration { self => end maybeFailureMessage def getWarnMapAndExpectedCount(files: Seq[JFile]): (HashMap[String, Integer], Int) = - val comment = raw"//( *)warn".r + val comment = raw"//( *)(nopos-)?warn".r val map = new HashMap[String, Integer]() var count = 0 def bump(key: String): Unit = @@ -787,8 +797,11 @@ trait ParallelTesting extends RunnerOrchestration { self => files.filter(isSourceFile).foreach { file => Using(Source.fromFile(file, StandardCharsets.UTF_8.name)) { source => source.getLines.zipWithIndex.foreach { case (line, lineNbr) => - comment.findAllMatchIn(line).foreach { _ => - bump(s"${file.getPath}:${lineNbr+1}") + comment.findAllMatchIn(line).foreach { m => + m.group(2) match + case "nopos-" => + bump("nopos") + case _ => bump(s"${file.getPath}:${lineNbr+1}") } } }.get @@ -809,7 +822,7 @@ trait ParallelTesting extends RunnerOrchestration { self => val key = s"${relativize(srcpos.source.file.toString())}:${srcpos.line + 1}" if !seenAt(key) then unexpected += key else - unpositioned += relativize(srcpos.source.file.toString()) + if(!seenAt("nopos")) unpositioned += relativize(srcpos.source.file.toString()) reporterWarnings.foreach(sawDiagnostic) diff --git a/dist/bin/scalac b/dist/bin/scalac index 4b888641e786..d9bd21ca425b 100644 --- a/dist/bin/scalac +++ b/dist/bin/scalac @@ -40,7 +40,7 @@ while [[ $# -gt 0 ]]; do # pass all remaining arguments to scala, e.g. to avoid interpreting them here as -D or -J while [[ $# -gt 0 ]]; do addScala "$1" && shift ; done ;; - # Optimize for short-running applications, see https://github.com/lampepfl/dotty/issues/222 + # Optimize for short-running applications, see https://github.com/scala/scala3/issues/222 -Oshort) addScala "-Oshort" && \ addJava "-XX:+TieredCompilation" && addJava "-XX:TieredStopAtLevel=1" && shift ;; diff --git a/dist/bin/scalac.bat b/dist/bin/scalac.bat index 454158c85666..cb1a76471f70 100644 --- a/dist/bin/scalac.bat +++ b/dist/bin/scalac.bat @@ -55,7 +55,7 @@ if defined _CONSUME_REMAINING ( set _SCALA_ARGS=!_SCALA_ARGS! "%__ARG%" shift ) else if "%__ARG%"=="-Oshort" ( - @rem optimize for short-running applications, see https://github.com/lampepfl/dotty/issues/222 + @rem optimize for short-running applications, see https://github.com/scala/scala3/issues/222 set _JAVA_ARGS=!_JAVA_ARGS! "-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1" set _SCALA_ARGS=!_SCALA_ARGS! -Oshort shift diff --git a/docs/_blog/_posts/2016-02-17-scaling-dot-soundness.md b/docs/_blog/_posts/2016-02-17-scaling-dot-soundness.md index 7619545b844e..bc9c558e3011 100644 --- a/docs/_blog/_posts/2016-02-17-scaling-dot-soundness.md +++ b/docs/_blog/_posts/2016-02-17-scaling-dot-soundness.md @@ -69,9 +69,9 @@ categories: is not associated with a runtime value. We can in fact construct soundness issues in all of these cases. Look -at the discussion for issues [#50](https://github.com/lampepfl/dotty/issues/50) -and [#1050](https://github.com/lampepfl/dotty/issues/1050) in the -[Dotty](https://github.com/lampepfl/dotty/issues/1050) repository +at the discussion for issues [#50](https://github.com/scala/scala3/issues/50) +and [#1050](https://github.com/scala/scala3/issues/1050) in the +[Dotty](https://github.com/scala/scala3/issues/1050) repository on GitHub. All issues work fundamentally in the same way: Construct a type `S` which has a type member `T` with bad bounds, say: @@ -98,7 +98,7 @@ course. The promise is usually broken at run-time by failing with a ## Plugging the Loopholes To get back to soundness we need to plug the loopholes. Some of the -necessary measures are taken in pull request [#1051](https://github.com/lampepfl/dotty/issues/1051). +necessary measures are taken in pull request [#1051](https://github.com/scala/scala3/issues/1051). That pull request - tightens the rules for overrides of lazy values: lazy values diff --git a/docs/_blog/_posts/2016-05-05-multiversal-equality.md b/docs/_blog/_posts/2016-05-05-multiversal-equality.md index 236225eec318..d9a48a9f4424 100644 --- a/docs/_blog/_posts/2016-05-05-multiversal-equality.md +++ b/docs/_blog/_posts/2016-05-05-multiversal-equality.md @@ -6,7 +6,7 @@ authorImg: images/martin.jpg date: 2016-05-05 --- -I have been working recently on making equality tests using `==` and `!=` safer in Scala. This has led to a [Language Enhancement Proposal](https://github.com/lampepfl/dotty/issues/1247) which I summarize in this blog. +I have been working recently on making equality tests using `==` and `!=` safer in Scala. This has led to a [Language Enhancement Proposal](https://github.com/scala/scala3/issues/1247) which I summarize in this blog. ## Why Change Equality? @@ -77,7 +77,7 @@ Given a set of `Eq` instances, the idea is that the Scala compiler will check ev So this means we still keep universal equality as it is in Scala now - we don't have a choice here anyway, because of backwards compatibility. But we render it safe by checking that for each comparison the corresponding `Eq` instance exists. -What about types for which no `Eq` instance exists? To maintain backwards compatibility, we allow comparisons of such types as well, by means of a fall-back `eqAny` instance. But we do not allow comparisons between types that have an `Eq` instance and types that have none. Details are explained in the [proposal](https://github.com/lampepfl/dotty/issues/1247). +What about types for which no `Eq` instance exists? To maintain backwards compatibility, we allow comparisons of such types as well, by means of a fall-back `eqAny` instance. But we do not allow comparisons between types that have an `Eq` instance and types that have none. Details are explained in the [proposal](https://github.com/scala/scala3/issues/1247). ## Properties diff --git a/docs/_blog/_posts/2016-12-05-implicit-function-types.md b/docs/_blog/_posts/2016-12-05-implicit-function-types.md index ba28159c0fa3..0d9eae53d37f 100644 --- a/docs/_blog/_posts/2016-12-05-implicit-function-types.md +++ b/docs/_blog/_posts/2016-12-05-implicit-function-types.md @@ -6,7 +6,7 @@ authorImg: images/martin.jpg date: 2016-12-05 --- -I just made the [first pull request](https://github.com/lampepfl/dotty/pull/1775) to add _implicit function types_ to +I just made the [first pull request](https://github.com/scala/scala3/pull/1775) to add _implicit function types_ to Scala. I am pretty excited about it, because - citing the explanation of the pull request - "_This is the first step to bring contextual abstraction to Scala_". What do I mean by this? @@ -181,7 +181,7 @@ implicit Transaction => Int ``` Just like the normal function type syntax `A => B`, desugars to `scala.Function1[A, B]` the implicit function type syntax `implicit A => B` desugars to `scala.ImplicitFunction1[A, B]`. -The same holds at other function arities. With Dotty's [pull request #1758](https://github.com/lampepfl/dotty/pull/1758) +The same holds at other function arities. With Dotty's [pull request #1758](https://github.com/scala/scala3/pull/1758) merged there is no longer an upper limit of 22 for such functions. The type `ImplicitFunction1` can be thought of being defined as follows: diff --git a/docs/_blog/_posts/2017-05-31-first-dotty-milestone-release.md b/docs/_blog/_posts/2017-05-31-first-dotty-milestone-release.md index 9bfd22b2e3db..3063e658537d 100644 --- a/docs/_blog/_posts/2017-05-31-first-dotty-milestone-release.md +++ b/docs/_blog/_posts/2017-05-31-first-dotty-milestone-release.md @@ -46,7 +46,7 @@ using Dotty with sbt, see the Releases are available for download on the _Releases_ section of the Dotty repository: -https://github.com/lampepfl/dotty/releases +https://github.com/scala/scala3/releases We also provide a [homebrew](https://brew.sh/) package that can be installed by running @@ -92,9 +92,9 @@ See here for the full [version number explanation](https://dotty.epfl.ch/docs/us Over the coming weeks and months, we plan to work on the following topics: - - [Integrate Local optimizations developed in Dotty linker](https://github.com/lampepfl/dotty/pull/2513); - - [Add Language-level support for HMaps and HLists](https://github.com/lampepfl/dotty/pull/2199); - - [Port global optimizations from Dotty linker](https://github.com/lampepfl/dotty/pull/1840). + - [Integrate Local optimizations developed in Dotty linker](https://github.com/scala/scala3/pull/2513); + - [Add Language-level support for HMaps and HLists](https://github.com/scala/scala3/pull/2199); + - [Port global optimizations from Dotty linker](https://github.com/scala/scala3/pull/1840). If you want to get your hands dirty with any of this, now is a good moment to get involved! Join the team of contributors, including diff --git a/docs/_blog/_posts/2017-07-12-second-dotty-milestone-release.md b/docs/_blog/_posts/2017-07-12-second-dotty-milestone-release.md index 9172b5ad67ec..ff314eed13f2 100644 --- a/docs/_blog/_posts/2017-07-12-second-dotty-milestone-release.md +++ b/docs/_blog/_posts/2017-07-12-second-dotty-milestone-release.md @@ -34,52 +34,52 @@ The [previous technology preview](/_blog/_posts/2017-05-31-first-dotty-milestone This technology preview is geared towards improving stability and reliability. It includes: - - [Local optimizations upstreamed from the Dotty Linker](https://github.com/lampepfl/dotty/pull/2513), [2647](https://github.com/lampepfl/dotty/pull/2647) by ([@OlivierBlanvillain](https://github.com/OlivierBlanvillain)). See more details below. - - [Optimizing Pattern Matcher](https://github.com/lampepfl/dotty/pull/2829) by ([@odersky](https://github.com/odersky)) - - [Idempotency checks](https://github.com/lampepfl/dotty/pull/2756) are the first step to reproducible builds - - [Faster Base class sets](https://github.com/lampepfl/dotty/pull/2676) by ([@odersky](https://github.com/odersky)) and ([@darkdimius](https://twitter.com/darkdimius)) + - [Local optimizations upstreamed from the Dotty Linker](https://github.com/scala/scala3/pull/2513), [2647](https://github.com/scala/scala3/pull/2647) by ([@OlivierBlanvillain](https://github.com/OlivierBlanvillain)). See more details below. + - [Optimizing Pattern Matcher](https://github.com/scala/scala3/pull/2829) by ([@odersky](https://github.com/odersky)) + - [Idempotency checks](https://github.com/scala/scala3/pull/2756) are the first step to reproducible builds + - [Faster Base class sets](https://github.com/scala/scala3/pull/2676) by ([@odersky](https://github.com/odersky)) and ([@darkdimius](https://twitter.com/darkdimius)) - Numerous fixes to IDE and Dotty Language Server covering: - - [Windows support for VS Code plugin](https://github.com/lampepfl/dotty/pull/2776) - - [Fix hover-on-type for implicitly converted expressions](https://github.com/lampepfl/dotty/pull/2836) - - [Fixes to find all references in external projects](https://github.com/lampepfl/dotty/pull/2810), [2773](https://github.com/lampepfl/dotty/pull/2773/files) - - [Fix conflict with dragos-vscode-scala](https://github.com/lampepfl/dotty/pull/2777) - - [Fix ide crash on non-parsable file](https://github.com/lampepfl/dotty/pull/2752) - - [Fix hover functionality for enum classes](https://github.com/lampepfl/dotty/pull/2722) - - [Report errors on Dotty Language Server initialization](https://github.com/lampepfl/dotty/pull/2708) - - [Fixes to sbt setting up Dotty IDE](https://github.com/lampepfl/dotty/pull/2690) - - General stability improvements [2838](https://github.com/lampepfl/dotty/pull/2838), [2787](https://github.com/lampepfl/dotty/pull/2787), [2692](https://github.com/lampepfl/dotty/pull/2692) + - [Windows support for VS Code plugin](https://github.com/scala/scala3/pull/2776) + - [Fix hover-on-type for implicitly converted expressions](https://github.com/scala/scala3/pull/2836) + - [Fixes to find all references in external projects](https://github.com/scala/scala3/pull/2810), [2773](https://github.com/scala/scala3/pull/2773/files) + - [Fix conflict with dragos-vscode-scala](https://github.com/scala/scala3/pull/2777) + - [Fix ide crash on non-parsable file](https://github.com/scala/scala3/pull/2752) + - [Fix hover functionality for enum classes](https://github.com/scala/scala3/pull/2722) + - [Report errors on Dotty Language Server initialization](https://github.com/scala/scala3/pull/2708) + - [Fixes to sbt setting up Dotty IDE](https://github.com/scala/scala3/pull/2690) + - General stability improvements [2838](https://github.com/scala/scala3/pull/2838), [2787](https://github.com/scala/scala3/pull/2787), [2692](https://github.com/scala/scala3/pull/2692) - Scalac compatibility improvements: - - [Support Scala 2.12 traits](https://github.com/lampepfl/dotty/pull/2685) - - [Fixes to handling of Scala 2 classfiles](https://github.com/lampepfl/dotty/pull/2834/files) - - [Scalac parser crashes on Dotty.jar](https://github.com/lampepfl/dotty/pull/2719) + - [Support Scala 2.12 traits](https://github.com/scala/scala3/pull/2685) + - [Fixes to handling of Scala 2 classfiles](https://github.com/scala/scala3/pull/2834/files) + - [Scalac parser crashes on Dotty.jar](https://github.com/scala/scala3/pull/2719) - Java compatibility improvements: - - [Fixes to handing of Java generic signatures](https://github.com/lampepfl/dotty/pull/2831) - - [java.lang.System.out is final but that's a lie](https://github.com/lampepfl/dotty/pull/2781) + - [Fixes to handing of Java generic signatures](https://github.com/scala/scala3/pull/2831) + - [java.lang.System.out is final but that's a lie](https://github.com/scala/scala3/pull/2781) - Improved error messages: - - [Nicer error message for "implicit function type needs non-empty parameter list"](https://github.com/lampepfl/dotty/pull/2821) - - [Nicer error message for nonsensical modifier combination](https://github.com/lampepfl/dotty/pull/2807/files), [2747](https://github.com/lampepfl/dotty/pull/2747) - - [Nicer error message for supercall inside @inline method](https://github.com/lampepfl/dotty/pull/2740) - - [Check that case classes don't inherit case classes](https://github.com/lampepfl/dotty/pull/2790) - - [Check that named parameters don't conflict with positional ones](https://github.com/lampepfl/dotty/pull/2785) + - [Nicer error message for "implicit function type needs non-empty parameter list"](https://github.com/scala/scala3/pull/2821) + - [Nicer error message for nonsensical modifier combination](https://github.com/scala/scala3/pull/2807/files), [2747](https://github.com/scala/scala3/pull/2747) + - [Nicer error message for supercall inside @inline method](https://github.com/scala/scala3/pull/2740) + - [Check that case classes don't inherit case classes](https://github.com/scala/scala3/pull/2790) + - [Check that named parameters don't conflict with positional ones](https://github.com/scala/scala3/pull/2785) - Improved command line handling: - - [Support params in a file like @file.txt](https://github.com/lampepfl/dotty/pull/2765) + - [Support params in a file like @file.txt](https://github.com/scala/scala3/pull/2765) - Type system stability: - - [Handle wildcard types in unions and intersections](https://github.com/lampepfl/dotty/pull/2742) + - [Handle wildcard types in unions and intersections](https://github.com/scala/scala3/pull/2742) - Fixes to implicit search: - - [Fix shadowing of higher order implicits](https://github.com/lampepfl/dotty/pull/2739) + - [Fix shadowing of higher order implicits](https://github.com/scala/scala3/pull/2739) ### Better generated code: @@ -313,7 +313,7 @@ using Dotty with sbt, see the Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -338,10 +338,10 @@ You can try it out there without installing anything. Over the coming weeks and months, we plan to work on the following topics: - - [Add support for using Dotty generated classes with Scala 2.12](https://github.com/lampepfl/dotty/pull/2827) - - [Add Language-level support for HMaps and HLists](https://github.com/lampepfl/dotty/pull/2199); + - [Add support for using Dotty generated classes with Scala 2.12](https://github.com/scala/scala3/pull/2827) + - [Add Language-level support for HMaps and HLists](https://github.com/scala/scala3/pull/2199); - Upstream more optimizations from Dotty Linker - - [Add support for existing in the same classpath with Scala 2.12](https://github.com/lampepfl/dotty/pull/2827) + - [Add support for existing in the same classpath with Scala 2.12](https://github.com/scala/scala3/pull/2827) If you want to get your hands dirty with any of this, now is a good moment to get involved! Join the team of contributors, including diff --git a/docs/_blog/_posts/2017-09-07-third-dotty-milestone-release.md b/docs/_blog/_posts/2017-09-07-third-dotty-milestone-release.md index 236591139105..01fec156ecde 100644 --- a/docs/_blog/_posts/2017-09-07-third-dotty-milestone-release.md +++ b/docs/_blog/_posts/2017-09-07-third-dotty-milestone-release.md @@ -33,12 +33,12 @@ stability and reliability: This technology preview further improves stability and reliability. Some highlighted PRs are: - IDE bug fixes: - [#2986](https://github.com/lampepfl/dotty/pull/2986), - [#2932](https://github.com/lampepfl/dotty/pull/2932), - [#2885](https://github.com/lampepfl/dotty/pull/2885), - [#2876](https://github.com/lampepfl/dotty/pull/2876), - [#2870](https://github.com/lampepfl/dotty/pull/2870), - [#2872](https://github.com/lampepfl/dotty/pull/2872) by [@odersky] and [@smarter]. + [#2986](https://github.com/scala/scala3/pull/2986), + [#2932](https://github.com/scala/scala3/pull/2932), + [#2885](https://github.com/scala/scala3/pull/2885), + [#2876](https://github.com/scala/scala3/pull/2876), + [#2870](https://github.com/scala/scala3/pull/2870), + [#2872](https://github.com/scala/scala3/pull/2872) by [@odersky] and [@smarter]. ## How can you try it out? @@ -65,7 +65,7 @@ using Dotty with sbt, see the ### Standalone installation Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -87,16 +87,16 @@ You can try it out there without installing anything. ## What are the next steps? Over the coming weeks and months, we plan to work on the following topics: - - [Add support for using Dotty generated classes with Scala 2.12](https://github.com/lampepfl/dotty/pull/2827) - - [Add Language-level support for HMaps and HLists](https://github.com/lampepfl/dotty/pull/2199); + - [Add support for using Dotty generated classes with Scala 2.12](https://github.com/scala/scala3/pull/2827) + - [Add Language-level support for HMaps and HLists](https://github.com/scala/scala3/pull/2199); - Upstream more optimizations from Dotty Linker - - [Add support for existing in the same classpath with Scala 2.12](https://github.com/lampepfl/dotty/pull/2827) - - [Add native Dotty REPL](https://github.com/lampepfl/dotty/pull/2991) + - [Add support for existing in the same classpath with Scala 2.12](https://github.com/scala/scala3/pull/2827) + - [Add native Dotty REPL](https://github.com/scala/scala3/pull/2991) ## Questions / Reporting Bugs If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible! @@ -122,7 +122,7 @@ According to `git shortlog -sn --no-merges 0.2.0-RC1..0.3.0-RC2` these are: If you want to get your hands dirty with any of this, now is a good moment to get involved! You can have a look at our [Getting Started page](https://dotty.epfl.ch/docs/contributing/getting-started.html), our [Awesome Error Messages](http://scala-lang.org/blog/2016/10/14/dotty-errors.html) or some of -the simple [Dotty issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +the simple [Dotty issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry-points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2017-10-16-fourth-dotty-milestone-release.md b/docs/_blog/_posts/2017-10-16-fourth-dotty-milestone-release.md index 7f98c4835ee6..1edf198380c8 100644 --- a/docs/_blog/_posts/2017-10-16-fourth-dotty-milestone-release.md +++ b/docs/_blog/_posts/2017-10-16-fourth-dotty-milestone-release.md @@ -25,14 +25,14 @@ stability and reliability. ## What’s new in the 0.4.0-RC1 technology preview? -### Rewritten REPL [#2991](https://github.com/lampepfl/dotty/pull/2991) +### Rewritten REPL [#2991](https://github.com/scala/scala3/pull/2991) The original Dotty REPL was a proof of concept hacked together from -[an ancient version of the scalac REPL](https://github.com/lampepfl/dotty/pull/1082#issuecomment-183905504). +[an ancient version of the scalac REPL](https://github.com/scala/scala3/pull/1082#issuecomment-183905504). It worked by creating Scala source files from the user input using string concatenation, this made it easy to adapt it for Dotty since it did not rely on the internals of scalac, but it was also fragile and hard to reason about. -The [new REPL](https://github.com/lampepfl/dotty/pull/2991) instead works by +The [new REPL](https://github.com/scala/scala3/pull/2991) instead works by manipulating ASTs (Abstract Syntax Trees), this is more robust and will make it easier to develop new features: we have already implemented auto-completion support (by reusing the APIs we had created for @@ -42,7 +42,7 @@ Note that the user interface of the REPL has not changed: like in the old REPL we use code adapted from the [Ammonite REPL](http://ammonite.io/#Ammonite-REPL) to provide syntax highlighting, multi-line editing, history, etc. -### Scala 2.12 support [#2827](https://github.com/lampepfl/dotty/pull/2827) +### Scala 2.12 support [#2827](https://github.com/scala/scala3/pull/2827) Since our first release, it has been possible to use Scala 2 libraries in a Dotty project as explained in the [dotty-example-project](https://github.com/smarter/dotty-example-project#getting-your-project-to-compile-with-dotty). @@ -82,7 +82,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala ### Standalone installation Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -99,7 +99,7 @@ brew upgrade dotty ## Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible! @@ -131,7 +131,7 @@ According to `git shortlog -sn --no-merges 0.3.0-RC2..0.4.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! You can have a look at our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), the [Awesome Error Messages](http://scala-lang.org/blog/2016/10/14/dotty-errors.html) project or some of -the simple [Dotty issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +the simple [Dotty issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry-points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2017-12-01-fifth-dotty-milestone-release.md b/docs/_blog/_posts/2017-12-01-fifth-dotty-milestone-release.md index 60d1062b7eac..dfc97e64f496 100644 --- a/docs/_blog/_posts/2017-12-01-fifth-dotty-milestone-release.md +++ b/docs/_blog/_posts/2017-12-01-fifth-dotty-milestone-release.md @@ -25,7 +25,7 @@ support for Scala 2.12 and came with a brand new REPL. ## What’s new in the 0.5.0-RC1 technology preview? -### Reworked implicit search [#3421](https://github.com/lampepfl/dotty/pull/3421) +### Reworked implicit search [#3421](https://github.com/scala/scala3/pull/3421) The treatment of ambiguity errors has changed. If an ambiguity is encountered in some recursive step of an implicit search, the ambiguity is propagated to the caller. Example: Say you have the following definitions: @@ -56,7 +56,7 @@ techniques no longer work. But there is now a new special type `scala.implicits. implements negation directly. For any query type `Q`: `Not[Q]` succeeds if and only if the implicit search for `Q` fails. -### Dependent function types [#3464](https://github.com/lampepfl/dotty/pull/3464) +### Dependent function types [#3464](https://github.com/scala/scala3/pull/3464) A dependent function type describes functions where the result type may depend on the function's parameter values. Example: @@ -108,7 +108,7 @@ are currently two backends using the TASTY frontend: This is the first step toward linking and whole word optimisations, recompiling code to a different backends... -### Generic java signatures [#3234](https://github.com/lampepfl/dotty/pull/3234) +### Generic java signatures [#3234](https://github.com/scala/scala3/pull/3234) Dotty now emits generic signatures for classes and methods. Those signatures are used by compilers, debuggers and to support runtime reflection. For example: @@ -144,7 +144,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala ### Standalone installation Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -161,7 +161,7 @@ brew upgrade dotty ## Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible! @@ -198,7 +198,7 @@ According to `git shortlog -sn --no-merges 0.4.0-RC1..0.5.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! You can have a look at our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), the [Awesome Error Messages](http://scala-lang.org/blog/2016/10/14/dotty-errors.html) project or some of -the simple [Dotty issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +the simple [Dotty issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry-points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2018-03-05-seventh-dotty-milestone-release.md b/docs/_blog/_posts/2018-03-05-seventh-dotty-milestone-release.md index a72e04409ea0..a70d71bc17b8 100644 --- a/docs/_blog/_posts/2018-03-05-seventh-dotty-milestone-release.md +++ b/docs/_blog/_posts/2018-03-05-seventh-dotty-milestone-release.md @@ -19,12 +19,12 @@ You can learn more about Dotty on our [website](http://dotty.epfl.ch). <!--more--> This is our seventh scheduled release according to our [6-week release schedule](https://dotty.epfl.ch/docs/usage/version-numbers.html). -The [previous technology preview](https://github.com/lampepfl/dotty/releases/tag/0.6.0-RC1) focussed +The [previous technology preview](https://github.com/scala/scala3/releases/tag/0.6.0-RC1) focussed on bug fixes and stability work. ## What’s new in the 0.7.0-RC1 technology preview? -### Enum Simplification [#4003](https://github.com/lampepfl/dotty/pull/4003) +### Enum Simplification [#4003](https://github.com/scala/scala3/pull/4003) The previously introduced syntax and rules for enum were arguably too complex. We can considerably simplify them by taking away one capability: that cases can have bodies which can define members. Arguably, if we choose an ADT decomposition of a problem, it's good style to write all methods using @@ -75,7 +75,7 @@ and how to use them to model [Algebraic Data Types](https://dotty.epfl.ch/docs/r visit the respective sections in our documentation. -### Erased terms [#3342](https://github.com/lampepfl/dotty/pull/3342) +### Erased terms [#3342](https://github.com/scala/scala3/pull/3342) The `erased` modifier can be used on parameters, `val` and `def` to enforce that no reference to those terms is ever used. As they are never used, they can safely be removed during compilation. @@ -103,10 +103,10 @@ For more information, visit the [Erased Terms](https://dotty.epfl.ch/docs/refere section of our documentation. **Note**: Erased terms replace _phantom types_: they have similar semantics, but with the added -advantage that any type can be an erased parameter. See [#3410](https://github.com/lampepfl/dotty/pull/3410). +advantage that any type can be an erased parameter. See [#3410](https://github.com/scala/scala3/pull/3410). -### Improved IDE support [#3960](https://github.com/lampepfl/dotty/pull/3960) +### Improved IDE support [#3960](https://github.com/scala/scala3/pull/3960) The Dotty language server now supports context sensitive IDE completions. Completions now include local and imported definitions. Members completions take possible implicit conversions into account. @@ -183,7 +183,7 @@ compile-time. For example, writing `(eval(a), eval(a))` instead of `(eval(a), eval(b))` in the example above should be an error, but it was not caught by Scala 2 or previous versions of Dotty, whereas we now get a type mismatch error as expected. More work remains to be done to fix the remaining [GADT-related -issues](https://github.com/lampepfl/dotty/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+gadt), +issues](https://github.com/scala/scala3/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+gadt), but so far no show-stopper has been found. ## Trying out Dotty @@ -210,7 +210,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala ### Standalone installation Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -227,7 +227,7 @@ brew upgrade dotty ## Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible! @@ -255,7 +255,7 @@ According to `git shortlog -sn --no-merges 0.6.0..0.7.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry-points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2018-04-27-eighth-dotty-milestone-release.md b/docs/_blog/_posts/2018-04-27-eighth-dotty-milestone-release.md index 72c0747e659d..d2194594edcc 100644 --- a/docs/_blog/_posts/2018-04-27-eighth-dotty-milestone-release.md +++ b/docs/_blog/_posts/2018-04-27-eighth-dotty-milestone-release.md @@ -24,12 +24,12 @@ You can learn more about Dotty on our [website](https://dotty.epfl.ch). <!--more--> This is our eighth scheduled release according to our [6-week release schedule](https://dotty.epfl.ch/docs/usage/version-numbers.html). -The [previous technology preview](https://github.com/lampepfl/dotty/releases/tag/0.7.0-RC1) simplified +The [previous technology preview](https://github.com/scala/scala3/releases/tag/0.7.0-RC1) simplified enums, introduced erased terms, improved IDE support and improved pattern matching for GADT. ## What’s new in the 0.8.0-RC1 technology preview? -### sbt 1 support [#3872](https://github.com/lampepfl/dotty/pull/3872) +### sbt 1 support [#3872](https://github.com/scala/scala3/pull/3872) Starting with Dotty 0.8.0, we will only support versions of sbt >= 1.1.4. Migrating to sbt 1 lets us use the new improved incremental compiler for Scala called [Zinc](https://github.com/sbt/zinc), and enables integration with tools such as [Bloop](https://scalacenter.github.io/bloop/). @@ -43,7 +43,7 @@ If you are already using Dotty with sbt 0.13, follow these simple steps to upgra ``` - replace usages of `.withDottyCompat()` by `.withDottyCompat(scalaVersion.value)` -### Unchecked warnings [#4045](https://github.com/lampepfl/dotty/pull/4045) +### Unchecked warnings [#4045](https://github.com/scala/scala3/pull/4045) Dotty now emits `unchecked` warnings like `scalac` whenever a type test is performed but cannot be fully checked at runtime because of type erasure. For example: @@ -64,7 +64,7 @@ def foo[T](x: T) = x match { } ``` -### Kind Polymorphism [#4108](https://github.com/lampepfl/dotty/pull/4108) +### Kind Polymorphism [#4108](https://github.com/scala/scala3/pull/4108) Normally type parameters in Scala are partitioned into kinds. First-level types are types of values. Higher-kinded types are type constructors such as `List` or `Map`. The kind of a type is indicated by the top type of which it is a subtype. Normal types are subtypes of `Any`, covariant single @@ -94,7 +94,7 @@ f[[X] =>> String] (i.e. `-Ykind-polymorphism`). For more information, visit the [Kind Polymorphism](https://dotty.epfl.ch/docs/reference/other-new-features/kind-polymorphism.html) section of our documentation. -### Improved support for SAM type [#4152](https://github.com/lampepfl/dotty/pull/4152) +### Improved support for SAM type [#4152](https://github.com/scala/scala3/pull/4152) This release includes fixes to [SAM types](https://www.scala-lang.org/news/2.12.0/#lambda-syntax-for-sam-types) that greatly improve interoperability with Java 8 lambdas. One can now easily write Scala code that uses Java streams: @@ -139,7 +139,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala ### Standalone installation Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -156,7 +156,7 @@ brew upgrade dotty ## Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible! @@ -187,7 +187,7 @@ According to `git shortlog -sn --no-merges 0.7.0..0.8.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry-points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2018-07-06-ninth-dotty-milestone-release.md b/docs/_blog/_posts/2018-07-06-ninth-dotty-milestone-release.md index 914eca4d73d3..73066551300b 100644 --- a/docs/_blog/_posts/2018-07-06-ninth-dotty-milestone-release.md +++ b/docs/_blog/_posts/2018-07-06-ninth-dotty-milestone-release.md @@ -24,23 +24,23 @@ You can learn more about Dotty on our [website](https://dotty.epfl.ch). <!--more--> This is our ninth scheduled release according to our [6-week release schedule](https://dotty.epfl.ch/docs/usage/version-numbers.html). -The [previous technology preview](https://github.com/lampepfl/dotty/releases/tag/0.8.0-RC1) added +The [previous technology preview](https://github.com/scala/scala3/releases/tag/0.8.0-RC1) added support for sbt 1, introduced improved unchecked warnings and improved SAM type support. ## What’s new in the 0.9.0-RC1 technology preview? -### Improved REPL [#4680](https://github.com/lampepfl/dotty/pull/4680) +### Improved REPL [#4680](https://github.com/scala/scala3/pull/4680) The REPL now uses [JLine 3](https://github.com/jline/jline3) under the hood which improves on many aspects such as, auto-completions and multi-line editing. The REPL now also works on Windows! -### Documentation support in the IDE [#4461](https://github.com/lampepfl/dotty/pull/4461), [#4648](https://github.com/lampepfl/dotty/pull/4648) +### Documentation support in the IDE [#4461](https://github.com/scala/scala3/pull/4461), [#4648](https://github.com/scala/scala3/pull/4648) The Dotty IDE will now display documentation while hovering over symbols that were previously compiled by the Dotty compiler. In the future, we plan to let users query the documentation in the REPL as well. -### Drop requirement that implicit functions must be non-empty [#4549](https://github.com/lampepfl/dotty/pull/4549) +### Drop requirement that implicit functions must be non-empty [#4549](https://github.com/scala/scala3/pull/4549) We remove the arbitrary restriction that parameters of implicit functions must by non-empty. We can now write: ```scala @@ -63,7 +63,7 @@ timed { Both definitions above are equivalent. -### Emit feature warnings for implicit conversions [#4229](https://github.com/lampepfl/dotty/pull/4229) +### Emit feature warnings for implicit conversions [#4229](https://github.com/scala/scala3/pull/4229) Implicit conversions are easily the most misused feature in Scala. We now emit feature warnings when encountering an implicit conversion definition, just like Scala 2 does. @@ -76,7 +76,7 @@ unless the conversion is: (we might extend this to more conversions). -### Optimise s and raw interpolators [#3961](https://github.com/lampepfl/dotty/pull/3961) +### Optimise s and raw interpolators [#3961](https://github.com/scala/scala3/pull/3961) `s` and `raw` string interpolators were known to be slower than their not type-safe counterparts: ```scala s"Hello $name!" @@ -89,7 +89,7 @@ The compiler will now desugar the former into the latter. Special thanks to compiler! -### Support for compiler plugins [#3438](https://github.com/lampepfl/dotty/pull/3438) +### Support for compiler plugins [#3438](https://github.com/scala/scala3/pull/3438) Dotty now supports Compiler plugins. Compiler plugins let you customize the compiler pipeline without having to modify the compiler source code. A major difference compared to Scala 2 is that Dotty plugins must run after the type checker. Being able to influence normal type checking @@ -123,7 +123,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala ### Standalone installation Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) We also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -144,7 +144,7 @@ installing anything. Note however that Scastie only supports Dotty 0.7.0-RC1. ## Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible! @@ -180,7 +180,7 @@ According to `git shortlog -sn --no-merges 0.8.0..0.9.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry-points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2018-10-10-10th-dotty-milestone-release.md b/docs/_blog/_posts/2018-10-10-10th-dotty-milestone-release.md index b583d1bd0f49..0a5ebd067391 100644 --- a/docs/_blog/_posts/2018-10-10-10th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2018-10-10-10th-dotty-milestone-release.md @@ -99,7 +99,7 @@ or the enclosing class did not change at call site. E.g. This restriction has now been removed. We also improve upon `scalac` which is not able to optimise methods that change the type of `this` on a polymorphic recursive call. -[Examples](https://github.com/lampepfl/dotty/blob/7a45a4a386d33180e5b7b21aa74271a77cce4707/tests/neg-tailcall/tailrec.scala#L43-L44) +[Examples](https://github.com/scala/scala3/blob/7a45a4a386d33180e5b7b21aa74271a77cce4707/tests/neg-tailcall/tailrec.scala#L43-L44) can be found in our test suite. ### Experimental support for generic Tuples @@ -125,7 +125,7 @@ val t2: (Int, String, Long, Int, String, Long) = (1,2,3,1,2,3) ### And much more! -Please read our [release notes](https://github.com/lampepfl/dotty/releases/tag/0.10.0-RC1) +Please read our [release notes](https://github.com/scala/scala3/releases/tag/0.10.0-RC1) for more details! ## Breaking changes @@ -160,7 +160,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) For macOS users, we also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -179,7 +179,7 @@ brew upgrade dotty If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -222,7 +222,7 @@ According to `git shortlog -sn --no-merges 0.9.0..0.10.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2018-11-30-11th-dotty-milestone-release.md b/docs/_blog/_posts/2018-11-30-11th-dotty-milestone-release.md index 344900e2e164..268d86db00c6 100644 --- a/docs/_blog/_posts/2018-11-30-11th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2018-11-30-11th-dotty-milestone-release.md @@ -115,7 +115,7 @@ information from the Scaladoc comment, then format it before we display it in th ### And much more! -Please read our [release notes](https://github.com/lampepfl/dotty/releases/tag/0.11.0-RC1) +Please read our [release notes](https://github.com/scala/scala3/releases/tag/0.11.0-RC1) for more details! ## Trying out Dotty @@ -146,7 +146,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) For macOS users, we also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -165,7 +165,7 @@ brew upgrade dotty If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -201,7 +201,7 @@ According to `git shortlog -sn --no-merges 0.10.0..0.11.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-01-21-12th-dotty-milestone-release.md b/docs/_blog/_posts/2019-01-21-12th-dotty-milestone-release.md index f9fc25375d86..d56a03b4e345 100644 --- a/docs/_blog/_posts/2019-01-21-12th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-01-21-12th-dotty-milestone-release.md @@ -106,7 +106,7 @@ This kind of reasoning is necessary for many advanced GADT usages! ### And much more! -Please read our [release notes](https://github.com/lampepfl/dotty/releases/tag/0.12.0-RC1) +Please read our [release notes](https://github.com/scala/scala3/releases/tag/0.12.0-RC1) for more details! ## Trying out Dotty @@ -137,7 +137,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) For macOS users, we also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -156,7 +156,7 @@ brew upgrade dotty If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -195,7 +195,7 @@ According to `git shortlog -sn --no-merges 0.11.0-RC1..0.12.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-03-05-13th-dotty-milestone-release.md b/docs/_blog/_posts/2019-03-05-13th-dotty-milestone-release.md index f1838847d81e..8ebb70ea59e5 100644 --- a/docs/_blog/_posts/2019-03-05-13th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-03-05-13th-dotty-milestone-release.md @@ -50,11 +50,11 @@ smoothly, but the *Parallelism and Concurrency* course given in the Spring semester teaches Spark, which means we needed to support it in Dotty! Luckily, this turned out to be mostly straightforward: we adopted the [object -serialization scheme](https://github.com/lampepfl/dotty/pull/5775) and [lambda -serialization scheme](https://github.com/lampepfl/dotty/pull/5837) pioneered by +serialization scheme](https://github.com/scala/scala3/pull/5775) and [lambda +serialization scheme](https://github.com/scala/scala3/pull/5837) pioneered by Scala 2, and that was enough to make our Spark assignments run correctly! This doesn't mean that our support is perfect however, so don't hesitate to [open an -issue](http://github.com/lampepfl/dotty/issues) if something is amiss. +issue](http://github.com/scala/scala3/issues) if something is amiss. ## Introducing top level definitions @@ -74,7 +74,7 @@ def b = a._2 You can read about [dropping package objects](https://dotty.epfl.ch/docs/reference/dropped-features/package-objects.html) at the documentation linked or at the relevant PR -[#5754](https://github.com/lampepfl/dotty/pull/5754). +[#5754](https://github.com/scala/scala3/pull/5754). ## All things impl... implied @@ -211,7 +211,7 @@ object B { **You can read more about** [implied imports](https://dotty.epfl.ch/docs/reference/contextual/import-delegate.html) from the docs or the relevant PR -[#5868](https://github.com/lampepfl/dotty/pull/5868). +[#5868](https://github.com/scala/scala3/pull/5868). As we mentioned above, *context queries* are functions with (only) inferable parameters. Here is an example of such a function: @@ -227,9 +227,9 @@ merely an alignment of IFTs into the new scheme. **You can read more about** the alternative to implicits through the *Contextual Abstractions* section of our documentation or for a deep dive from the relevant PR chain that originated from -[#5458](https://github.com/lampepfl/dotty/pull/5458). The syntax changes for new +[#5458](https://github.com/scala/scala3/pull/5458). The syntax changes for new implicits are summarized in -[#5825](https://github.com/lampepfl/dotty/pull/5825). +[#5825](https://github.com/scala/scala3/pull/5825). This release offers the support for _type class derivation_ as a language feature. Type class derivation is a way to generate instances of certain type @@ -279,8 +279,8 @@ def derived[T] given Generic[T] = ... **You can read more about** [Type class Derivation](https://dotty.epfl.ch/docs/reference/contextual/derivation.html) or have a deep dive at the relevant PRs: -[#5540](https://github.com/lampepfl/dotty/pull/5540) and -[#5839](https://github.com/lampepfl/dotty/pull/5839). +[#5540](https://github.com/scala/scala3/pull/5540) and +[#5839](https://github.com/scala/scala3/pull/5839). _Multiversal equality_ is now supported through the `Eql` marker trait (renamed from `Eq` to differentiate it from Cats' `Eq`). For example, in order to be able @@ -292,7 +292,7 @@ implied for Eql[Int, String] = Eql.derived ``` **You can read more about** how we based multiversal equality on type class derivation through -the relevant PR [#5843](https://github.com/lampepfl/dotty/pull/5843). +the relevant PR [#5843](https://github.com/scala/scala3/pull/5843). _Implicit conversions_ are now defined by implied instances of the `scala.Conversion` class. For example: @@ -311,7 +311,7 @@ important with the documentation of each feature, please consult the ## Implicit resolution rule changes -PR [#5887](https://github.com/lampepfl/dotty/pull/5887) applies the following +PR [#5887](https://github.com/scala/scala3/pull/5887) applies the following changes to implicit resolution: 1. nested implicits always take precedence over outer ones @@ -324,12 +324,12 @@ changes to implicit resolution: data model for semantic information such as symbols and types about programs in Scala and other languages. SemanticDB decouples production and consumption of semantic information, establishing documented means for communication between -tools. With PR [#5761](https://github.com/lampepfl/dotty/pull/5761) we add the +tools. With PR [#5761](https://github.com/scala/scala3/pull/5761) we add the first prototype for the generation of SemanticDB information from TASTy. ## And much more! -Please read our [release notes](https://github.com/lampepfl/dotty/releases/tag/0.13.0-RC1) +Please read our [release notes](https://github.com/scala/scala3/releases/tag/0.13.0-RC1) for more details! # Trying out Dotty @@ -360,7 +360,7 @@ the IDE sections of the [getting-started page](https://docs.scala-lang.org/scala Releases are available for download on the _Releases_ section of the Dotty repository: -[https://github.com/lampepfl/dotty/releases](https://github.com/lampepfl/dotty/releases) +[https://github.com/scala/scala3/releases](https://github.com/scala/scala3/releases) For macOS users, we also provide a [homebrew](https://brew.sh/) package that can be installed by running: @@ -379,7 +379,7 @@ brew upgrade dotty If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -417,7 +417,7 @@ According to `git shortlog -sn --no-merges 0.12.0-RC1..0.13.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-04-15-14th-dotty-milestone-release.md b/docs/_blog/_posts/2019-04-15-14th-dotty-milestone-release.md index 6724ae11cef1..1ac1c3ae9fbb 100644 --- a/docs/_blog/_posts/2019-04-15-14th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-04-15-14th-dotty-milestone-release.md @@ -72,7 +72,7 @@ For more information, please read more in the [documentation](https://dotty.epfl ## An immutable array type -A new type, `scala.IArray[T]`, is added, which is an immutable version of the `Array` type. Its implementation deserves a special attention, as it uses the new Dotty features in an elegant way (the below is an abstract from the corresponding [commit](https://github.com/lampepfl/dotty/commit/af2a0e66eb4b1204eac5dcb1d979486b92ef93d7#diff-156dc405d9f228bbc0fe406dfba63f65): +A new type, `scala.IArray[T]`, is added, which is an immutable version of the `Array` type. Its implementation deserves a special attention, as it uses the new Dotty features in an elegant way (the below is an abstract from the corresponding [commit](https://github.com/scala/scala3/commit/af2a0e66eb4b1204eac5dcb1d979486b92ef93d7#diff-156dc405d9f228bbc0fe406dfba63f65): ```scala opaque type IArray[T] = Array[T] @@ -131,7 +131,7 @@ Some of the other changes include: If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -171,7 +171,7 @@ According to `git shortlog -sn --no-merges 0.13.0-RC1..0.14.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-05-23-15th-dotty-milestone-release.md b/docs/_blog/_posts/2019-05-23-15th-dotty-milestone-release.md index 68337d78ca8c..1ffb07377da4 100644 --- a/docs/_blog/_posts/2019-05-23-15th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-05-23-15th-dotty-milestone-release.md @@ -6,7 +6,7 @@ authorImg: images/anatolii.png date: 2019-05-23 --- -Hi! We are very excited to announce the 15th release of Dotty. The most exciting thing in this release is the full bootstrap for Dotty introduced by PR [#5923](https://github.com/lampepfl/dotty/pull/5923)🎉😍. This means that we now always compile Dotty with Dotty itself, hence we can use use all the new features in the compiler code base. +Hi! We are very excited to announce the 15th release of Dotty. The most exciting thing in this release is the full bootstrap for Dotty introduced by PR [#5923](https://github.com/scala/scala3/pull/5923)🎉😍. This means that we now always compile Dotty with Dotty itself, hence we can use use all the new features in the compiler code base. With this release comes a bunch of new features and improvements, such as the ability to enforce whether an operator is intended to be used in an infix position, the type safe pattern bindings and more. @@ -36,7 +36,7 @@ This is our 15th scheduled release according to our ## Full Bootstrap Bootstrapping Dotty is a big milestone for us and in compiler construction in general. Firstly, we feel more confident that our compiler works as is (even without reusing the new features). Secondly, in the immediate future, we will be able to reuse many of the features that dotty proposes within dotty itself. For example, we have no fewer than 2641 occurrences of the text string (implicit ctx: Context) in the compiler that we can scrap with [Contextual Function types](https://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html). Big milestones have high risk/high gain and we must be attentive. That is the reason that we will wait a bit until we start using new features. Consequently, at the moment we cross-compile the build with 2.12 on the CI so that we don't accidentally start using Dotty features in case we need to revise the bootstrap process (we'll start using Dotty features eventually, but let's wait until we're confident that this setup works well enough). -Check the following for more information [#5923 (comment)](https://github.com/lampepfl/dotty/pull/5923#issuecomment-485421148) and please let us know if you have any incremental compilation issues or anything else! +Check the following for more information [#5923 (comment)](https://github.com/scala/scala3/pull/5923#issuecomment-485421148) and please let us know if you have any incremental compilation issues or anything else! ## Operator Rules This change addresses the problem of the regulation of whether an operator is supposed to be used in an infix position. The motivation is for the library authors to be able to enforce whether a method or a type is supposed to be used in an infix position by the users. This ability will help to make code bases more consistent in the way the calls to methods are performed. @@ -150,7 +150,7 @@ For the migration purposes, the above change will only take effect in Scala 3.1. For more information, see the [documentation](https://dotty.epfl.ch/docs/reference/changed-features/pattern-bindings.html). ## Further improvements to Generalised Algebraic Data Types (GADTs) support -In this release, we've further improved our support for GADTs. Most notably, we now support variant GADTs, thus fixing [#2985](https://github.com/lampepfl/dotty/issues/2985): +In this release, we've further improved our support for GADTs. Most notably, we now support variant GADTs, thus fixing [#2985](https://github.com/scala/scala3/issues/2985): ```scala enum Expr[+T] { @@ -164,20 +164,20 @@ def eval[T](e: Expr[T]): T = e match { } ``` -We've also plugged a few soundness problems (e.g. [#5667](https://github.com/lampepfl/dotty/issues/5667)) caused by inferring too much when matching on abstract, union and intersection types. For more information, see PR [#5736](https://github.com/lampepfl/dotty/pull/5736). +We've also plugged a few soundness problems (e.g. [#5667](https://github.com/scala/scala3/issues/5667)) caused by inferring too much when matching on abstract, union and intersection types. For more information, see PR [#5736](https://github.com/scala/scala3/pull/5736). ## Other changes Some of the other notable changes include the following: - Singletons are now allowed in union types. E.g. the following is allowed: `object foo; type X = Int | foo.type`. -- A bunch of improvements was made for the type inference system – see, e.g., PRs [#6454](https://github.com/lampepfl/dotty/pull/6454) and [#6467](https://github.com/lampepfl/dotty/pull/6467). -- Improvements to the Scala 2 code support which, in particular, improves Cats support – see PRs [#6494](https://github.com/lampepfl/dotty/pull/6494) and [#6498](https://github.com/lampepfl/dotty/pull/6498). +- A bunch of improvements was made for the type inference system – see, e.g., PRs [#6454](https://github.com/scala/scala3/pull/6454) and [#6467](https://github.com/scala/scala3/pull/6467). +- Improvements to the Scala 2 code support which, in particular, improves Cats support – see PRs [#6494](https://github.com/scala/scala3/pull/6494) and [#6498](https://github.com/scala/scala3/pull/6498). # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -205,7 +205,7 @@ According to `git shortlog -sn --no-merges 0.14.0-RC1..0.15.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-06-11-16th-dotty-milestone-release.md b/docs/_blog/_posts/2019-06-11-16th-dotty-milestone-release.md index 41194df26625..91f63a5610b7 100644 --- a/docs/_blog/_posts/2019-06-11-16th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-06-11-16th-dotty-milestone-release.md @@ -49,7 +49,7 @@ represented by `=>>`. As a result a function from types to types is written as `[X] =>> F[X]`. For those who are interested in the discussions, -[#6558](https://github.com/lampepfl/dotty/pull/6558) introduced the new syntax. +[#6558](https://github.com/scala/scala3/pull/6558) introduced the new syntax. ## Syntax Change: Wildcard Arguments in Types @@ -92,7 +92,7 @@ delegate ListOrd[T] for Ord[List[T]] given (ord: Ord[T]) { ``` For more information, the documentation has been updated as part of the relevant -PR [#6649](https://github.com/lampepfl/dotty/pull/6649) +PR [#6649](https://github.com/scala/scala3/pull/6649) ## Polymorphic function types @@ -127,7 +127,7 @@ With PFTs we can now achieve what we want: ``` For those who are interested in the discussions and more test cases, -[#4672](https://github.com/lampepfl/dotty/pull/4672/) introduced PFTs. +[#4672](https://github.com/scala/scala3/pull/4672/) introduced PFTs. ## `lazy val`s are now thread-safe by default @@ -156,9 +156,9 @@ enum B(val gravity: Double) extends java.lang.Enum[B] { } ``` -For more information please check the [test case](https://github.com/lampepfl/dotty/tree/main/tests/run/enum-java) and -also the relevant PRs [#6602](https://github.com/lampepfl/dotty/pull/6602) and -[#6629](https://github.com/lampepfl/dotty/pull/6629). +For more information please check the [test case](https://github.com/scala/scala3/tree/main/tests/run/enum-java) and +also the relevant PRs [#6602](https://github.com/scala/scala3/pull/6602) and +[#6629](https://github.com/scala/scala3/pull/6629). In the test, the enums are defined in the `MainScala.scala` file and used from a Java source, `Test.java`. @@ -212,13 +212,13 @@ Advantages of new scheme: - Complete decoupling between derives clauses and mirror generation. For the technical details of these changes please consule the corresponding PR -[#6531](https://github.com/lampepfl/dotty/pull/6531). +[#6531](https://github.com/scala/scala3/pull/6531). # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -245,7 +245,7 @@ According to `git shortlog -sn --no-merges 0.15.0-RC1..0.16.0-RC3` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-07-25-17th-dotty-milestone-release.md b/docs/_blog/_posts/2019-07-25-17th-dotty-milestone-release.md index eea99263def9..62e0a550598d 100644 --- a/docs/_blog/_posts/2019-07-25-17th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-07-25-17th-dotty-milestone-release.md @@ -31,7 +31,7 @@ This is our 17th scheduled release according to our # What’s new in the 0.17.0-RC1 technology preview? ## New implicit scoping rules -We aim to make the implicit scoping rules clean and intuitive. In this release, the scoping rules were refactored to facilitate this goal. As specified in the [code documentation](https://github.com/lampepfl/dotty/pull/6832/files#diff-584b631c45ba6f2d4bc5d803074b8f12R474): +We aim to make the implicit scoping rules clean and intuitive. In this release, the scoping rules were refactored to facilitate this goal. As specified in the [code documentation](https://github.com/scala/scala3/pull/6832/files#diff-584b631c45ba6f2d4bc5d803074b8f12R474): The implicit scope of a type `tp` is the smallest set S of object references (i.e. TermRefs with Module symbol) such that: @@ -48,14 +48,14 @@ with Module symbol) such that: - If `tp` is some other type, its implicit scope is the union of the implicit scopes of its parts (parts defined as in the spec). -You can learn more from PR [#6832](https://github.com/lampepfl/dotty/pull/6832). +You can learn more from PR [#6832](https://github.com/scala/scala3/pull/6832). ## Metaprogramming We are making steady progress developing metaprogramming features. The highlights for this release are: -- Tasty Reflection's `Reflection` object moved inside `QuoteContext` object. This means that if previously to do Tasty Reflection you had to implicitly depend on `Reflection`, now you need to depend on `QuoteContext`. To know more, see [#6723](https://github.com/lampepfl/dotty/pull/6723). -- Progress made on quoted patterns – see [#6504](https://github.com/lampepfl/dotty/pull/6504). -- `code` string interpolator allows to obtain the code a user passes to a macro as a String. See [#6661](https://github.com/lampepfl/dotty/pull/6661). To enable this feature, do the following import: `import scala.compiletime._`. +- Tasty Reflection's `Reflection` object moved inside `QuoteContext` object. This means that if previously to do Tasty Reflection you had to implicitly depend on `Reflection`, now you need to depend on `QuoteContext`. To know more, see [#6723](https://github.com/scala/scala3/pull/6723). +- Progress made on quoted patterns – see [#6504](https://github.com/scala/scala3/pull/6504). +- `code` string interpolator allows to obtain the code a user passes to a macro as a String. See [#6661](https://github.com/scala/scala3/pull/6661). To enable this feature, do the following import: `import scala.compiletime._`. ## 2.12 build removed from the CI tests 2.12 build is removed from the test suite. The 2.12 build compiled and tested the Dotty compiler with the Scala 2.12 compiler. This means that, even though Dotty is bootstrapped (i.e. capable of compiling itself), we were not able to use any of the new Dotty features in the Dotty codebase since these features would not compile with Scala 2.12. The decision to abstain from using the new features was made to give us the time to see if something goes wrong with the bootstrap and the ability to revert to Scala 2.12 if it becomes necessary. @@ -74,7 +74,7 @@ There were some organizational and infrastructural changes worth mentioning. If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -113,7 +113,7 @@ According to `git shortlog -sn --no-merges 0.16.0-RC3..0.17.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-08-30-18th-dotty-milestone-release.md b/docs/_blog/_posts/2019-08-30-18th-dotty-milestone-release.md index 420b9103d3b7..8c06b2058230 100644 --- a/docs/_blog/_posts/2019-08-30-18th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-08-30-18th-dotty-milestone-release.md @@ -168,7 +168,7 @@ val iterator = Iterator.from(10, -1) } ``` -For more information, see PR [#6994](https://github.com/lampepfl/dotty/pull/6994). +For more information, see PR [#6994](https://github.com/scala/scala3/pull/6994). ## Brace-less syntax for control expressions This is an effort to clean-up the control expressions. Scala 2 has two ways of writing `if` statements – with and without parentheses. Parentheses can be dropped in Scala 2 `if`s inside `match` or `for` statements. We'd like to have a single style of writing all of the control expressions, and the cleaner the better. @@ -202,7 +202,7 @@ This release, hence, brings the ability to write all of the control expressions Moreover, the compiler can automatically rewrite your sources from the old syntax to the new syntax and vice versa. To rewrite the sources to the new syntax, run the compiler with the `-rewrite -new-syntax` flags, and to rewrite to the old syntax, use `-rewrite -old-syntax`. So far, both syntaxes are supported. -For more information and the precise rules, see PR [#7024](https://github.com/lampepfl/dotty/pull/7024). +For more information and the precise rules, see PR [#7024](https://github.com/scala/scala3/pull/7024). ## Significant indentation syntax Significant indentations syntax is here! A logical continuation of the brace-less syntax for control expressions described above, meant as an exploration into a better way to write Scala, it allows writing Scala programs without braces. For example: @@ -232,7 +232,7 @@ given as scala.util.FromString[Day]: So far, it is a purely experimental effort. This means there is no final decision yet on whether or not it will be included in Scala 3. However, we treat this feature seriously enough to give it an extended period of trial and see if it is viable as the new look and feel for Scala. -For more details and the discussion, see PRs [#7083](https://github.com/lampepfl/dotty/pull/7083) and [#7114](https://github.com/lampepfl/dotty/pull/7114). +For more details and the discussion, see PRs [#7083](https://github.com/scala/scala3/pull/7083) and [#7114](https://github.com/scala/scala3/pull/7114). ## Generic Number Literals It is now possible to seamlessly integrate with different number formats: that is, to write a number and get it automatically converted to your class of choice. E.g.: @@ -256,13 +256,13 @@ For precise rules, semantics and a larger example of `BigFloat`, see [the docume ## Metaprogramming Progress We are making steady progress with the language metaprogramming features. The metaprogramming spotlights of this release are as follows: -- `toExprOfTuple` method which allows converting a `Seq[Expr[Any]]` to `Expr[Tuple]`. The types of the expressions will be preserved in the tuple. See [#7037](https://github.com/lampepfl/dotty/pull/7037) and [#7076](https://github.com/lampepfl/dotty/pull/7076) for the details. -- `toExprOfTuple` method that converts a tuple of expressions to an expression of tuple – see [#7047](https://github.com/lampepfl/dotty/pull/7047). -- `toExprOfSeq` which converts an `Seq[Expr[A]]` to `Expr[Seq[A]]` – see [#6935](https://github.com/lampepfl/dotty/pull/6935). -- More `Liftable` instances – for Tuples of arity greater than 22, `BigInt` and `BigDecimal` – see [#6947](https://github.com/lampepfl/dotty/pull/6947) and [#6944](https://github.com/lampepfl/dotty/pull/6944). -- Leverage implicit lambdas to simplify `Liftable.toExpr` method – see [#6924](https://github.com/lampepfl/dotty/pull/6924) to learn how it is done. -- Runtime staging `run` moved to `scala.quoted.staging` in [#7077](https://github.com/lampepfl/dotty/pull/7077). -- Runtime staging factored out to a separate library in [#7080](https://github.com/lampepfl/dotty/pull/7080). +- `toExprOfTuple` method which allows converting a `Seq[Expr[Any]]` to `Expr[Tuple]`. The types of the expressions will be preserved in the tuple. See [#7037](https://github.com/scala/scala3/pull/7037) and [#7076](https://github.com/scala/scala3/pull/7076) for the details. +- `toExprOfTuple` method that converts a tuple of expressions to an expression of tuple – see [#7047](https://github.com/scala/scala3/pull/7047). +- `toExprOfSeq` which converts an `Seq[Expr[A]]` to `Expr[Seq[A]]` – see [#6935](https://github.com/scala/scala3/pull/6935). +- More `Liftable` instances – for Tuples of arity greater than 22, `BigInt` and `BigDecimal` – see [#6947](https://github.com/scala/scala3/pull/6947) and [#6944](https://github.com/scala/scala3/pull/6944). +- Leverage implicit lambdas to simplify `Liftable.toExpr` method – see [#6924](https://github.com/scala/scala3/pull/6924) to learn how it is done. +- Runtime staging `run` moved to `scala.quoted.staging` in [#7077](https://github.com/scala/scala3/pull/7077). +- Runtime staging factored out to a separate library in [#7080](https://github.com/scala/scala3/pull/7080). ## Type Class Derivation Type class derivation has received a major rework and an [updated documentation](https://dotty.epfl.ch/docs/reference/contextual/derivation.html). We have dropped the usage of the `Shape` type to describe the shape of a type. Instead, all the relevant information is now encoded in the `Mirror` type and its subtypes as tuples. @@ -270,15 +270,15 @@ Type class derivation has received a major rework and an [updated documentation] For more information, see the [documentation](https://dotty.epfl.ch/docs/reference/contextual/derivation.html). ## Other -- This release also features the new version of the SBT Dotty Plugin – 0.3.4. It contains some bug fixes – see [#7120](https://github.com/lampepfl/dotty/pull/7120) for details. -- Scala Days 2019 talks related to Dotty are now [mentioned](https://dotty.epfl.ch/docs/resources/talks.html) at our website – this allows to systematize the knowledge about the next generation of Scala in one place – see [#6984](https://github.com/lampepfl/dotty/pull/6984). -- ScalaJS needs your help! We would like to have robust support for ScalaJS in Dotty, which unfortunately is not the case so far. If you are interested in contributing, please see [the getting started tutorial](https://gist.github.com/sjrd/e0823a5bddbcef43999cdaa032b1220c) and [the discussion](https://github.com/lampepfl/dotty/issues/7113). +- This release also features the new version of the SBT Dotty Plugin – 0.3.4. It contains some bug fixes – see [#7120](https://github.com/scala/scala3/pull/7120) for details. +- Scala Days 2019 talks related to Dotty are now [mentioned](https://dotty.epfl.ch/docs/resources/talks.html) at our website – this allows to systematize the knowledge about the next generation of Scala in one place – see [#6984](https://github.com/scala/scala3/pull/6984). +- ScalaJS needs your help! We would like to have robust support for ScalaJS in Dotty, which unfortunately is not the case so far. If you are interested in contributing, please see [the getting started tutorial](https://gist.github.com/sjrd/e0823a5bddbcef43999cdaa032b1220c) and [the discussion](https://github.com/scala/scala3/issues/7113). # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -310,7 +310,7 @@ According to `git shortlog -sn --no-merges 0.17.0-RC1..0.18.1-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-09-23-19th-dotty-milestone-release.md b/docs/_blog/_posts/2019-09-23-19th-dotty-milestone-release.md index 0de8d87b92bb..55458b5a20c6 100644 --- a/docs/_blog/_posts/2019-09-23-19th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-09-23-19th-dotty-milestone-release.md @@ -160,7 +160,7 @@ For instance, `-project-logo dotty-logo.svg` will make `/images/dotty-logo.svg` [The front page](https://dotty.epfl.ch) has been redesigned too, with a new responsive menu and improved contrast. -Overall, every page has been updated with consistent settings of fonts and colors. A more detailed comparison between the new and the old design can be found [here](https://github.com/lampepfl/dotty/pull/7153). +Overall, every page has been updated with consistent settings of fonts and colors. A more detailed comparison between the new and the old design can be found [here](https://github.com/scala/scala3/pull/7153). ## Metaprogramming Progress We're making steady progress on the Dotty metaprogramming capability. In our previous work, we've implemented a bunch of functions for working with expressions. For example, we have a capability to convert a list of expressions into an expression of list, or a tuple of expressions into an expression of tuple. @@ -179,7 +179,7 @@ Also, `x.toExpr` syntax which lifts `x` into an expression is now deprecated. It If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -206,7 +206,7 @@ According to `git shortlog -sn --no-merges 0.18.1-RC1..0.19.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-11-04-20th-dotty-milestone-release.md b/docs/_blog/_posts/2019-11-04-20th-dotty-milestone-release.md index 78cbe171ca11..e28b2304831c 100644 --- a/docs/_blog/_posts/2019-11-04-20th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-11-04-20th-dotty-milestone-release.md @@ -127,16 +127,16 @@ It is easy to forget to put `then` at the end of the line if nothing else follow ## Metaprogramming Progress We are making a steady progress developing and improving the metaprogramming features of Dotty. Here are metaprogramming highlights of this release: -- Fix #7189: Do not try to load contents if file does not exist [#7476](https://github.com/lampepfl/dotty/pull/7476) -- Add customizable names for definitions in quotes [#7346](https://github.com/lampepfl/dotty/pull/7346) -- Rename scala.quoted.matching.{Bind => Sym} [#7332](https://github.com/lampepfl/dotty/pull/7332) -- Replace AsFunction implicit class with Expr.reduce [#7299](https://github.com/lampepfl/dotty/pull/7299) +- Fix #7189: Do not try to load contents if file does not exist [#7476](https://github.com/scala/scala3/pull/7476) +- Add customizable names for definitions in quotes [#7346](https://github.com/scala/scala3/pull/7346) +- Rename scala.quoted.matching.{Bind => Sym} [#7332](https://github.com/scala/scala3/pull/7332) +- Replace AsFunction implicit class with Expr.reduce [#7299](https://github.com/scala/scala3/pull/7299) # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -173,7 +173,7 @@ According to `git shortlog -sn --no-merges 0.19.0-RC1..0.20.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2019-12-20-21th-dotty-milestone-release.md b/docs/_blog/_posts/2019-12-20-21th-dotty-milestone-release.md index 94d8ee61bec9..794eb875e3fc 100644 --- a/docs/_blog/_posts/2019-12-20-21th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2019-12-20-21th-dotty-milestone-release.md @@ -17,7 +17,7 @@ happy to announce that we are now feature complete! # Feature Complete! This release is a HUGE milestone for us, for Dotty, for Scala 3, for our community. Since that -[initial commit](https://github.com/lampepfl/dotty/commit/90962407e72d88f8f3249ade0f6bd60ff15af5ce) +[initial commit](https://github.com/scala/scala3/commit/90962407e72d88f8f3249ade0f6bd60ff15af5ce) on the 6th December of 2012 when the only feature was the basic structure of a compiler based on the DOT calculus, we have come a long way. @@ -48,7 +48,7 @@ It means that we can now put the Scala 3 compiler under heavy load, getting it ready for industrial strength applications. At the moment we have 23 projects on our community projects and we expect this number to go up! -> https://github.com/lampepfl/dotty/tree/main/community-build/community-projects +> https://github.com/scala/scala3/tree/main/community-build/community-projects This project contains tests to build and test a corpus of open sources Scala 2.x projects against Scala 3. @@ -333,7 +333,7 @@ root for `.semanticdb` files) and `-sourceroot` to calculate a relative path for If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -378,7 +378,7 @@ According to `git shortlog -sn --no-merges 0.20.0-RC1..0.21.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2020-02-05-22nd-dotty-milestone-release.md b/docs/_blog/_posts/2020-02-05-22nd-dotty-milestone-release.md index a901e83130d8..1dc100a9a741 100644 --- a/docs/_blog/_posts/2020-02-05-22nd-dotty-milestone-release.md +++ b/docs/_blog/_posts/2020-02-05-22nd-dotty-milestone-release.md @@ -55,7 +55,7 @@ println(s"Third: ${list.third}") // 3 This syntax is a completely separate one from the `given` syntax and hence is aimed to bring more clarity and disentangle the two different concepts. -For the discussion, see [PR #7917](https://github.com/lampepfl/dotty/pull/7917). For more information on how to use extension methods in general and collective extension methods in particular, see the [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). +For the discussion, see [PR #7917](https://github.com/scala/scala3/pull/7917). For more information on how to use extension methods in general and collective extension methods in particular, see the [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). # Kind projector syntax support [Kind projector](https://github.com/typelevel/kind-projector) is a popular compiler plugin for Scala 2. It is especially useful in the context of purely functional programming and type class derivation – everywhere where you need to work extensively with types. @@ -90,7 +90,7 @@ object tupleFunctor extends Functor[λ[x => (x, x)]] println(squared) // (1,4) ``` -For the discussion, see [PR #7775](https://github.com/lampepfl/dotty/pull/7775). Also see the GitHub [repository](https://github.com/typelevel/kind-projector) of the kind projector Scala 2 plugin for more context. +For the discussion, see [PR #7775](https://github.com/scala/scala3/pull/7775). Also see the GitHub [repository](https://github.com/typelevel/kind-projector) of the kind projector Scala 2 plugin for more context. # Further improvements to the context parameters syntax Scala 3 context parameters are successors of Scala 2 implicits. In Scala 2, they proved useful for a wide range of applications including purely functional programming, dependency injection, type class derivation, type-level programming. Because their apparent value, one of the priorities in Scala 3 for us is to improve the conceptual framework behind them. @@ -127,7 +127,7 @@ As opposed to the previous: f(2)(given 20) ``` -For the time being, the change is experimental and the old syntax is also supported. For the discussion, see [PR #8162](https://github.com/lampepfl/dotty/pull/8162). You can browse the documentation concerning the new syntax [here](https://dotty.epfl.ch/docs/reference/contextual/motivation-new.html). +For the time being, the change is experimental and the old syntax is also supported. For the discussion, see [PR #8162](https://github.com/scala/scala3/pull/8162). You can browse the documentation concerning the new syntax [here](https://dotty.epfl.ch/docs/reference/contextual/motivation-new.html). # Semantics of inline parameters changed Inline parameters is a metaprogramming feature of Dotty which allows to splice the body of the parameter on its call site. Previously, inline parameters to methods were required to be known on compile time. With this release, this constraint has been relaxed. The following: @@ -149,7 +149,7 @@ Notice how the value of the by-name parameter `b` is not inlined but is bound to So, if previously you had a macro `inline def operationOnCode(code: => Unit) = ${ mcrImpl('code) }` which did something on the AST of the passed `code`, with this release you need to change it to `inline def operationOnCode(inline code: Unit) = ${ mcrImpl('code) }`. -This change was introduced by [PR #8060](https://github.com/lampepfl/dotty/pull/8060/). +This change was introduced by [PR #8060](https://github.com/scala/scala3/pull/8060/). Another change in the semantics of the inline parameters involves the fact that the can no longer be passed as constants to macro implementations. Previously, the following was possible: @@ -169,7 +169,7 @@ inline def power(x: Double, inline n: Int) = ${ powerCode('x, 'n) } private def powerCode(x: Expr[Double], n: Expr[Int])(given QuoteContext): Expr[Double] = ??? ``` -You can obtain the constant value of `n` from within the macro implementation by calling `n.getValue` on it which returns an `Option`. This change was introduced by [PR #8061](https://github.com/lampepfl/dotty/pull/8061). +You can obtain the constant value of `n` from within the macro implementation by calling `n.getValue` on it which returns an `Option`. This change was introduced by [PR #8061](https://github.com/scala/scala3/pull/8061). For more information about the inline capability of Dotty, see [documentation](https://dotty.epfl.ch/docs/reference/metaprogramming/inline.html). @@ -194,7 +194,7 @@ The compile-time error above will say: This feature is particularly useful for data science applications. In data science, it is very easy to make a linear algebra mistake, multiply matrices of wrong dimensions and get a runtime error – sometimes after a few hours of running the model. Hence compile-time verification of the models has a great potential for saving time. With such a type-level arithmetic, Scala becomes well-positioned to implement such type-safe data science frameworks. -For the discussion, see [PR #7628](https://github.com/lampepfl/dotty/pull/7628). The documentation is available [here](https://dotty.epfl.ch/docs/reference/metaprogramming/inline.html#the-scalacompiletimeops-package). +For the discussion, see [PR #7628](https://github.com/scala/scala3/pull/7628). The documentation is available [here](https://dotty.epfl.ch/docs/reference/metaprogramming/inline.html#the-scalacompiletimeops-package). # Suggestions on missing context parameters If there's a compile-time error due to a missing context parameter and this error can be fixed with an import, the compiler will attempt to suggest such an import in the error message. Here is an example of how this error looks like: @@ -212,7 +212,7 @@ If there's a compile-time error due to a missing context parameter and this erro One area where these suggestions will make life easier is purely functional programming with type-classes, with libraries like [cats](https://typelevel.org/cats/). Having the fix for a missing type class in the error message itself is a big time-saver. -For the discussion, see [PR #7862](https://github.com/lampepfl/dotty/pull/7862). +For the discussion, see [PR #7862](https://github.com/scala/scala3/pull/7862). # TASTy Inspector library TASTy Consumer was renamed to TASTy Inspector as of this release. It was also published in a library of its own. For more information, see the [documentation](https://dotty.epfl.ch/docs/reference/metaprogramming/tasty-inspect.html) on this library. @@ -221,7 +221,7 @@ TASTy Consumer was renamed to TASTy Inspector as of this release. It was also pu If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -267,7 +267,7 @@ According to `git shortlog -sn --no-merges 0.21.0-RC1..0.22.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2020-03-18-23rd-dotty-milestone-release.md b/docs/_blog/_posts/2020-03-18-23rd-dotty-milestone-release.md index e52db993dd19..7725d7e7d254 100644 --- a/docs/_blog/_posts/2020-03-18-23rd-dotty-milestone-release.md +++ b/docs/_blog/_posts/2020-03-18-23rd-dotty-milestone-release.md @@ -52,7 +52,7 @@ In this release, we have added an aid for the programmer to detect such mistakes 1 error found ``` -You can learn more about the feature from the [documentation](https://dotty.epfl.ch/0.23.0-RC1/docs/reference/other-new-features/safe-initialization.html). For the discussion, see PR [#7789](https://github.com/lampepfl/dotty/pull/7789). +You can learn more about the feature from the [documentation](https://dotty.epfl.ch/0.23.0-RC1/docs/reference/other-new-features/safe-initialization.html). For the discussion, see PR [#7789](https://github.com/scala/scala3/pull/7789). ## Bitwise Int compiletime operations In the previous release, Dotty has [received](https://dotty.epfl.ch/blog/2020/02/05/22nd-dotty-milestone-release.html#primitive-compiletime-operations-on-singleton-types) a support for type-level arithmetic operations on integers. In this release, we are extending this support by adding bitwise operations. For example: @@ -246,7 +246,7 @@ Notice how above, we are calling `app.fun` and `app.args`. `fun` and `args` are If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -294,7 +294,7 @@ According to `git shortlog -sn --no-merges 0.22.0-RC1..0.23.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2020-04-29-24th-dotty-milestone-release.md b/docs/_blog/_posts/2020-04-29-24th-dotty-milestone-release.md index e32df8cacc55..79148254e409 100644 --- a/docs/_blog/_posts/2020-04-29-24th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2020-04-29-24th-dotty-milestone-release.md @@ -76,13 +76,13 @@ Bar 22 Bar 22 ``` -This new change, however, comes with rather intricated rules – if you are interested to learn about them in details, see [documentation](https://dotty.epfl.ch/docs/reference/metaprogramming/inline.html#rules-for-overriding) on inlines and the PR #[8543](https://github.com/lampepfl/dotty/pull/8543/files) which introduced the change. +This new change, however, comes with rather intricated rules – if you are interested to learn about them in details, see [documentation](https://dotty.epfl.ch/docs/reference/metaprogramming/inline.html#rules-for-overriding) on inlines and the PR #[8543](https://github.com/scala/scala3/pull/8543/files) which introduced the change. # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -125,7 +125,7 @@ According to `git shortlog -sn --no-merges 0.23.0-RC1..0.24.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -134,7 +134,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2020-06-22-25th-dotty-milestone-release.md b/docs/_blog/_posts/2020-06-22-25th-dotty-milestone-release.md index dd5def04bfe9..db73513c2413 100644 --- a/docs/_blog/_posts/2020-06-22-25th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2020-06-22-25th-dotty-milestone-release.md @@ -35,13 +35,13 @@ This default budget is configurable via a compiler flag `-Ximport-suggestion-tim This change should speed up the compiler when it comes to programming with givens. -For more information, see PR [#9167](https://github.com/lampepfl/dotty/pull/9167). +For more information, see PR [#9167](https://github.com/scala/scala3/pull/9167). # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible 🎉 @@ -89,7 +89,7 @@ According to `git shortlog -sn --no-merges 0.24.0-RC1..0.25.0-RC2` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -98,7 +98,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2020-07-27-26th-dotty-milestone-release.md b/docs/_blog/_posts/2020-07-27-26th-dotty-milestone-release.md index b0d153dded7e..06bf6fc5dabb 100644 --- a/docs/_blog/_posts/2020-07-27-26th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2020-07-27-26th-dotty-milestone-release.md @@ -35,7 +35,7 @@ extension (ss: Seq[String]): def longestString: String = longestStrings.head ``` -You can read more about the new syntax in the [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). For the discussion, see [PR](https://github.com/lampepfl/dotty/pull/9255). +You can read more about the new syntax in the [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). For the discussion, see [PR](https://github.com/scala/scala3/pull/9255). # Local Selectable Instances Local and anonymous classes that extend `Selectable` get more refined types than other classes. For example: @@ -78,7 +78,7 @@ val result = constValueTuple["foo" *: "bar" *: 10 *: 2.5 *: EmptyTuple] println(result) // (foo,bar,10,2.5) ``` -This feature was introduced by PR [#9209](https://github.com/lampepfl/dotty/pull/9209). +This feature was introduced by PR [#9209](https://github.com/scala/scala3/pull/9209). # Per-run time budget for import suggestions Import suggestions is a feature useful for debugging but potentially taxing for performance. Therefore, we have added the `-Ximport-suggestion-timeout <time-in-ms>` to allow specifying the timeout (in milliseconds) after which the suggestions mechanism should stop the lookup. The timeout budget is per-run (and not per suggestion) which ensures that the performance does not degrade in case of too many suggestions. @@ -87,7 +87,7 @@ Import suggestions is a feature useful for debugging but potentially taxing for If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing @@ -119,7 +119,7 @@ According to `git shortlog -sn --no-merges 0.25.0-RC2..0.26.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -128,7 +128,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2020-08-31-27th-dotty-milestone-release.md b/docs/_blog/_posts/2020-08-31-27th-dotty-milestone-release.md index e42e98a1385b..7d0eebe369e2 100644 --- a/docs/_blog/_posts/2020-08-31-27th-dotty-milestone-release.md +++ b/docs/_blog/_posts/2020-08-31-27th-dotty-milestone-release.md @@ -41,30 +41,30 @@ To the best of our knowledge, cross-compiling libraries should be able to use Sc If you experience a bug with anything except the unsupported features mentioned above, please file a bug report. # Stability -As we're getting closer to the release of Scala 3, we are continuing to focus on the stability and performance of the language. In this release, we have fixed support of objects under JDK9+ (PR [#9181](https://github.com/lampepfl/dotty/pull/9181)). The issue was, due to the changes in JDK9+ compared to JDK8, our initialization scheme for objects did not work under JDK9+. The aforementioned fixed that issue, thereby unblocking JDK9+ support for Dotty. +As we're getting closer to the release of Scala 3, we are continuing to focus on the stability and performance of the language. In this release, we have fixed support of objects under JDK9+ (PR [#9181](https://github.com/scala/scala3/pull/9181)). The issue was, due to the changes in JDK9+ compared to JDK8, our initialization scheme for objects did not work under JDK9+. The aforementioned fixed that issue, thereby unblocking JDK9+ support for Dotty. -We are also continuing to work on stabilising enums. PR [#9532](https://github.com/lampepfl/dotty/pull/9532) corrects the deserialization and serialization of singleton enum values with `ObjectInputStream` and `ObjectOutputStream`. PR [#9549](https://github.com/lampepfl/dotty/pull/9549) enables overriding the `toString` method on enums – previously this was not possible because of the way enums were desugared. +We are also continuing to work on stabilising enums. PR [#9532](https://github.com/scala/scala3/pull/9532) corrects the deserialization and serialization of singleton enum values with `ObjectInputStream` and `ObjectOutputStream`. PR [#9549](https://github.com/scala/scala3/pull/9549) enables overriding the `toString` method on enums – previously this was not possible because of the way enums were desugared. # Performance We are also focusing these days on making the compiler faster and memory-efficient. For the past month, we were looking in the compiler's memory footprint. We were trying to determine what was allocated in unreasonable amounts during compilation and trying to resolve these allocation issues. The following PRs attempt to increase the performance of the compiler: -- Optimize megaphase [#9597](https://github.com/lampepfl/dotty/pull/9597) -- Cache all memberNamed results [#9633](https://github.com/lampepfl/dotty/pull/9633) -- Parallelize position pickling [#9619](https://github.com/lampepfl/dotty/pull/9619) -- Simplify TypeComparer [#9405](https://github.com/lampepfl/dotty/pull/9405) -- Optimize and simplify SourcePosition handling [#9561](https://github.com/lampepfl/dotty/pull/9561) +- Optimize megaphase [#9597](https://github.com/scala/scala3/pull/9597) +- Cache all memberNamed results [#9633](https://github.com/scala/scala3/pull/9633) +- Parallelize position pickling [#9619](https://github.com/scala/scala3/pull/9619) +- Simplify TypeComparer [#9405](https://github.com/scala/scala3/pull/9405) +- Optimize and simplify SourcePosition handling [#9561](https://github.com/scala/scala3/pull/9561) # Metaprogramming We are keeping the work on the metaprogramming API improvements. For this release, the following PRs bring better API to metaprogrammers: -- Avoid leak of internal implementation in tasty.Reflection [#9613](https://github.com/lampepfl/dotty/pull/9613) -- Redefine quoted.Expr.betaReduce [#9469](https://github.com/lampepfl/dotty/pull/9469) +- Avoid leak of internal implementation in tasty.Reflection [#9613](https://github.com/scala/scala3/pull/9613) +- Redefine quoted.Expr.betaReduce [#9469](https://github.com/scala/scala3/pull/9469) # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributing Thank you to all the contributors who made this release possible 🎉 @@ -100,7 +100,7 @@ According to `git shortlog -sn --no-merges 0.26.0-RC1..0.27.0-RC1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -109,7 +109,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2020-11-09-scala3-m1.md b/docs/_blog/_posts/2020-11-09-scala3-m1.md index ffef5618f9ff..228a9f8eb99e 100644 --- a/docs/_blog/_posts/2020-11-09-scala3-m1.md +++ b/docs/_blog/_posts/2020-11-09-scala3-m1.md @@ -19,8 +19,8 @@ Below, you can find a short summary of the changes that took place during betwee Dotty 0.27.0-RC1 had introduced preliminary Scala.js support with the portable subset of Scala and native JavaScript types. Scala 3.0.0-M1 significantly expands on that support: -* support for non-native JS types ([#9774](https://github.com/lampepfl/dotty/pull/9774)), and -* better support for other JS interop features, notably their interactions with Scala 3 features such as top-level declarations and `enum`s (e.g, [#9725](https://github.com/lampepfl/dotty/pull/9725) and [#9955](https://github.com/lampepfl/dotty/pull/9955)). +* support for non-native JS types ([#9774](https://github.com/scala/scala3/pull/9774)), and +* better support for other JS interop features, notably their interactions with Scala 3 features such as top-level declarations and `enum`s (e.g, [#9725](https://github.com/scala/scala3/pull/9725) and [#9955](https://github.com/scala/scala3/pull/9955)). The only remaining feature of Scala.js that is not supported yet is JS exports: `@JSExport` and its siblings `@JSExportAll`, `@JSExportTopLevel` and `@JSExportStatic` are all ignored by Scala 3.0.0-M1. Support for JS exports will come in the next release. @@ -46,7 +46,7 @@ x match { As of Scala 3.1.0, the `@` syntax will be deprecated and the codebases should switch to `as` instead. -This change was implemented by PR [#9837](https://github.com/lampepfl/dotty/pull/9837). +This change was implemented by PR [#9837](https://github.com/scala/scala3/pull/9837). # Pattern-Bound Given Instances The syntax for `given` instances in patterns has also changed. In the `for`-comprehensions, the correct way of using `given`s is as follows: @@ -62,7 +62,7 @@ pair match case (ctx as given Context, y) => ... ``` -For more information, see [documentation](https://dotty.epfl.ch/docs/reference/contextual/givens.html#pattern-bound-given-instances), and for discussion, see PR [#10091](https://github.com/lampepfl/dotty/pull/10091). +For more information, see [documentation](https://dotty.epfl.ch/docs/reference/contextual/givens.html#pattern-bound-given-instances), and for discussion, see PR [#10091](https://github.com/scala/scala3/pull/10091). # Change wildcard given selectors This is another syntactic change which aims to simplify the code. Instead of: @@ -77,7 +77,7 @@ The correct version of the wildcard `given` import now becomes: import p.given ``` -This change was implemented by PR [#9949](https://github.com/lampepfl/dotty/pull/9949). +This change was implemented by PR [#9949](https://github.com/scala/scala3/pull/9949). # Final API for enumerations `enum` definitions are now released in their final design. since `0.27.0-RC1` we have made the following changes: @@ -125,22 +125,22 @@ val res1: Opt[?] = Nn # Keep `@alpha` optional for operators Following the discussion on [contributors](https://contributors.scala-lang.org/t/the-alpha-notation/4583), we now keep `@alpha` optional for operators. The checking behavior is still available when compiling with the `-Yrequire-alpha`. -`@alpha` annotations provide a way to define an alternate name for symbolic operators. You can learn more about `@alpha` annotations from the [documentation](https://dotty.epfl.ch/docs/reference/changed-features/operators.html#the-alpha-annotation). The change was implemented by PR [#10093](https://github.com/lampepfl/dotty/pull/10093). +`@alpha` annotations provide a way to define an alternate name for symbolic operators. You can learn more about `@alpha` annotations from the [documentation](https://dotty.epfl.ch/docs/reference/changed-features/operators.html#the-alpha-annotation). The change was implemented by PR [#10093](https://github.com/scala/scala3/pull/10093). # Optimizing the compiler During the last months, a considerable amount of effort went into investigating performance bottlenecks in the compiler and optimizing its workflow. We also work on stabilizing the compiler and porting relevant changes from the Scala 2 compiler to Scala 3. The following PRs are relevant to highlighting this work: -- Port classfile parsing improvements [#10037](https://github.com/lampepfl/dotty/pull/10037) -- Semanticdb usability enhancements [#9768](https://github.com/lampepfl/dotty/pull/9768) -- Optimize core and frontend [#9867](https://github.com/lampepfl/dotty/pull/9867) +- Port classfile parsing improvements [#10037](https://github.com/scala/scala3/pull/10037) +- Semanticdb usability enhancements [#9768](https://github.com/scala/scala3/pull/9768) +- Optimize core and frontend [#9867](https://github.com/scala/scala3/pull/9867) # Known issues -This release of Scala 3 doesn't work on JDK 14 because of a regression fixed in [#10135](https://github.com/lampepfl/dotty/pull/10135). JDK 15 doesn't work either because of [scala/bug#12172](https://github.com/scala/bug/issues/12172) which will be fixed in the new scala-library release. +This release of Scala 3 doesn't work on JDK 14 because of a regression fixed in [#10135](https://github.com/scala/scala3/pull/10135). JDK 15 doesn't work either because of [scala/bug#12172](https://github.com/scala/bug/issues/12172) which will be fixed in the new scala-library release. # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributors @@ -190,7 +190,7 @@ According to `git shortlog -sn --no-merges 0.27.0-RC1..3.0.0-M1` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -199,7 +199,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2020-12-18-scala3-m3.md b/docs/_blog/_posts/2020-12-18-scala3-m3.md index 41cfa76c0265..84fa9e823bda 100644 --- a/docs/_blog/_posts/2020-12-18-scala3-m3.md +++ b/docs/_blog/_posts/2020-12-18-scala3-m3.md @@ -19,7 +19,7 @@ You can try out the M3 version online via [Scastie](https://scastie.scala-lang.o <!--more--> # sbt plugin update -We published a new version of the sbt plugin `sbt-dotty`, v0.5.1. Because of the changes in PR [#10607](https://github.com/lampepfl/dotty/pull/10607), this release of Scala 3 will not work with earlier versions of sbt-dotty. You will need to upgrade sbt-dotty to 0.5.1 to be able to use Scala 3.0.0-M3. +We published a new version of the sbt plugin `sbt-dotty`, v0.5.1. Because of the changes in PR [#10607](https://github.com/scala/scala3/pull/10607), this release of Scala 3 will not work with earlier versions of sbt-dotty. You will need to upgrade sbt-dotty to 0.5.1 to be able to use Scala 3.0.0-M3. # Final syntactic tweaks ## `as` dropped from the `given` syntax @@ -57,7 +57,7 @@ given global: ExecutionContext = ForkJoinContext() given Context = ctx ``` -You can find a discussion of the above change in the [PR #10538](https://github.com/lampepfl/dotty/pull/10538). +You can find a discussion of the above change in the [PR #10538](https://github.com/scala/scala3/pull/10538). ## Drop `as` in patterns Since we dropped `as` from `given`s, we lost a strong reason for having `as` at all. Therefore, we dropped `as` from patterns as well. The following syntax, valid in Scala 3.0.0-M2, is not accepted anymore: @@ -128,16 +128,16 @@ In the meantime, the compiler will emit warnings when trying to call those metho Note that the warnings are only active with language mode `3.1-migration` or higher - see the documentation on the [Language Versions](https://dotty.epfl.ch/docs/usage/language-versions.html) to learn how to enable it. -You can read the discussion of this change in the [PR #10670](https://github.com/lampepfl/dotty/pull/10670). You can also read more about it in the [documentation](https://dotty.epfl.ch/docs/reference/other-new-features/matchable.html). +You can read the discussion of this change in the [PR #10670](https://github.com/scala/scala3/pull/10670). You can also read more about it in the [documentation](https://dotty.epfl.ch/docs/reference/other-new-features/matchable.html). # Tooling improvements As we are getting closer to a stable release of Scala 3, the focus increasingly shifts on the tooling available to get started with Scala 3. For a while now, we are not using the old dottydoc documentation tool for building the documentation. We are developing an entirely new tool, scala3doc, from scratch. This new documentation tool is more robust and faster than the old one. -As part of the tooling effort, this new Scala 3 documentation tool is rapidly improved. [PR #10522](https://github.com/lampepfl/dotty/pull/10522) proves that the doctool can generate documentation for the community build projects. You can access this documentation via the following [link](https://scala3doc.virtuslab.com/pr-master-docs/index.html). +As part of the tooling effort, this new Scala 3 documentation tool is rapidly improved. [PR #10522](https://github.com/scala/scala3/pull/10522) proves that the doctool can generate documentation for the community build projects. You can access this documentation via the following [link](https://scala3doc.virtuslab.com/pr-master-docs/index.html). -[PR #10491](https://github.com/lampepfl/dotty/pull/10491) introduced scripting support in Scala 3. Consider the following source named `Main.scala`: +[PR #10491](https://github.com/scala/scala3/pull/10491) introduced scripting support in Scala 3. Consider the following source named `Main.scala`: ```scala @main def Test(name: String): Unit = @@ -157,25 +157,25 @@ The documentation for this feature is available [here](https://dotty.epfl.ch/doc # Metaprogramming changes We have been polishing the metaprogramming API and making it more uniform. The following notable changes occurred between M2 and M3: -- Add `Expr.asTerm` [#10694](https://github.com/lampepfl/dotty/pull/10694) -- Add reflect `MatchCase` `TypeRepr` [#10735](https://github.com/lampepfl/dotty/pull/10735) -- Rework reflect Symbol fields API [#10705](https://github.com/lampepfl/dotty/pull/10705) -- Remove `Expr.StringContext.unapply` [#10675](https://github.com/lampepfl/dotty/pull/10675) -- Rename `Liftable` to `ToExpr` and `Unliftable` to `FromExpr` [#10618](https://github.com/lampepfl/dotty/pull/10618) -- Remove Unliftable[Unit] [#10570](https://github.com/lampepfl/dotty/pull/10570) -- Remove reflect.LambdaType [#10548](https://github.com/lampepfl/dotty/pull/10548) -- Add `scala.quoted.Expr.unapply` as dual of `Expr.apply` [#10580](https://github.com/lampepfl/dotty/pull/10580) -- Move `Quotes` as last parameter in `ExprMap.transform` [#10519](https://github.com/lampepfl/dotty/pull/10519) -- Rework reflect Constant API [#10753](https://github.com/lampepfl/dotty/pull/10753) -- Unify quoted.report and reflect.Reporting [#10474](https://github.com/lampepfl/dotty/pull/10474) -- Fix #10359: Add GivenSelector to reflection API [#10469](https://github.com/lampepfl/dotty/pull/10469) -- Rework reflect show API [#10661](https://github.com/lampepfl/dotty/pull/10661) -- Fix #10709: Add missing level check before inlining [#10781](https://github.com/lampepfl/dotty/pull/10781) +- Add `Expr.asTerm` [#10694](https://github.com/scala/scala3/pull/10694) +- Add reflect `MatchCase` `TypeRepr` [#10735](https://github.com/scala/scala3/pull/10735) +- Rework reflect Symbol fields API [#10705](https://github.com/scala/scala3/pull/10705) +- Remove `Expr.StringContext.unapply` [#10675](https://github.com/scala/scala3/pull/10675) +- Rename `Liftable` to `ToExpr` and `Unliftable` to `FromExpr` [#10618](https://github.com/scala/scala3/pull/10618) +- Remove Unliftable[Unit] [#10570](https://github.com/scala/scala3/pull/10570) +- Remove reflect.LambdaType [#10548](https://github.com/scala/scala3/pull/10548) +- Add `scala.quoted.Expr.unapply` as dual of `Expr.apply` [#10580](https://github.com/scala/scala3/pull/10580) +- Move `Quotes` as last parameter in `ExprMap.transform` [#10519](https://github.com/scala/scala3/pull/10519) +- Rework reflect Constant API [#10753](https://github.com/scala/scala3/pull/10753) +- Unify quoted.report and reflect.Reporting [#10474](https://github.com/scala/scala3/pull/10474) +- Fix #10359: Add GivenSelector to reflection API [#10469](https://github.com/scala/scala3/pull/10469) +- Rework reflect show API [#10661](https://github.com/scala/scala3/pull/10661) +- Fix #10709: Add missing level check before inlining [#10781](https://github.com/scala/scala3/pull/10781) # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributors @@ -231,7 +231,7 @@ We are looking forward to having you join the team of contributors. ## Library authors: Join our community build -Scala 3 is regularly tested against a sample of libraries known as the "community build". You can add your library to the [community build](https://github.com/lampepfl/dotty/tree/main/community-build) by submitting a PR. +Scala 3 is regularly tested against a sample of libraries known as the "community build". You can add your library to the [community build](https://github.com/scala/scala3/tree/main/community-build) by submitting a PR. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2021-02-17-scala3-rc1.md b/docs/_blog/_posts/2021-02-17-scala3-rc1.md index 9751f7b7461e..011dc0819107 100644 --- a/docs/_blog/_posts/2021-02-17-scala3-rc1.md +++ b/docs/_blog/_posts/2021-02-17-scala3-rc1.md @@ -11,7 +11,7 @@ Greetings from the Scala 3 team! We are delighted to announce the first release This release brings some last-minute polishings, clean-ups and changes before the big release. There were a few language changes to improve the user experience, as well as the polishings of the metaprogramming framework. We have also worked on the issues that had to be fixed before the stable release. -Overall, more than [400 PRs](https://github.com/lampepfl/dotty/pulls?q=is%3Apr+is%3Aclosed+closed%3A%3E2020-12-02+sort%3Acomments-desc) were merged after the M3 release and until today! Read more below! +Overall, more than [400 PRs](https://github.com/scala/scala3/pulls?q=is%3Apr+is%3Aclosed+closed%3A%3E2020-12-02+sort%3Acomments-desc) were merged after the M3 release and until today! Read more below! <!--more--> ## Allow secondary type parameter list in extension methods @@ -43,7 +43,7 @@ Or, when passing both type arguments: sumBy[String](List("a", "bb", "ccc"))[Int](_.length) ``` -For discussion, see [PR #10940](https://github.com/lampepfl/dotty/pull/10940). For more information about the extension methods, see [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). +For discussion, see [PR #10940](https://github.com/scala/scala3/pull/10940). For more information about the extension methods, see [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). ## New `import` syntax @@ -62,11 +62,11 @@ import scala.collection.mutable as mut import NumPy as np ``` -For the details and discussion, see [PR #11244](https://github.com/lampepfl/dotty/pull/11244). Read more about this change in the [documentation](https://dotty.epfl.ch/docs/reference/changed-features/imports.html). +For the details and discussion, see [PR #11244](https://github.com/scala/scala3/pull/11244). Read more about this change in the [documentation](https://dotty.epfl.ch/docs/reference/changed-features/imports.html). ## Use `*` for vararg splices -[PR #11240](https://github.com/lampepfl/dotty/pull/11240) changed the syntax of vararg splices in patterns and function arguments. The new syntax uses a postfix `*`, instead of `: _*`, analogously to how a vararg parameter is declared. +[PR #11240](https://github.com/scala/scala3/pull/11240) changed the syntax of vararg splices in patterns and function arguments. The new syntax uses a postfix `*`, instead of `: _*`, analogously to how a vararg parameter is declared. ## Use `uninitialized` for wildcard initializers @@ -88,7 +88,7 @@ var x: A = uninitialized This way expresses the intent of the idiom in a more verbose and easy to read way than simply writing an underscore. -For discussion, see [PR #11231](https://github.com/lampepfl/dotty/pull/11231), and the [documentation](https://dotty.epfl.ch/docs/reference/dropped-features/wildcard-init.html) is available on our website. +For discussion, see [PR #11231](https://github.com/scala/scala3/pull/11231), and the [documentation](https://dotty.epfl.ch/docs/reference/dropped-features/wildcard-init.html) is available on our website. ## Eta-expand companion object if functions are expected @@ -109,49 +109,49 @@ Results in: |The method `apply` is inserted. The auto insertion will be deprecated, please write `Foo.apply` explicitly. ``` -As the warning suggests, now you should write `Foo.apply` instead of `Foo`. See [Issue #6190](https://github.com/lampepfl/dotty/issues/6190) and [PR #7207](https://github.com/lampepfl/dotty/pull/7207) for discussion. +As the warning suggests, now you should write `Foo.apply` instead of `Foo`. See [Issue #6190](https://github.com/scala/scala3/issues/6190) and [PR #7207](https://github.com/scala/scala3/pull/7207) for discussion. ## Settling on `scaladoc` as the documentation tool We have settled on using the well-known `scaladoc` as a name for the documentation tool for Scala 3 (known previously as `scala3doc`). The obsolete `dotty-doc` (or `scala3-doc`) is removed in RC1. We have also removed all the Kotlin dependencies (Dokka, etc.) from scaladoc. -For details, see [PR #11349](https://github.com/lampepfl/dotty/pull/11349). To read more about `scaladoc`, see [documentation](https://dotty.epfl.ch/docs/usage/scaladoc/index.html) +For details, see [PR #11349](https://github.com/scala/scala3/pull/11349). To read more about `scaladoc`, see [documentation](https://dotty.epfl.ch/docs/usage/scaladoc/index.html) ## Use `future` and `future-migration` to specify language versions after 3.0 in `-source` -[PR #11355](https://github.com/lampepfl/dotty/pull/11355) changes the `-source` specifier for the Scala version(s) after 3.0 from `3.1` to `future`. I.e. it is now +[PR #11355](https://github.com/scala/scala3/pull/11355) changes the `-source` specifier for the Scala version(s) after 3.0 from `3.1` to `future`. I.e. it is now `-source future` and `-source future-migration` instead of `-source 3.1` and `-source 3.1-migration`. Language imports are changed analogously. The reason for the change is that we want to keep the possibility open to ship a `3.1` version that does not yet contain all the changes enabled under `-source future`. ## Other language changes -- Warn when matching against an opaque type [#10664](https://github.com/lampepfl/dotty/pull/10664) -- Fix [#8634](https://github.com/lampepfl/dotty/issues/8634): Support -release option [#10746](https://github.com/lampepfl/dotty/pull/10746) – the same way Scala 2 does. +- Warn when matching against an opaque type [#10664](https://github.com/scala/scala3/pull/10664) +- Fix [#8634](https://github.com/scala/scala3/issues/8634): Support -release option [#10746](https://github.com/scala/scala3/pull/10746) – the same way Scala 2 does. This setting allows you to specify a version of the Java platform (8, 9 etc) and compile the code with classes specific to the that Java platform, and emit the bytecode for that version. ## Metaprogramming changes A lot of work has been done on the metaprogramming side of things. Mostly we are cleaning up and polishing the API to prepare it for the stable release. The following are the important metaprogramming changes that took place: -- Add `scala.quoted.Expr.unapply` as dual of `Expr.apply` [#10580](https://github.com/lampepfl/dotty/pull/10580) -- Remove `Expr.StringContext.unapply` [#10675](https://github.com/lampepfl/dotty/pull/10675) -- Add reflect `MatchCase` `TypeRepr` [#10735](https://github.com/lampepfl/dotty/pull/10735) -- Rename `scala.quoted.staging.{Toolbox => Compiler}` [#11129](https://github.com/lampepfl/dotty/pull/11129) -- Fix [#10863](https://github.com/lampepfl/dotty/issues/10863): Make show `AnyKind`ed [#10988](https://github.com/lampepfl/dotty/pull/10988) -- Add ParamClause to allow multiple type param clauses [#11074](https://github.com/lampepfl/dotty/pull/11074) -- Rework reflect Symbol fields API [#10705](https://github.com/lampepfl/dotty/pull/10705) -- Rename `Liftable` to `ToExpr` and `Unliftable` to `FromExpr` [#10618](https://github.com/lampepfl/dotty/pull/10618) -- Expand non-transparent macros after Typer [#9984](https://github.com/lampepfl/dotty/pull/9984) -- Rework TastyInspector API to allow inspection of all files [#10792](https://github.com/lampepfl/dotty/pull/10792) -- Allow leading context parameters in extension methods [#10940](https://github.com/lampepfl/dotty/pull/10940) -- Rename `Not` to `NotGiven` to make its purpose clearer [#10720](https://github.com/lampepfl/dotty/pull/10720) -- Fix [#10709](https://github.com/lampepfl/dotty/issues/10709): Add missing level check before inlining [#10781](https://github.com/lampepfl/dotty/pull/10781) +- Add `scala.quoted.Expr.unapply` as dual of `Expr.apply` [#10580](https://github.com/scala/scala3/pull/10580) +- Remove `Expr.StringContext.unapply` [#10675](https://github.com/scala/scala3/pull/10675) +- Add reflect `MatchCase` `TypeRepr` [#10735](https://github.com/scala/scala3/pull/10735) +- Rename `scala.quoted.staging.{Toolbox => Compiler}` [#11129](https://github.com/scala/scala3/pull/11129) +- Fix [#10863](https://github.com/scala/scala3/issues/10863): Make show `AnyKind`ed [#10988](https://github.com/scala/scala3/pull/10988) +- Add ParamClause to allow multiple type param clauses [#11074](https://github.com/scala/scala3/pull/11074) +- Rework reflect Symbol fields API [#10705](https://github.com/scala/scala3/pull/10705) +- Rename `Liftable` to `ToExpr` and `Unliftable` to `FromExpr` [#10618](https://github.com/scala/scala3/pull/10618) +- Expand non-transparent macros after Typer [#9984](https://github.com/scala/scala3/pull/9984) +- Rework TastyInspector API to allow inspection of all files [#10792](https://github.com/scala/scala3/pull/10792) +- Allow leading context parameters in extension methods [#10940](https://github.com/scala/scala3/pull/10940) +- Rename `Not` to `NotGiven` to make its purpose clearer [#10720](https://github.com/scala/scala3/pull/10720) +- Fix [#10709](https://github.com/scala/scala3/issues/10709): Add missing level check before inlining [#10781](https://github.com/scala/scala3/pull/10781) ## Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributors @@ -225,7 +225,7 @@ According to `git shortlog -sn --no-merges 3.0.0-M3..3.0.0-RC1` these are: If you want to get your hands dirty and contribute to Scala 3, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. diff --git a/docs/_blog/_posts/2021-03-31-scala3-rc2.md b/docs/_blog/_posts/2021-03-31-scala3-rc2.md index 178dfabfbffc..13170adbcfad 100644 --- a/docs/_blog/_posts/2021-03-31-scala3-rc2.md +++ b/docs/_blog/_posts/2021-03-31-scala3-rc2.md @@ -6,7 +6,7 @@ authorImg: /images/anatolii.png date: 2021-03-31 --- -Hello! We are happy to announce Scala 3.0.0-RC2. With this release, we are getting ready for 3.0.0. The significance of it is to give the community the chance and time to test all the changes meant for 3.0.0 final. A lot of bug fixes found their way into this release to ensure stability for 3.0.0 – more than [250 PRs](https://github.com/lampepfl/dotty/pulls?q=is%3Apr+is%3Aclosed+closed%3A%3E2021-02-16) were merged after the 3.0.0-RC1 release and until today! +Hello! We are happy to announce Scala 3.0.0-RC2. With this release, we are getting ready for 3.0.0. The significance of it is to give the community the chance and time to test all the changes meant for 3.0.0 final. A lot of bug fixes found their way into this release to ensure stability for 3.0.0 – more than [250 PRs](https://github.com/scala/scala3/pulls?q=is%3Apr+is%3Aclosed+closed%3A%3E2021-02-16) were merged after the 3.0.0-RC1 release and until today! Read more about this release below. @@ -28,31 +28,31 @@ As mentioned above, we are currently in an issue-fixing mode. So a lot of those There are some notable changes worth mentioning. ## Restrict experimental features to unstable releases only -PR [#11920](https://github.com/lampepfl/dotty/pull/11920) restricts usage of experimental features only to nightlies and snapshots. This change ensures that changes deemed experimental will not propagate into the wider ecosystem provided that the wider ecosystem depends on stable releases. This is needed so that if an experimental feature is modified or removed from the language, the ecosystem will not be impacted. +PR [#11920](https://github.com/scala/scala3/pull/11920) restricts usage of experimental features only to nightlies and snapshots. This change ensures that changes deemed experimental will not propagate into the wider ecosystem provided that the wider ecosystem depends on stable releases. This is needed so that if an experimental feature is modified or removed from the language, the ecosystem will not be impacted. ## New `unsafeNulls` language feature -PR [#9884](https://github.com/lampepfl/dotty/pull/9884) adds a new language feature which enables unsafe null operations under explicit nulls. This is a tool to help projects migrating to full explicit nulls gradually. From now on, you can use an import `import scala.language.unsafeNulls` to create an unsafe scope. For discussion, see the PR linked above, and for more information on the feature, see the [documentation](https://dotty.epfl.ch/docs/reference/other-new-features/explicit-nulls.html). +PR [#9884](https://github.com/scala/scala3/pull/9884) adds a new language feature which enables unsafe null operations under explicit nulls. This is a tool to help projects migrating to full explicit nulls gradually. From now on, you can use an import `import scala.language.unsafeNulls` to create an unsafe scope. For discussion, see the PR linked above, and for more information on the feature, see the [documentation](https://dotty.epfl.ch/docs/reference/other-new-features/explicit-nulls.html). ## Treat Scala.js pseudo-unions as real unions -In PR [#11671](https://github.com/lampepfl/dotty/pull/11671), we now treat the `scala.scalajs.js.|[A, B]` as if it was a real Scala 3 union `A | B`, which further boosts the support for Scala.js in Scala 3. +In PR [#11671](https://github.com/scala/scala3/pull/11671), we now treat the `scala.scalajs.js.|[A, B]` as if it was a real Scala 3 union `A | B`, which further boosts the support for Scala.js in Scala 3. ## Other API changes -`-Ycheck-init` was renamed to `-Ysafe-init`. This flag is used to check safe initialization, more about which you can read in the [documentation](https://dotty.epfl.ch/docs/reference/other-new-features/safe-initialization.html). See also PR [#11920](https://github.com/lampepfl/dotty/pull/11920). +`-Ycheck-init` was renamed to `-Ysafe-init`. This flag is used to check safe initialization, more about which you can read in the [documentation](https://dotty.epfl.ch/docs/reference/other-new-features/safe-initialization.html). See also PR [#11920](https://github.com/scala/scala3/pull/11920). -PR [#11745](https://github.com/lampepfl/dotty/pull/11745) changes the `compiletime` package API a bit. `compiletime.S` was moved to `compiletime.ops.int.S` and the package object `compiletime` was removed in favor of top-level definitions. +PR [#11745](https://github.com/scala/scala3/pull/11745) changes the `compiletime` package API a bit. `compiletime.S` was moved to `compiletime.ops.int.S` and the package object `compiletime` was removed in favor of top-level definitions. ## Metaprogramming The following are some notable metaprogramming changes included into this release: -- Add quotes.Type.valueOfConstant [#11715](https://github.com/lampepfl/dotty/pull/11715) -- Remove compiletime.Widen [#11569](https://github.com/lampepfl/dotty/pull/11569) -- Add -Xcheck-macros scalac option [#11655](https://github.com/lampepfl/dotty/pull/11655) +- Add quotes.Type.valueOfConstant [#11715](https://github.com/scala/scala3/pull/11715) +- Remove compiletime.Widen [#11569](https://github.com/scala/scala3/pull/11569) +- Add -Xcheck-macros scalac option [#11655](https://github.com/scala/scala3/pull/11655) # Let us know what you think! If you have questions or any sort of feedback, feel free to send us a message on our [Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please -[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). +[open an issue on GitHub](https://github.com/scala/scala3/issues/new). ## Contributors @@ -107,7 +107,7 @@ According to `git shortlog -sn --no-merges 3.0.0-RC1..3.0.0-RC2` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -116,7 +116,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2021-04-21-scala3-rc3.md b/docs/_blog/_posts/2021-04-21-scala3-rc3.md index 8651730da93a..6eddc82e7273 100644 --- a/docs/_blog/_posts/2021-04-21-scala3-rc3.md +++ b/docs/_blog/_posts/2021-04-21-scala3-rc3.md @@ -13,16 +13,16 @@ This release also impacts the release date for 3.0.0 stable. 3.0.0 stable will g <!--more--> # Bug fixes included -- Fix type test for trait parameter arguments [#12066](https://github.com/lampepfl/dotty/pull/12066) -- Set file filter correctly [#12119](https://github.com/lampepfl/dotty/pull/12119) -- Provide mirror support after inlining [#12079](https://github.com/lampepfl/dotty/pull/12079) -- Revert "Recursively check nonvariant arguments of base types for realizability" [#12067](https://github.com/lampepfl/dotty/pull/12067) -- When simplifying match types, ensure fully defined before reducing [#12068](https://github.com/lampepfl/dotty/pull/12068) -- sbt-dotty: the binary version is 3 for Scala >= 3.0.0 [#12084](https://github.com/lampepfl/dotty/pull/12084) -- Fix isInstanceOf[Array[?]] returning true on non-Array [#12108](https://github.com/lampepfl/dotty/pull/12108) -- Scala2Unpickler: don't unpickle the same type parameter twice [#12129](https://github.com/lampepfl/dotty/pull/12129) -- Overloading resolution: Handle SAM types more like Java and Scala 2 [#12131](https://github.com/lampepfl/dotty/pull/12131) -- Add TermParamClause.isGiven [#12042](https://github.com/lampepfl/dotty/pull/12042) +- Fix type test for trait parameter arguments [#12066](https://github.com/scala/scala3/pull/12066) +- Set file filter correctly [#12119](https://github.com/scala/scala3/pull/12119) +- Provide mirror support after inlining [#12079](https://github.com/scala/scala3/pull/12079) +- Revert "Recursively check nonvariant arguments of base types for realizability" [#12067](https://github.com/scala/scala3/pull/12067) +- When simplifying match types, ensure fully defined before reducing [#12068](https://github.com/scala/scala3/pull/12068) +- sbt-dotty: the binary version is 3 for Scala >= 3.0.0 [#12084](https://github.com/scala/scala3/pull/12084) +- Fix isInstanceOf[Array[?]] returning true on non-Array [#12108](https://github.com/scala/scala3/pull/12108) +- Scala2Unpickler: don't unpickle the same type parameter twice [#12129](https://github.com/scala/scala3/pull/12129) +- Overloading resolution: Handle SAM types more like Java and Scala 2 [#12131](https://github.com/scala/scala3/pull/12131) +- Add TermParamClause.isGiven [#12042](https://github.com/scala/scala3/pull/12042) ## Contributors Thank you to all the contributors who made this release possible 🎉 @@ -40,7 +40,7 @@ According to `git shortlog -sn --no-merges 3.0.0-RC2..3.0.0-RC3` these are: If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), -and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). +and have a look at some of the [good first issues](https://github.com/scala/scala3/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). They make perfect entry points into hacking on the compiler. We are looking forward to having you join the team of contributors. @@ -49,7 +49,7 @@ We are looking forward to having you join the team of contributors. Dotty now has a set of widely-used community libraries that are built against every nightly Dotty snapshot. Currently, this includes shapeless, ScalaPB, algebra, scalatest, scopt and squants. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2021-06-07-scala3.0.1-rc1-release.md b/docs/_blog/_posts/2021-06-07-scala3.0.1-rc1-release.md index e9fac2d0447c..617f175e74b7 100644 --- a/docs/_blog/_posts/2021-06-07-scala3.0.1-rc1-release.md +++ b/docs/_blog/_posts/2021-06-07-scala3.0.1-rc1-release.md @@ -21,13 +21,13 @@ The spirit of this policy is to make sure that effectively, no library published Having said that, we still encourage people to play with the experimental features from the `NIGHTLY` compiler versions and discuss their findings. Without the curious and adventurous part of the community playing with the new features, there is no way of knowing what they are good for, and no way to decide whether they should be dropped or promoted to a stable feature. -More about this change you can read in the PR [#12102](https://github.com/lampepfl/dotty/pull/12102). +More about this change you can read in the PR [#12102](https://github.com/scala/scala3/pull/12102). # Kind-projector work -This release also brings extra features for the [Kind Projector](https://docs.scala-lang.org/scala3/guides/migration/plugin-kind-projector.html) migration support. First, PR [#12378](https://github.com/lampepfl/dotty/pull/12378) allows `_` as type lambda placeholder. Second, PR [#12341](https://github.com/lampepfl/dotty/pull/12341) brings support for the variance annotations on the placeholder. This work enhances the ability to cross-compile Scala 2 code that uses the Kind Projector plugin to Scala 3. +This release also brings extra features for the [Kind Projector](https://docs.scala-lang.org/scala3/guides/migration/plugin-kind-projector.html) migration support. First, PR [#12378](https://github.com/scala/scala3/pull/12378) allows `_` as type lambda placeholder. Second, PR [#12341](https://github.com/scala/scala3/pull/12341) brings support for the variance annotations on the placeholder. This work enhances the ability to cross-compile Scala 2 code that uses the Kind Projector plugin to Scala 3. # Improved error reporting -Down the error reporting lane, match type reduction errors were improved. When using a match type, it may or may not reduce to one of its cases. If it doesn't match type is used as specified, e.g. if `M[T]` is a match type and it didn't reduce for `M[Int]`, `M[Int]` will be used. This behavior, however, is frequently not what you want: there is a lot of cases where you would expect a match type to reduce but it doesn't. In such cases, it would be nice to have some diagnostic regarding why it didn't reduce. PR [#12053](https://github.com/lampepfl/dotty/pull/12053/) adds just such a diagnostic. E.g. the following code: +Down the error reporting lane, match type reduction errors were improved. When using a match type, it may or may not reduce to one of its cases. If it doesn't match type is used as specified, e.g. if `M[T]` is a match type and it didn't reduce for `M[Int]`, `M[Int]` will be used. This behavior, however, is frequently not what you want: there is a lot of cases where you would expect a match type to reduce but it doesn't. In such cases, it would be nice to have some diagnostic regarding why it didn't reduce. PR [#12053](https://github.com/scala/scala3/pull/12053/) adds just such a diagnostic. E.g. the following code: ```scala trait A @@ -58,32 +58,32 @@ will report the following error: ``` # Scaladoc -We have updated the [documentation](http://dotty.epfl.ch/docs/usage/scaladoc/index.html) for Scaladoc making it easier for you to get started. Also, PR [#11582](https://github.com/lampepfl/dotty/pull/11582) has added the snippet compiler to ensure the snippets in your scaladoc documentation comments aren't broken. You can read more about this feature on the [mailing list](https://contributors.scala-lang.org/t/snippet-validation-in-scaladoc-for-scala-3/4976). +We have updated the [documentation](http://dotty.epfl.ch/docs/usage/scaladoc/index.html) for Scaladoc making it easier for you to get started. Also, PR [#11582](https://github.com/scala/scala3/pull/11582) has added the snippet compiler to ensure the snippets in your scaladoc documentation comments aren't broken. You can read more about this feature on the [mailing list](https://contributors.scala-lang.org/t/snippet-validation-in-scaladoc-for-scala-3/4976). # Metaprogramming A lot of metaprogramming work was focused on improving the performance. Some of the notable PRs include: -- Cache quote unpickling [#12242](https://github.com/lampepfl/dotty/pull/12242) -- Avoid pickled tasty for some captured quote reference [#12248](https://github.com/lampepfl/dotty/pull/12248) -- Improve quote matcher performance [#12418](https://github.com/lampepfl/dotty/pull/12418) -- Port scala.quoted.runtime.impl.QuoteMatcher [#12402](https://github.com/lampepfl/dotty/pull/12402) +- Cache quote unpickling [#12242](https://github.com/scala/scala3/pull/12242) +- Avoid pickled tasty for some captured quote reference [#12248](https://github.com/scala/scala3/pull/12248) +- Improve quote matcher performance [#12418](https://github.com/scala/scala3/pull/12418) +- Port scala.quoted.runtime.impl.QuoteMatcher [#12402](https://github.com/scala/scala3/pull/12402) # Issue fixing Otherwise, we are making an effort to reduce our issue tracker. Among others, the following are some of the PRs dedicated to issue fixing: -- IArray.toArray: Deprecate broken method [#12598](https://github.com/lampepfl/dotty/pull/12598) -- Fix comparison of dependent function types [#12214](https://github.com/lampepfl/dotty/pull/12214) -- Make translucentSuperType handle match types [#12153](https://github.com/lampepfl/dotty/pull/12153) -- Harden Type Inference [#12560](https://github.com/lampepfl/dotty/pull/12560) -- Reject references to self in super constructor calls [#12567](https://github.com/lampepfl/dotty/pull/12567) -- Provide mirror support after inlining [#12062](https://github.com/lampepfl/dotty/pull/12062) -- Allow export paths to see imports [#12134](https://github.com/lampepfl/dotty/pull/12134) -- Streamline given syntax [#12107](https://github.com/lampepfl/dotty/pull/12107) -- Export constructor proxies [#12311](https://github.com/lampepfl/dotty/pull/12311) -- Identify package and nested package object in isSubPrefix [#12297](https://github.com/lampepfl/dotty/pull/12297) -- Treat Refinements more like AndTypes [#12317](https://github.com/lampepfl/dotty/pull/12317) -- Fix [#9871](https://github.com/lampepfl/dotty/pull/9871): use toNestedPairs in provablyDisjoint [#10560](https://github.com/lampepfl/dotty/pull/10560) +- IArray.toArray: Deprecate broken method [#12598](https://github.com/scala/scala3/pull/12598) +- Fix comparison of dependent function types [#12214](https://github.com/scala/scala3/pull/12214) +- Make translucentSuperType handle match types [#12153](https://github.com/scala/scala3/pull/12153) +- Harden Type Inference [#12560](https://github.com/scala/scala3/pull/12560) +- Reject references to self in super constructor calls [#12567](https://github.com/scala/scala3/pull/12567) +- Provide mirror support after inlining [#12062](https://github.com/scala/scala3/pull/12062) +- Allow export paths to see imports [#12134](https://github.com/scala/scala3/pull/12134) +- Streamline given syntax [#12107](https://github.com/scala/scala3/pull/12107) +- Export constructor proxies [#12311](https://github.com/scala/scala3/pull/12311) +- Identify package and nested package object in isSubPrefix [#12297](https://github.com/scala/scala3/pull/12297) +- Treat Refinements more like AndTypes [#12317](https://github.com/scala/scala3/pull/12317) +- Fix [#9871](https://github.com/scala/scala3/pull/9871): use toNestedPairs in provablyDisjoint [#10560](https://github.com/scala/scala3/pull/10560) # Contributors @@ -147,7 +147,7 @@ According to `git shortlog -sn --no-merges 3.0.0-RC2..3.0.1-RC1`† these are: ## Library authors: Join our community build Scala 3 now has a set of widely-used community libraries that are built against every nightly Scala 3 snapshot. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_blog/_posts/2021-06-25-scala301-rc2.md b/docs/_blog/_posts/2021-06-25-scala301-rc2.md index 76257d1a8664..054a8dfc9d56 100644 --- a/docs/_blog/_posts/2021-06-25-scala301-rc2.md +++ b/docs/_blog/_posts/2021-06-25-scala301-rc2.md @@ -6,9 +6,9 @@ authorImg: /images/anatolii.png date: 2021-06-25 --- -This post is a quick announcement of Scala 3.0.1-RC2. This is the second release candidate for 3.0.1. The reason for this release is that a regression with respect to 3.0.0 was introduced by PR [#12519](https://github.com/lampepfl/dotty/pull/12519) which caused the compiler to fail where it shouldn't. We have fixed this regression in PR [#12827](https://github.com/lampepfl/dotty/pull/12827) and backported it to 3.0.1. This is the main reason for having 3.0.1-RC2 before 3.0.1 which is due in one week. +This post is a quick announcement of Scala 3.0.1-RC2. This is the second release candidate for 3.0.1. The reason for this release is that a regression with respect to 3.0.0 was introduced by PR [#12519](https://github.com/scala/scala3/pull/12519) which caused the compiler to fail where it shouldn't. We have fixed this regression in PR [#12827](https://github.com/scala/scala3/pull/12827) and backported it to 3.0.1. This is the main reason for having 3.0.1-RC2 before 3.0.1 which is due in one week. -Besides this main change, taking advantage of the fact that RC2 is happening, we have also included various SBT reporting improvements (PR [#12845](https://github.com/lampepfl/dotty/pull/12845)) which should improve interaction with [Metals](https://scalameta.org/metals/). Also we've backported a few infrastructural fixes even though they aren't a regression from 3.0.0. +Besides this main change, taking advantage of the fact that RC2 is happening, we have also included various SBT reporting improvements (PR [#12845](https://github.com/scala/scala3/pull/12845)) which should improve interaction with [Metals](https://scalameta.org/metals/). Also we've backported a few infrastructural fixes even though they aren't a regression from 3.0.0. <!--more--> @@ -29,7 +29,7 @@ According to `git shortlog -sn --no-merges 3.0.1-RC1..3.0.1-RC2` these are: ## Library authors: Join our community build Scala 3 now has a set of widely-used community libraries that are built against every nightly Scala 3 snapshot. -Join our [community build](https://github.com/lampepfl/dotty/tree/main/community-build) +Join our [community build](https://github.com/scala/scala3/tree/main/community-build) to make sure that our regression suite includes your library. [Scastie]: https://scastie.scala-lang.org/?target=dotty diff --git a/docs/_docs/contributing/architecture/context.md b/docs/_docs/contributing/architecture/context.md index cd38ee437867..61cb88ad5494 100644 --- a/docs/_docs/contributing/architecture/context.md +++ b/docs/_docs/contributing/architecture/context.md @@ -50,4 +50,4 @@ convention is that the `Context` be an explicit parameter, to track its usage. | ... | and so on | -[Contexts]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Contexts.scala +[Contexts]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Contexts.scala diff --git a/docs/_docs/contributing/architecture/lifecycle.md b/docs/_docs/contributing/architecture/lifecycle.md index 2cf58f477da3..30ca934ede71 100644 --- a/docs/_docs/contributing/architecture/lifecycle.md +++ b/docs/_docs/contributing/architecture/lifecycle.md @@ -78,13 +78,13 @@ tools // contains helpers and the `scala` generic runner ``` -[Phases]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Phases.scala -[CompilationUnit]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala +[Phases]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Phases.scala +[CompilationUnit]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala -[dotty.tools]: https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools -[ScalaSettings]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +[dotty.tools]: https://github.com/scala/scala3/tree/master/compiler/src/dotty/tools +[ScalaSettings]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala [syntax]: https://docs.scala-lang.org/scala3/reference/syntax.html -[Main]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Main.scala -[Driver]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Driver.scala -[Compiler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala -[Run]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Run.scala \ No newline at end of file +[Main]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/Main.scala +[Driver]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/Driver.scala +[Compiler]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala +[Run]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/Run.scala \ No newline at end of file diff --git a/docs/_docs/contributing/architecture/phases.md b/docs/_docs/contributing/architecture/phases.md index 844ae144dddb..8e63de04dadb 100644 --- a/docs/_docs/contributing/architecture/phases.md +++ b/docs/_docs/contributing/architecture/phases.md @@ -85,24 +85,24 @@ suitable for the runtime system, with two sub-groupings: ### `backendPhases` These map the transformed trees to Java classfiles or SJSIR files. -[CompilationUnit]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala -[Compiler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala -[Phase]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Phases.scala -[MiniPhase]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala -[Run]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Run.scala -[parser]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/parsing/ParserPhase.scala -[typer]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala -[posttyper]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PostTyper.scala -[prepjsinterop]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala -[pickler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Pickler.scala -[inlining]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Inlining.scala -[postInlining]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PostInlining.scala -[staging]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Staging.scala -[pickleQuotes]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala -[refchecks]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/typer/RefChecks.scala -[initChecker]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/init/Checker.scala -[firstTransform]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala -[patternMatcher]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala -[erasure]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Erasure.scala -[Mirror]: https://github.com/lampepfl/dotty/blob/master/library/src/scala/deriving/Mirror.scala +[CompilationUnit]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala +[Compiler]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala +[Phase]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Phases.scala +[MiniPhase]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala +[Run]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/Run.scala +[parser]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/parsing/ParserPhase.scala +[typer]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala +[posttyper]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +[prepjsinterop]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala +[pickler]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/Pickler.scala +[inlining]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/Inlining.scala +[postInlining]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/PostInlining.scala +[staging]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/Staging.scala +[pickleQuotes]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala +[refchecks]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +[initChecker]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/init/Checker.scala +[firstTransform]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +[patternMatcher]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +[erasure]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/Erasure.scala +[Mirror]: https://github.com/scala/scala3/blob/master/library/src/scala/deriving/Mirror.scala [PCP]: ../../reference/metaprogramming/macros.md#the-phase-consistency-principle diff --git a/docs/_docs/contributing/architecture/symbols.md b/docs/_docs/contributing/architecture/symbols.md index c19588a4ff12..c11c054b4967 100644 --- a/docs/_docs/contributing/architecture/symbols.md +++ b/docs/_docs/contributing/architecture/symbols.md @@ -60,11 +60,11 @@ All definition symbols will contain a `SymDenotation`. The denotation, in turn, A class symbol will instead be associated with a `ClassDenotation`, which extends `SymDenotation` with some additional fields specific for classes. -[Signature1]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Signature.scala#L9-L33 -[Symbols]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Symbols.scala -[flatten]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Flatten.scala -[lambdaLift]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala -[CompilationUnit]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala -[Denotations]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Denotations.scala -[SymDenotations]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/SymDenotations.scala -[flags]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Flags.scala +[Signature1]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Signature.scala#L9-L33 +[Symbols]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Symbols.scala +[flatten]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/Flatten.scala +[lambdaLift]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala +[CompilationUnit]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala +[Denotations]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Denotations.scala +[SymDenotations]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +[flags]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Flags.scala diff --git a/docs/_docs/contributing/architecture/time.md b/docs/_docs/contributing/architecture/time.md index 588b1ce40bb2..56a6cf7447a1 100644 --- a/docs/_docs/contributing/architecture/time.md +++ b/docs/_docs/contributing/architecture/time.md @@ -61,8 +61,8 @@ method foo after typer => (b: Box)(x: b.X): scala.collection.immutable.List[b. method foo after erasure => (b: Box, x: Object): scala.collection.immutable.List ``` -[runs]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/Run.scala -[periods]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Periods.scala -[Contexts]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Contexts.scala -[typer]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala -[erasure]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Erasure.scala +[runs]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/Run.scala +[periods]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Periods.scala +[Contexts]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Contexts.scala +[typer]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala +[erasure]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/Erasure.scala diff --git a/docs/_docs/contributing/architecture/types.md b/docs/_docs/contributing/architecture/types.md index 2dfdc33101a0..ed8995c08643 100644 --- a/docs/_docs/contributing/architecture/types.md +++ b/docs/_docs/contributing/architecture/types.md @@ -143,5 +143,5 @@ Type -+- proxy_type --+- NamedType --------+- TypeRef ``` -[Types.scala]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Types.scala -[DottyTypeStealer]: https://github.com/lampepfl/dotty/blob/master/compiler/test/dotty/tools/DottyTypeStealer.scala +[Types.scala]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Types.scala +[DottyTypeStealer]: https://github.com/scala/scala3/blob/master/compiler/test/dotty/tools/DottyTypeStealer.scala diff --git a/docs/_docs/contributing/community-build.md b/docs/_docs/contributing/community-build.md index b382786c614e..e333e4985e36 100644 --- a/docs/_docs/contributing/community-build.md +++ b/docs/_docs/contributing/community-build.md @@ -32,14 +32,14 @@ project to the community build you can follow these steps: check out the [Scala 3 Migration Guide](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html). You can see the submodules in - [community-projects](https://github.com/lampepfl/dotty/tree/main/community-build/community-projects/) + [community-projects](https://github.com/scala/scala3/tree/main/community-build/community-projects/) for examples of projects that compile with Scala 3. 2. Open a PR against this repo that: - Adds your project as a new git submodule - `git submodule add https://github.com/dotty-staging/XYZ.git community-build/community-projects/XYZ` - - Add the project to [projects.scala](https://github.com/lampepfl/dotty/blob/main/community-build/src/scala/dotty/communitybuild/projects.scala) - - Adds a test in [CommunityBuildTest.scala](https://github.com/lampepfl/dotty/blob/main/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala) + - Add the project to [projects.scala](https://github.com/scala/scala3/blob/main/community-build/src/scala/dotty/communitybuild/projects.scala) + - Adds a test in [CommunityBuildTest.scala](https://github.com/scala/scala3/blob/main/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala) 3. Once the CI is green, someone from the Dotty team will fork your repo and add it to [dotty-staging](https://github.com/dotty-staging). This enables us to diff --git a/docs/_docs/contributing/debugging/ide-debugging.md b/docs/_docs/contributing/debugging/ide-debugging.md index af817826565a..8548235672af 100644 --- a/docs/_docs/contributing/debugging/ide-debugging.md +++ b/docs/_docs/contributing/debugging/ide-debugging.md @@ -74,7 +74,7 @@ To locate them on your filesystem you can run the `export scala3-library-bootstr ``` $ sbt > export scala3-library-bootstrapped/fullClasspath -/home/user/lampepfl/dotty/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar +/home/user/scala/scala3/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar [success] Total time: 1 s, completed Mar 10, 2023, 4:37:43 PM ``` @@ -93,7 +93,7 @@ Here is the final configuration: "../tests/pos/HelloWorld.scala", "-classpath", // To replace with your own paths - "/home/user/lampepfl/dotty/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar", + "/home/user/scala/scala3/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar", "-color", "never" ], @@ -112,7 +112,7 @@ You can compile more than one Scala file, by adding them in the `args`: "file1.scala", "file2.scala", "-classpath", - "/home/user/lampepfl/dotty/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar" + "/home/user/scala/scala3/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar" ] ``` @@ -132,7 +132,7 @@ And concatenate the output into the classpath argument, which should already con "args": [ "using-cats.scala", "-classpath", - "/home/user/lampepfl/dotty/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-core_3/2.9.0/cats-core_3-2.9.0.jar:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-kernel_3/2.9.0/cats-kernel_3-2.9.0.jar" + "/home/user/scala/scala3/out/bootstrap/scala3-library-bootstrapped/scala-3.3.1-RC1-bin-SNAPSHOT-nonbootstrapped/classes:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-core_3/2.9.0/cats-core_3-2.9.0.jar:/home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-kernel_3/2.9.0/cats-kernel_3-2.9.0.jar" ] ``` diff --git a/docs/_docs/contributing/debugging/inspection.md b/docs/_docs/contributing/debugging/inspection.md index a80c3d3462ae..7cb1fa68abff 100644 --- a/docs/_docs/contributing/debugging/inspection.md +++ b/docs/_docs/contributing/debugging/inspection.md @@ -181,6 +181,6 @@ class StealBox: assert(empty.name.toString == "<empty>") ``` -[DottyTypeStealer]: https://github.com/lampepfl/dotty/blob/master/compiler/test/dotty/tools/DottyTypeStealer.scala -[ScalaSettings]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala -[symbols]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +[DottyTypeStealer]: https://github.com/scala/scala3/blob/master/compiler/test/dotty/tools/DottyTypeStealer.scala +[ScalaSettings]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +[symbols]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/SymDenotations.scala diff --git a/docs/_docs/contributing/debugging/other-debugging.md b/docs/_docs/contributing/debugging/other-debugging.md index 50be43db51ab..e8b72bcca656 100644 --- a/docs/_docs/contributing/debugging/other-debugging.md +++ b/docs/_docs/contributing/debugging/other-debugging.md @@ -152,7 +152,7 @@ To print out the trees after all phases: scalac -Xprint:all ../issues/Playground.scala ``` -To find out the list of all the phases and their names, check out [this](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/Compiler.scala#L34) line in `Compiler.scala`. Each `Phase` object has `phaseName` defined on it, this is the phase name. +To find out the list of all the phases and their names, check out [this](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/Compiler.scala#L34) line in `Compiler.scala`. Each `Phase` object has `phaseName` defined on it, this is the phase name. ## Printing out stack traces of compile time errors You can use the flag `-Ydebug-error` to get the stack trace of all the compile-time errors. Consider the following file: @@ -207,7 +207,7 @@ val YshowVarBounds = BooleanSetting("-Yshow-var-bounds" , "Print type varia val YtestPickler = BooleanSetting("-Ytest-pickler" , "self-test for pickling functionality; should be used with -Ystop-after:pickler") ``` -They are defined in [ScalaSettings.scala](https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala). E.g. `YprintPos` is defined as: +They are defined in [ScalaSettings.scala](https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala). E.g. `YprintPos` is defined as: ```scala val YprintPos: Setting[Boolean] = BooleanSetting("-Yprint-pos", "show tree positions.") @@ -244,7 +244,7 @@ package <empty>@<Playground.scala:1> { ### Figuring out an object creation site #### Via ID -Every [Positioned](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/ast/Positioned.scala) (a parent class of `Tree`) object has a `uniqueId` field. It is an integer that is unique for that tree and doesn't change from compile run to compile run. You can output these IDs from any printer (such as the ones used by `.show` and `-Xprint`) via `-Yshow-tree-ids` flag, e.g.: +Every [Positioned](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/ast/Positioned.scala) (a parent class of `Tree`) object has a `uniqueId` field. It is an integer that is unique for that tree and doesn't change from compile run to compile run. You can output these IDs from any printer (such as the ones used by `.show` and `-Xprint`) via `-Yshow-tree-ids` flag, e.g.: ```shell scalac -Xprint:typer -Yshow-tree-ids ../issues/Playground.scala @@ -355,7 +355,7 @@ if (tree.show == """println("Hello World")""") { } ``` -In other words, you have a reference to the object and want to know were it was created. To do so, go to the class definition of that object. In our case, `tree` is a [`Tree`](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/ast/Trees.scala#L52). Now, create a new `val` member of that type: +In other words, you have a reference to the object and want to know were it was created. To do so, go to the class definition of that object. In our case, `tree` is a [`Tree`](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/ast/Trees.scala#L52). Now, create a new `val` member of that type: ```scala val tracer = Thread.currentThread.getStackTrace.mkString("\n") @@ -380,7 +380,7 @@ Dotty has a lot of debug calls scattered throughout the code, most of which are These do not follow any particular system and so probably it will be easier to go with `println` most of the times instead. #### Printers -Defined in [Printers.scala](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/config/Printers.scala) as a set of variables, each responsible for its own domain. To enable them, replace `noPrinter` with `default`. [Example](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/typer/Typer.scala#L2226) from the code: +Defined in [Printers.scala](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/config/Printers.scala) as a set of variables, each responsible for its own domain. To enable them, replace `noPrinter` with `default`. [Example](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/typer/Typer.scala#L2226) from the code: ```scala typr.println(i"make contextual function $tree / $pt ---> $ifun") @@ -389,13 +389,13 @@ typr.println(i"make contextual function $tree / $pt ---> $ifun") `typr` is a printer. #### Tracing -Defined in [trace.scala](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/reporting/trace.scala). [Example](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/typer/Typer.scala#L2232) from the code: +Defined in [trace.scala](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/reporting/trace.scala). [Example](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/typer/Typer.scala#L2232) from the code: ```scala trace(i"typing $tree", typr, show = true) { // ... ``` -To enable globally, change [tracingEnabled](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/config/Config.scala#L164) to `true` (will recompile a lot of code). +To enable globally, change [tracingEnabled](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/config/Config.scala#L164) to `true` (will recompile a lot of code). You also need to set the printer referenced in the call (in the example, `typr`) to `default` as explained in the section on printers. @@ -406,4 +406,4 @@ trace.force(i"typing $tree", typr, show = true) { // ... ``` #### Reporter -Defined in [Reporter.scala](https://github.com/lampepfl/dotty/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/reporting/Reporter.scala). Enables calls such as `report.log`. To enable, run scalac with `-Ylog:typer` option. +Defined in [Reporter.scala](https://github.com/scala/scala3/blob/10526a7d0aa8910729b6036ee51942e05b71abf6/compiler/src/dotty/tools/dotc/reporting/Reporter.scala). Enables calls such as `report.log`. To enable, run scalac with `-Ylog:typer` option. diff --git a/docs/_docs/contributing/getting-started.md b/docs/_docs/contributing/getting-started.md index 938e7ff36d42..63e968902600 100644 --- a/docs/_docs/contributing/getting-started.md +++ b/docs/_docs/contributing/getting-started.md @@ -127,7 +127,7 @@ For more information, see the [scaladoc section](./scaladoc.md). ## Community The main development discussion channels are: -- [github.com/lampepfl/dotty/discussions](https://github.com/lampepfl/dotty/discussions) +- [github.com/scala/scala3/discussions](https://github.com/scala/scala3/discussions) - [contributors.scala-lang.org](https://contributors.scala-lang.org) - [gitter.im/scala/contributors](https://gitter.im/scala/contributors) @@ -141,5 +141,5 @@ The main development discussion channels are: [adopt]: https://adoptopenjdk.net/ [compat]: https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html [scala-cla]: https://www.lightbend.com/contribute/cla/scala -[dotty-issue]: https://github.com/lampepfl/dotty/issues -[dotty-discussion]: https://github.com/lampepfl/dotty/discussions +[dotty-issue]: https://github.com/scala/scala3/issues +[dotty-discussion]: https://github.com/scala/scala3/discussions diff --git a/docs/_docs/contributing/index.md b/docs/_docs/contributing/index.md index 507149340941..965847e39a94 100644 --- a/docs/_docs/contributing/index.md +++ b/docs/_docs/contributing/index.md @@ -12,9 +12,9 @@ also documents the inner workings of the Scala 3 compiler, `dotc`. Keep in mind that the code for `dotc` is continually changing, so the ideas discussed in this guide may fall out of date. This is a living document, so please consider contributing to it on -[GitHub](https://github.com/lampepfl/dotty/tree/main/docs/_docs/contributing) if +[GitHub](https://github.com/scala/scala3/tree/main/docs/_docs/contributing) if you notice anything out of date, or report any issues -[here](https://github.com/lampepfl/dotty/issues). +[here](https://github.com/scala/scala3/issues). ### Get the most from This Guide diff --git a/docs/_docs/contributing/issues/areas.md b/docs/_docs/contributing/issues/areas.md index ce27e9c0a5aa..9206d608ffbb 100644 --- a/docs/_docs/contributing/issues/areas.md +++ b/docs/_docs/contributing/issues/areas.md @@ -55,17 +55,17 @@ See [Inliner]. #### Compiletime Ops Types See `tryCompiletimeConstantFold` in [Types]. -[Showable]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/printing/Showable.scala -[PlainPrinter]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala -[RefinedPrinter]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala -[ErrorMessageID]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala -[messages]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/reporting/messages.scala -[Synthesizer]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala -[SyntheticMembers]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala -[quotes-impl]: https://github.com/lampepfl/dotty/tree/master/compiler/src/scala/quoted/runtime/impl -[Inliner]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/inlines/Inliner.scala -[Types]: https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/core/Types.scala -[Completion]: https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/interactive/Completion.scala -[DesugarEnums]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala -[Desugar]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/ast/Desugar.scala -[Space]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +[Showable]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/printing/Showable.scala +[PlainPrinter]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +[RefinedPrinter]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +[ErrorMessageID]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +[messages]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/reporting/messages.scala +[Synthesizer]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +[SyntheticMembers]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala +[quotes-impl]: https://github.com/scala/scala3/tree/master/compiler/src/scala/quoted/runtime/impl +[Inliner]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/inlines/Inliner.scala +[Types]: https://github.com/scala/scala3/tree/master/compiler/src/dotty/tools/dotc/core/Types.scala +[Completion]: https://github.com/scala/scala3/tree/master/compiler/src/dotty/tools/dotc/interactive/Completion.scala +[DesugarEnums]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala +[Desugar]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/ast/Desugar.scala +[Space]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala diff --git a/docs/_docs/contributing/issues/cause.md b/docs/_docs/contributing/issues/cause.md index e23f6d1f747f..f96d3b6d2f8a 100644 --- a/docs/_docs/contributing/issues/cause.md +++ b/docs/_docs/contributing/issues/cause.md @@ -116,7 +116,7 @@ def myInfo: Type = myInfo_debug, def myInfo_=(x: Type) = { tracer = Thread.currentThread.getStackTrace.mkString("\n"); myInfo_debug = x } ``` -[Printers]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/config/Printers.scala -[Denotation]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Denotations.scala -[PostTyper]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PostTyper.scala -[ScalaSettings]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +[Printers]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/config/Printers.scala +[Denotation]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/core/Denotations.scala +[PostTyper]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +[ScalaSettings]: https://github.com/scala/scala3/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala diff --git a/docs/_docs/contributing/issues/reproduce.md b/docs/_docs/contributing/issues/reproduce.md index ca5da324a867..ae031a44d76f 100644 --- a/docs/_docs/contributing/issues/reproduce.md +++ b/docs/_docs/contributing/issues/reproduce.md @@ -159,7 +159,7 @@ scala -classpath $here/out Test # Run main method of `Test` generated by the co In this section, you have seen how to reproduce an issue locally, and next you will see how to try and detect its root cause. -[lampepfl/dotty]: https://github.com/lampepfl/dotty/issues -[#7710]: https://github.com/lampepfl/dotty/issues/7710 +[lampepfl/dotty]: https://github.com/scala/scala3/issues +[#7710]: https://github.com/scala/scala3/issues/7710 [dotty-issue-workspace]: https://github.com/anatoliykmetyuk/dotty-issue-workspace [workspace-readme]: https://github.com/anatoliykmetyuk/dotty-issue-workspace#getting-started diff --git a/docs/_docs/contributing/procedures/release.md b/docs/_docs/contributing/procedures/release.md index c54bb637aff5..88e1beb1b93b 100644 --- a/docs/_docs/contributing/procedures/release.md +++ b/docs/_docs/contributing/procedures/release.md @@ -28,7 +28,7 @@ Say we want to release the 0.14.0 version. In this section we describe the proce CI is set to automatically detect the tags of the format discussed above and perform the required release operations. Precisely, it will do two things for the release tags: - Publish the release jars to Maven -- Create the drafts at the GitHub [release](https://github.com/lampepfl/dotty/releases) page of the repository with the artefacts of the release. +- Create the drafts at the GitHub [release](https://github.com/scala/scala3/releases) page of the repository with the artefacts of the release. The CI operation is entirely automatic provided you have tagged the release correctly. No need to do anything here. @@ -50,11 +50,11 @@ However, you may end up with as many as 6 tasks being run. The auxiliary tasks m ### Release Procedure Checklist Before we start the release procedure, we create an issue with a release checklist. As we go through the release, we update the checklist. To generate the checklist, run the following command: -`bash <(curl -sL https://raw.githubusercontent.com/lampepfl/dotty/main/docs/docs/contributing/checklist.sh) <stable_release>` +`bash <(curl -sL https://raw.githubusercontent.com/scala/scala3/main/docs/docs/contributing/checklist.sh) <stable_release>` Above, `<stable_release>` is the stable version being released. For example, if you are releasing `0.14.0` and `0.15.0-RC1`, this variable is `14` and the command is as follows: -`bash <(curl -sL https://raw.githubusercontent.com/lampepfl/dotty/main/docs/docs/contributing/checklist.sh) 14` +`bash <(curl -sL https://raw.githubusercontent.com/scala/scala3/main/docs/docs/contributing/checklist.sh) 14` Copy and paste the output into the release issue. @@ -73,10 +73,10 @@ After the release is done, we document it as follows: During the release process we ensure that various parts of the community are also prepared for the new version of Scala so that users can hit the ground running when the new release is announced. You can see an example of this -[here](https://github.com/lampepfl/dotty/issues/17559). +[here](https://github.com/scala/scala3/issues/17559). # Procedure in Bash Scripts -The below procedure is compiled from [this](https://github.com/lampepfl/dotty/issues/5907#issue-409313505) and [this](https://github.com/lampepfl/dotty/issues/6235#issue-429265748) checklists. It assumes we want to publish the `0.14.0` given the `0.14.0-RC1` release candidate. +The below procedure is compiled from [this](https://github.com/scala/scala3/issues/5907#issue-409313505) and [this](https://github.com/scala/scala3/issues/6235#issue-429265748) checklists. It assumes we want to publish the `0.14.0` given the `0.14.0-RC1` release candidate. Note that at the same time we will also publish the `0.15.0-RC1` release. We publish two releases at the same time as per the logic outlined at the [Example/At the Dotty Repo](#at-the-dotty-repo) and the [Model](#model) sections above: the step (5) in the algorithm outlined in the [Example](#at-the-dotty-repo) for the release cycle of `0.14.0` is the step (1) in the release cycle of `0.15.0`. @@ -101,7 +101,7 @@ git merge 0.14.x git push origin main ######## Publish the 0.15.0-RC1 unstable version – begin the release cycle for 0.15.0 ######## -# Move all the unfinished tasks from Milestone 15 to Milestone 16 on GitHub – see https://github.com/lampepfl/dotty/milestones +# Move all the unfinished tasks from Milestone 15 to Milestone 16 on GitHub – see https://github.com/scala/scala3/milestones git checkout -b 0.15.x diff --git a/docs/_docs/contributing/sending-in-a-pr.md b/docs/_docs/contributing/sending-in-a-pr.md index c99e6a28172b..0c276e2c9287 100644 --- a/docs/_docs/contributing/sending-in-a-pr.md +++ b/docs/_docs/contributing/sending-in-a-pr.md @@ -104,7 +104,7 @@ every part of CI. For example, maybe you're just updating some documentation and there is no need to run the community build for this. We skip parts of the CI by utilizing keywords inside of brackets. The most up-to-date way to see this are by looking in the `if` statements of jobs. For example you can see some -[here](https://github.com/lampepfl/dotty/blob/5d2812a5937389f8a46f9e97ab9cbfbb3f298d87/.github/workflows/ci.yaml#L54-L64). +[here](https://github.com/scala/scala3/blob/5d2812a5937389f8a46f9e97ab9cbfbb3f298d87/.github/workflows/ci.yaml#L54-L64). Below are commonly used ones: @@ -160,8 +160,8 @@ you're PR will be merged in! [pull-request]: https://docs.github.com/en?query=pull+requests [lampepfl/dotty]: https://github.com/lampepfl/dotty [cla]: http://typesafe.com/contribute/cla/scala -[issues]: https://github.com/lampepfl/dotty/issues -[full-list]: https://github.com/lampepfl/dotty/blob/master/CONTRIBUTING.md +[issues]: https://github.com/scala/scala3/issues +[full-list]: https://github.com/scala/scala3/blob/master/CONTRIBUTING.md [discord]: https://discord.gg/TSmY9zkHar [dry]: https://www.oreilly.com/library/view/97-things-every/9780596809515/ch30.html [scouts]: https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html diff --git a/docs/_docs/contributing/setting-up-your-ide.md b/docs/_docs/contributing/setting-up-your-ide.md index 3bb7d329d50c..a02c1dee63cb 100644 --- a/docs/_docs/contributing/setting-up-your-ide.md +++ b/docs/_docs/contributing/setting-up-your-ide.md @@ -34,7 +34,7 @@ want to make sure you do two things: 1. You'll want to find and change the following under `commonBootstrappedSettings` which is found in the - [`Build.scala`](https://github.com/lampepfl/dotty/blob/main/project/Build.scala) + [`Build.scala`](https://github.com/scala/scala3/blob/main/project/Build.scala) file. ```diff diff --git a/docs/_docs/contributing/testing.md b/docs/_docs/contributing/testing.md index f755bcafcd66..039b37ead8bf 100644 --- a/docs/_docs/contributing/testing.md +++ b/docs/_docs/contributing/testing.md @@ -164,25 +164,32 @@ to load the TASTy and the runtime to load the original classfiles. The library is compiled in `scala2-library-bootstrapped` with TASTy and classfiles. These classfiles should not be used. The `scala2-library-tasty` project repackages the -JAR `scala2-library-bootstrapped` to only keep TASTy files. The `scala2-library-tasty-tests` provides some basic tests using the library TASTy JAR. - -``` -$ sbt -> scala2-library-tasty/compile -> scala2-library-tasty-tests/run -> scala2-library-tasty-tests/test -``` +JAR `scala2-library-bootstrapped` to only keep TASTy files. We can enable this library in the build using the SBT setting `useScala2LibraryTasty`. This setting can only be used by bootstrapped compiler tests and is currently only supported for `test` (or `testCompilation`) and `scalac` (or `run`). ``` $ sbt -> set ThisBuild/Build.useScala2LibraryTasty := true +> set ThisBuild/Build.scala2Library := Build.Scala2LibraryTasty > scala3-compiler-bootstrapped/scalac MyFile.scala > scala3-compiler-bootstrapped/test > scala3-compiler-bootstrapped/testCompilation ``` +By default `scala2Library` is set to `Scala2LibraryJar`. This setting can be set to stop using the Scala 2 library TASTy. +``` +> set ThisBuild/Build.scala2Library := Build.Scala2LibraryJar +``` + +#### Scala 2 library with CC TASTy tests +These follow the same structure as the _Scala 2 library TASTy tests_ but add captured checked signatures to the library. The library is compiled in `scala2-library-cc` (instead of `scala2-library-bootstrapped`) and `scala2-library-cc-tasty` (instead of `scala2-library-cc-tasty`). + +We can also enable this library in the build using the SBT setting `useScala2LibraryTasty`. +``` +> set ThisBuild/Build.scala2Library := Build.Scala2LibraryCCTasty +``` + + ### From TASTy tests `testCompilation` has an additional mode to run tests that compile code from a `.tasty` file. @@ -239,7 +246,7 @@ can enter an inconsistent state and cause spurious test failures. If you suspect you can run `rm -rf out/*` from the root of the repository and run your tests again. If that fails, you can try `git clean -xfd`. -[CompilationTests]: https://github.com/lampepfl/dotty/blob/master/compiler/test/dotty/tools/dotc/CompilationTests.scala -[compiler/test]: https://github.com/lampepfl/dotty/blob/master/compiler/test/ -[compiler/test/dotc]: https://github.com/lampepfl/dotty/tree/master/compiler/test/dotc -[SemanticdbTests]: https://github.com/lampepfl/dotty/blob/master/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala +[CompilationTests]: https://github.com/scala/scala3/blob/master/compiler/test/dotty/tools/dotc/CompilationTests.scala +[compiler/test]: https://github.com/scala/scala3/blob/master/compiler/test/ +[compiler/test/dotc]: https://github.com/scala/scala3/tree/master/compiler/test/dotc +[SemanticdbTests]: https://github.com/scala/scala3/blob/master/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala diff --git a/docs/_docs/internals/cc/handling-invariant-vars.md b/docs/_docs/internals/cc/handling-invariant-vars.md new file mode 100644 index 000000000000..e9f0dc85317c --- /dev/null +++ b/docs/_docs/internals/cc/handling-invariant-vars.md @@ -0,0 +1,125 @@ +Handling invariant capture set variables +======================================== + +This note gives a high-level overview of constraints and constraint solving in Scala's capture checker. It then describes a proposal to improve a current problem area: the handling of invariantly mapped capture set variables. + +A capture checking constraint consists of subcapturing constraints between +capture sets. Capture sets can be variable or constant. A capture set variable is either defined by itself, +or is the result of a mapping of a type map. +Depending on what part of an original type created a map result, the set `v` is classified as invariant, covariant, or contravariant. + +We can describe the syntax of capture set constraints like this: +``` +Capture set a, b, c = ac // constant, aliases bv, cc + | av // variable, aliases bv, cv + +Typemap tm = B // bijective on capabilities + | F // arbitrary + +Constraint C = a <: b // simple constraint + | a = B(b) // bimap constraint + | a >: F(b) // covariant map constraint + | a <: F(b) // contravariant map constraint + | a = F(b) // invariant map constraint +``` +Variables appearing in the left hand side of a map constraint are called +map results. In a constraint set, each map result variable appears on the left hand side of only one map constraint, the one which defines it. +We distinguish two kinds of type maps, bijective maps `B` and general maps `F`. General maps are capture-monotonic: if `A <: B` +then the capture set of `F(A)` subcaptures the capture set of `F(B)`. All considered type maps map `cap` to `cap`. + +Examples of bijective maps are substitutions of parameters of one method type +for another, or mapping local method parameter symbols to method parameters. +Examples of monotonic maps are substitutions of argument types for parameters, +avoidance, or as-seen-from. + +Bijective map constraints define variables exactly. General map constraints come in three different forms. In the form `a >: F(b)`, `a` is bounded from +below by the map's result. Such constraints are created when a part +of a type appearing in covariant position is mapped. Consequently, variables +bound that way are called _covariant_. _Contravariant_ variables are defined +by constraints of the `a <: F(b)`. Such constraints are created when a part +of a type appearing in contravariant position is mapped. Finally, _invariant_ variables are defined by constraints of the `a = F(b)`, which are created when a part of a type appearing in invariant position is mapped. + +A solution to a subcapturing constraint set consists of an assignment of capture set constants to capture set variables, so that the resulting constraint set is true. The capture checker uses an incremental propagation-based +solver where capture set variables record which references they are known to contain. When new elements +are added to a set or a new relationship between capture sets is added, elements are propagated until +a new partial solution is found, or a contradiction is detected. A contradiction arises when an attempt +is made to add an element to a constant set that is not accounted for by the set. + +The propagation actions depend on the kind of constraint and whether a new capture set `c` is propagated +to the left part `a` or the right part `b` of the constraint. In the cases where the constraint +involves a general mapping `F`, the mapping `F(r)` of a capability `r` is in general a type, not +a capability or capture set. In this case we use `F(r).CS` for the capture set of the type +`F(r)`. Likewise, if `c` is a capture set, then `F(c)` might be a capture set `c'` if `F` maps all +capabilities in `c` to capabilities. But in general it will be a set of types, and `F(c).CS` +denotes the set of capture sets of these types. Furthermore, we use `c.super` for the capture set +of the definition of the reference `c` (as it shows up in rule (sc-var)). + +The propagation rules are summarized as follows: + +``` +Constraint new relation propagation remark +--------------------------------------------------------------- + a <: b c <: a c <: b + c <: b none + + a = B(b) c <: a B^-1(c) <: b + c <: b B(c) <: a + + a >: F(b) c <: a none + c <: b F(c).CS <: a + + a <: F(b) c <: a c <: b if F(c) = c (1) + c.super <: a otherwise + c <: b none + + a = F(b) c <: a c <: b if F(c) = c (1) + c.super <: a otherwise + c <: b c' <: a if F(c) = c' + F(c).CS? <: a otherwise (2) +``` +Remarks: + +(1) If `F(c) = c`, we solve by adding `c` also to `b`. Otherwise + we try again with `c.super <: a` instead of `c <: a`. At some point + this will succeed since we assume that for all maps `F`, `F(cap) = cap`. + This is clearly sound, but loses completeness since there might be + other, smaller solutions for the constraint. But with `F` not being + bijective, we'd have to try all possible capture sets to find + a suitable set that we could add to `b` so that `c` subcaptures the mapped set. + +(2) is the hard case. If the target set `a` appears invariantly, and `F(x)` is a type, we can use neither the lower bound set `{}` nor the upper bound set `F(x).CS`. Previously, we addressed this problem by making sure case (2) could not arise using the _range_ mechanism, which is also employed for regular type inference. To explain, let's say we try to map some type `t` where `F` is not defined on `t` but we know lower and upper approximations `tl` and `tu`. If `t` appears in +co- or contravariant positions, we can return `tu` or `tl`, respectively. But if `t` +appears in invariant position, we return `Range(tl, tu)`. This is not a type, but a type interval +which will be mapped itself, and will be resolved to one of its bounds at the first +point further out where the variance is positive or negative. There's also the case +where a Range appears in argument position of a parameterized class type, where we can +map it to the wildcard type `? >: tl <: tu`. We used the same mechanism for capture +set inference, by converting invariant occurrences of mapped type arguments `t^v` to wildcard types `? >: t^v1 <: t^v2` proactively, splitting the variable `v` to `v1` and `v2`, so that all capture set constraints occurred at co- or contravariant positions. + +Unfortunately this splitting has bad consequences for type inference, since a wildcard +is usually not compatible with a single expected type. So we would like to find another +technique for solving this issue. + +The idea is to use a technique similar to ranges directly on the capture sets. This means +that we now have a new class of elements of capture sets standing for references that might or might not be in the set. We use `{x?, ...}` as notation for a reference `x` that might or might not be an element of the enclosing capture set. Like `Range`, the notation is purely internal, we +never write it in a source program. + +We now describe how to handle the missing case (2) above. Assume `F(x)` is not a tracked reference, its image `a` is invariant and its capture set `cfr` is `{x_1,...,x_n}` where `n > 0`. In this case we add to `a` the _maybe references_ `x_1?, ..., x_n?`. Generalized to sets, `c <: b` where +`F(c) != c` leads to `F(c).CS?` to be added to `a`. Here, `CS?` is the set consisting of all references `x` in `cs` converted to maybe references `x?`. + +These references behave as follows: + + - For unions, `x` subsumes `x?`, so adding both `x` and `x?` to a set means + only `x` needs to be addded. + + - For further propagation of elements up the chain in e.g. `a <: b`, a maybe reference `x?` behaves like `x`. That is, since the reference could be in the set we have to propagate it upwards to be sound. + + - For propagations from lower sets, a maybe reference is treated as if it was missing. For instance, if we have `a <: b`, `b` contains `x?` and we propagate `x` from `a` to `b`, we need to add `x` as usual to `b`, which might imply back-proagation in the case `b` is an image of a type map `F`. + + - For mappings, maybe references are handled depending on the variance of the + image set. Assume we add `x?` to `b`. If `a >: F(b)` this amounts + to adding `F(x).CS` to `a`. If `a` is contravariant, this amounts to doing nothing. If `a` is invariant, we add `F(x).CS?` to `a`. If + `CS` is a capture set variable, it's "maybe" status has to be recorded and all elements this set acquires in the future also have to be converted to maybe references. + + + diff --git a/docs/_docs/internals/coverage.md b/docs/_docs/internals/coverage.md index 162aa182a1e0..923908683721 100644 --- a/docs/_docs/internals/coverage.md +++ b/docs/_docs/internals/coverage.md @@ -5,7 +5,7 @@ title: "Code Coverage for Scala 3" ## Instrument code for coverage analysis -[PR#13880](https://github.com/lampepfl/dotty/pull/13880) has implemented code coverage support for Dotty. +[PR#13880](https://github.com/scala/scala3/pull/13880) has implemented code coverage support for Dotty. In general, code coverage "instruments" the program at compile time: code is inserted to record which statement are called. This does not change the behavior of the program. Also, a list of all the coverable statements is produced. To use this feature, add the compile option `-coverage-out:DIR`, where `DIR` is the destination of the measurement files. diff --git a/docs/_docs/internals/debug-macros.md b/docs/_docs/internals/debug-macros.md index 4d5cab52c568..a085ebbde355 100644 --- a/docs/_docs/internals/debug-macros.md +++ b/docs/_docs/internals/debug-macros.md @@ -34,7 +34,7 @@ the stack trace, we will be able to figure out where the tree is created. If the position is in the compiler, then either report a compiler bug or fix the problem with `.withSpan(tree.span)`. The following fix is an example: -- https://github.com/lampepfl/dotty/pull/6581 +- https://github.com/scala/scala3/pull/6581 ## unresolved symbols in pickling diff --git a/docs/_docs/internals/dotc-scalac.md b/docs/_docs/internals/dotc-scalac.md index 03baad375eb1..e5335c734891 100644 --- a/docs/_docs/internals/dotc-scalac.md +++ b/docs/_docs/internals/dotc-scalac.md @@ -133,6 +133,6 @@ if (sym is Flags.PackageClass) // Scala 3 (*) * `MethodType(paramSyms, resultType)` from scalac => `mt @ MethodType(paramNames, paramTypes)`. Result type is `mt.resultType` -[Denotations1]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Denotations.scala#L27-L72 -[Denotations2]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Denotations.scala#L77-L103 -[Signature1]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Signature.scala#L9-L33 +[Denotations1]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Denotations.scala#L27-L72 +[Denotations2]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Denotations.scala#L77-L103 +[Signature1]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Signature.scala#L9-L33 diff --git a/docs/_docs/internals/overall-structure.md b/docs/_docs/internals/overall-structure.md index ab936ddd8512..a25c287e16c9 100644 --- a/docs/_docs/internals/overall-structure.md +++ b/docs/_docs/internals/overall-structure.md @@ -235,10 +235,10 @@ Phases fall into four categories: * Code generators: These map the transformed trees to Java classfiles or .sjsir files. -[dotty.tools]: https://github.com/lampepfl/dotty/tree/main/compiler/src/dotty/tools -[dotc]: https://github.com/lampepfl/dotty/tree/main/compiler/src/dotty/tools/dotc -[Main]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/Main.scala -[Driver]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/Driver.scala -[Compiler]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/Compiler.scala -[Run]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/Run.scala -[Context]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/core/Contexts.scala +[dotty.tools]: https://github.com/scala/scala3/tree/main/compiler/src/dotty/tools +[dotc]: https://github.com/scala/scala3/tree/main/compiler/src/dotty/tools/dotc +[Main]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/Main.scala +[Driver]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/Driver.scala +[Compiler]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/Compiler.scala +[Run]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/Run.scala +[Context]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/core/Contexts.scala diff --git a/docs/_docs/internals/periods.md b/docs/_docs/internals/periods.md index 46241da0bb17..bf9c4a5fe786 100644 --- a/docs/_docs/internals/periods.md +++ b/docs/_docs/internals/periods.md @@ -88,6 +88,6 @@ object Period { As a sentinel value there's `Nowhere`, a period that is empty. -[runs]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/Run.scala -[phases]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Phases.scala -[period]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Periods.scala +[runs]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/Run.scala +[phases]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Phases.scala +[period]: https://github.com/scala/scala3/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Periods.scala diff --git a/docs/_docs/internals/type-system.md b/docs/_docs/internals/type-system.md index 8fa8912a7118..d2c0cd869e61 100644 --- a/docs/_docs/internals/type-system.md +++ b/docs/_docs/internals/type-system.md @@ -95,7 +95,7 @@ checks if `tp1` is a subtype of `tp2`. ### Type rebasing ### **FIXME**: This section is no longer accurate because -https://github.com/lampepfl/dotty/pull/331 changed the handling of refined +https://github.com/scala/scala3/pull/331 changed the handling of refined types. Consider [tests/pos/refinedSubtyping.scala][5] @@ -132,8 +132,8 @@ TODO ## Type inference via constraint solving ## TODO -[1]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/core/Types.scala +[1]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/core/Types.scala [2]: https://github.com/samuelgruetter/dotty/blob/classdiagrampdf/dotty-types.pdf [3]: https://github.com/samuelgruetter/scaladiagrams/tree/print-descendants -[4]: https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/core/TypeComparer.scala -[5]: https://github.com/lampepfl/dotty/blob/main/tests/pos/refinedSubtyping.scala +[4]: https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +[5]: https://github.com/scala/scala3/blob/main/tests/pos/refinedSubtyping.scala diff --git a/docs/_docs/reference/changed-features/eta-expansion-spec.md b/docs/_docs/reference/changed-features/eta-expansion-spec.md index 714ab37ae11a..516764ef5370 100644 --- a/docs/_docs/reference/changed-features/eta-expansion-spec.md +++ b/docs/_docs/reference/changed-features/eta-expansion-spec.md @@ -74,4 +74,4 @@ The method value syntax `m _` is deprecated. ## Reference -For more information, see [PR #2701](https://github.com/lampepfl/dotty/pull/2701). +For more information, see [PR #2701](https://github.com/scala/scala3/pull/2701). diff --git a/docs/_docs/reference/changed-features/implicit-conversions-spec.md b/docs/_docs/reference/changed-features/implicit-conversions-spec.md index dc19e10c8b8f..a70321b70c15 100644 --- a/docs/_docs/reference/changed-features/implicit-conversions-spec.md +++ b/docs/_docs/reference/changed-features/implicit-conversions-spec.md @@ -114,4 +114,4 @@ changes to implicit resolution, refer to the [Changes in Implicit Resolution](im ## Reference For more information about implicit resolution, see [Changes in Implicit Resolution](implicit-resolution.md). -Other details are available in [PR #2065](https://github.com/lampepfl/dotty/pull/2065). +Other details are available in [PR #2065](https://github.com/scala/scala3/pull/2065). diff --git a/docs/_docs/reference/changed-features/structural-types-spec.md b/docs/_docs/reference/changed-features/structural-types-spec.md index 18d0f31ee6fe..216b738ae61c 100644 --- a/docs/_docs/reference/changed-features/structural-types-spec.md +++ b/docs/_docs/reference/changed-features/structural-types-spec.md @@ -16,7 +16,7 @@ RefineStat ::= ‘val’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl ## Implementation of Structural Types The standard library defines a universal marker trait -[`scala.Selectable`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/Selectable.scala): +[`scala.Selectable`](https://github.com/scala/scala3/blob/main/library/src/scala/Selectable.scala): ```scala trait Selectable extends Any @@ -150,4 +150,4 @@ conversion that can turn `v` into a `Selectable`, and the selection methods coul ## Context -For more information, see [Rethink Structural Types](https://github.com/lampepfl/dotty/issues/1886). +For more information, see [Rethink Structural Types](https://github.com/scala/scala3/issues/1886). diff --git a/docs/_docs/reference/contextual/by-name-context-parameters.md b/docs/_docs/reference/contextual/by-name-context-parameters.md index 3515efd78fa5..7c517abe9406 100644 --- a/docs/_docs/reference/contextual/by-name-context-parameters.md +++ b/docs/_docs/reference/contextual/by-name-context-parameters.md @@ -61,5 +61,5 @@ No local given instance was generated because the synthesized argument is not re ## Reference -For more information, see [Issue #1998](https://github.com/lampepfl/dotty/issues/1998) +For more information, see [Issue #1998](https://github.com/scala/scala3/issues/1998) and the associated [Scala SIP](https://docs.scala-lang.org/sips/byname-implicits.html). diff --git a/docs/_docs/reference/contextual/multiversal-equality.md b/docs/_docs/reference/contextual/multiversal-equality.md index b51d03b10963..6258973c0cda 100644 --- a/docs/_docs/reference/contextual/multiversal-equality.md +++ b/docs/_docs/reference/contextual/multiversal-equality.md @@ -25,7 +25,7 @@ the program will still typecheck, since values of all types can be compared with But it will probably give unexpected results and fail at runtime. Multiversal equality is an opt-in way to make universal equality safer. -It uses a binary type class [`scala.CanEqual`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/CanEqual.scala) +It uses a binary type class [`scala.CanEqual`](https://github.com/scala/scala3/blob/main/library/src/scala/CanEqual.scala) to indicate that values of two given types can be compared with each other. The example above would not typecheck if `S` or `T` was a class that derives `CanEqual`, e.g. @@ -71,7 +71,7 @@ given CanEqual[A, B] = CanEqual.derived given CanEqual[B, A] = CanEqual.derived ``` -The [`scala.CanEqual`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/CanEqual.scala) +The [`scala.CanEqual`](https://github.com/scala/scala3/blob/main/library/src/scala/CanEqual.scala) object defines a number of `CanEqual` given instances that together define a rule book for what standard types can be compared (more details below). @@ -225,4 +225,4 @@ work under `-language:strictEquality`, since otherwise the universal `Eq[Any]` i More on multiversal equality is found in a [blog post](http://www.scala-lang.org/blog/2016/05/06/multiversal-equality.html) -and a [GitHub issue](https://github.com/lampepfl/dotty/issues/1247). +and a [GitHub issue](https://github.com/scala/scala3/issues/1247). diff --git a/docs/_docs/reference/dropped-features/auto-apply.md b/docs/_docs/reference/dropped-features/auto-apply.md index eadfe2f429ea..1a809275d4d0 100644 --- a/docs/_docs/reference/dropped-features/auto-apply.md +++ b/docs/_docs/reference/dropped-features/auto-apply.md @@ -93,4 +93,4 @@ stricter checking. ## Reference -For more information, see [Issue #2570](https://github.com/lampepfl/dotty/issues/2570) and [PR #2716](https://github.com/lampepfl/dotty/pull/2716). +For more information, see [Issue #2570](https://github.com/scala/scala3/issues/2570) and [PR #2716](https://github.com/scala/scala3/pull/2716). diff --git a/docs/_docs/reference/dropped-features/type-projection.md b/docs/_docs/reference/dropped-features/type-projection.md index 08b5ffb34eca..2c3e82ce99b8 100644 --- a/docs/_docs/reference/dropped-features/type-projection.md +++ b/docs/_docs/reference/dropped-features/type-projection.md @@ -9,7 +9,7 @@ and `A` names a type member of `T`. Scala 3 disallows this if `T` is an abstract type (class types and type aliases are fine). This change was made because unrestricted type projection -is [unsound](https://github.com/lampepfl/dotty/issues/1050). +is [unsound](https://github.com/scala/scala3/issues/1050). This restriction rules out the [type-level encoding of a combinator calculus](https://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/). diff --git a/docs/_docs/reference/enums/adts.md b/docs/_docs/reference/enums/adts.md index 5219e062a633..36dd1daf0b59 100644 --- a/docs/_docs/reference/enums/adts.md +++ b/docs/_docs/reference/enums/adts.md @@ -170,4 +170,4 @@ The changes are specified below as deltas with respect to the Scala syntax given ## Reference -For more information, see [Issue #1970](https://github.com/lampepfl/dotty/issues/1970). +For more information, see [Issue #1970](https://github.com/scala/scala3/issues/1970). diff --git a/docs/_docs/reference/enums/enums.md b/docs/_docs/reference/enums/enums.md index 65051bdfb39f..8d4fca3268b0 100644 --- a/docs/_docs/reference/enums/enums.md +++ b/docs/_docs/reference/enums/enums.md @@ -180,7 +180,7 @@ scala> Color.Red.compareTo(Color.Green) val res15: Int = -1 ``` -For a more in-depth example of using Scala 3 enums from Java, see [this test](https://github.com/lampepfl/dotty/tree/main/tests/run/enum-java). In the test, the enums are defined in the `MainScala.scala` file and used from a Java source, `Test.java`. +For a more in-depth example of using Scala 3 enums from Java, see [this test](https://github.com/scala/scala3/tree/main/tests/run/enum-java). In the test, the enums are defined in the `MainScala.scala` file and used from a Java source, `Test.java`. ## Implementation @@ -218,5 +218,5 @@ val Red: Color = $new(0, "Red") ## Reference -For more information, see [Issue #1970](https://github.com/lampepfl/dotty/issues/1970) and -[PR #4003](https://github.com/lampepfl/dotty/pull/4003). +For more information, see [Issue #1970](https://github.com/scala/scala3/issues/1970) and +[PR #4003](https://github.com/scala/scala3/pull/4003). diff --git a/docs/_docs/reference/experimental/explicit-nulls.md b/docs/_docs/reference/experimental/explicit-nulls.md index f8f9ac8e11be..1925b0b3c925 100644 --- a/docs/_docs/reference/experimental/explicit-nulls.md +++ b/docs/_docs/reference/experimental/explicit-nulls.md @@ -1,7 +1,7 @@ --- layout: doc-page title: "Explicit Nulls" -nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/explicit-nulls.html +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/explicit-nulls.html --- Explicit nulls is an opt-in feature that modifies the Scala type system, which makes reference types @@ -431,7 +431,7 @@ When dealing with local mutable variables, there are two questions: x = null ``` -See [more examples](https://github.com/lampepfl/dotty/blob/main/tests/explicit-nulls/neg/flow-varref-in-closure.scala). +See [more examples](https://github.com/scala/scala3/blob/main/tests/explicit-nulls/neg/flow-varref-in-closure.scala). Currently, we are unable to track paths with a mutable variable prefix. For example, `x.a` if `x` is mutable. diff --git a/docs/_docs/reference/experimental/tupled-function.md b/docs/_docs/reference/experimental/tupled-function.md index 0cc016953a80..de683128fb0c 100644 --- a/docs/_docs/reference/experimental/tupled-function.md +++ b/docs/_docs/reference/experimental/tupled-function.md @@ -35,7 +35,7 @@ The compiler will synthesize an instance of `TupledFunction[F, G]` if: Examples -------- `TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities. -The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-tupled.scala)). +The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-tupled.scala)). ```scala /** Creates a tupled version of this function: instead of N arguments, @@ -49,7 +49,7 @@ extension [F, Args <: Tuple, R](f: F) def tupled(using tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) ``` -`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-untupled.scala)) +`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-untupled.scala)) ```scala /** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements, @@ -65,7 +65,7 @@ extension [F, Args <: Tuple, R](f: Args => R) def untupled(using tf: TupledFunction[F, Args => R]): F = tf.untupled(f) ``` -`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. +`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. ```scala /** Composes two instances of TupledFunction into a new TupledFunction, with this function applied last. diff --git a/docs/_docs/reference/features-classification.md b/docs/_docs/reference/features-classification.md index 36cea3b9e72d..550130780b44 100644 --- a/docs/_docs/reference/features-classification.md +++ b/docs/_docs/reference/features-classification.md @@ -72,7 +72,7 @@ These constructs are restricted to make the language safer. - [Given Imports](contextual/given-imports.md): implicits now require a special form of import, to make the import clearly visible. - [Type Projection](dropped-features/type-projection.md): only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound. - [Multiversal equality](contextual/multiversal-equality.md) implements an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`. - - [infix](https://github.com/lampepfl/dotty/pull/5975) + - [infix](https://github.com/scala/scala3/pull/5975) makes method application syntax uniform across code bases. Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other constructs in the list above are available only under `-source 3.0-migration`. @@ -100,7 +100,7 @@ These constructs are proposed to be dropped without a new construct replacing th - [Auto application](dropped-features/auto-apply.md), - [Weak conformance](dropped-features/weak-conformance.md), - [Compound types](new-types/intersection-types.md), - - [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged). + - [Auto tupling](https://github.com/scala/scala3/pull/4311) (implemented, but not merged). The date when these constructs are dropped varies. The current status is: @@ -148,7 +148,7 @@ These are additions to the language that make it more powerful or pleasant to us - [Enums](enums/enums.md) provide concise syntax for enumerations and [algebraic data types](enums/adts.md). - [Parameter untupling](other-new-features/parameter-untupling.md) avoids having to use `case` for tupled parameter destructuring. - [Dependent function types](new-types/dependent-function-types.md) generalize dependent methods to dependent function values and types. - - [Polymorphic function types](https://github.com/lampepfl/dotty/pull/4672) generalize polymorphic methods to dependent function values and types. _Current status_: There is a proposal, and a prototype implementation, but the implementation has not been finalized or merged yet. + - [Polymorphic function types](https://github.com/scala/scala3/pull/4672) generalize polymorphic methods to dependent function values and types. _Current status_: There is a proposal, and a prototype implementation, but the implementation has not been finalized or merged yet. - [Kind polymorphism](other-new-features/kind-polymorphism.md) allows the definition of operators working equally on types and type constructors. **Status: mixed** diff --git a/docs/_docs/reference/metaprogramming/compiletime-ops.md b/docs/_docs/reference/metaprogramming/compiletime-ops.md index 048c6b6165bb..dcefb3a16ed3 100644 --- a/docs/_docs/reference/metaprogramming/compiletime-ops.md +++ b/docs/_docs/reference/metaprogramming/compiletime-ops.md @@ -259,5 +259,5 @@ val notMissing : NotMissing = summonInlineCheck(3) ## Reference -For more information about compile-time operations, see [PR #4768](https://github.com/lampepfl/dotty/pull/4768), -which explains how `summonFrom`'s predecessor (implicit matches) can be used for typelevel programming and code specialization and [PR #7201](https://github.com/lampepfl/dotty/pull/7201) which explains the new `summonFrom` syntax. +For more information about compile-time operations, see [PR #4768](https://github.com/scala/scala3/pull/4768), +which explains how `summonFrom`'s predecessor (implicit matches) can be used for typelevel programming and code specialization and [PR #7201](https://github.com/scala/scala3/pull/7201) which explains the new `summonFrom` syntax. diff --git a/docs/_docs/reference/metaprogramming/macros.md b/docs/_docs/reference/metaprogramming/macros.md index 5bfaa167a12f..b63616185285 100644 --- a/docs/_docs/reference/metaprogramming/macros.md +++ b/docs/_docs/reference/metaprogramming/macros.md @@ -452,10 +452,10 @@ The lambda arguments will replace the variables that might have been extruded. ```scala '{ ((x: Int) => x + 1).apply(2) } match - case '{ ((y: Int) => $f(y)).apply($z: Int) } => + case '{ ((y: Int) => $f(y): Int).apply($z: Int) } => // f may contain references to `x` (replaced by `$y`) - // f = (y: Expr[Int]) => '{ $y + 1 } - f(z) // generates '{ 2 + 1 } + // f = '{ (y: Int) => $y + 1 } + Expr.betaReduce('{ $f($z)}) // generates '{ 2 + 1 } ``` diff --git a/docs/_docs/reference/new-types/dependent-function-types-spec.md b/docs/_docs/reference/new-types/dependent-function-types-spec.md index f603200b1ae0..3084ff4de71c 100644 --- a/docs/_docs/reference/new-types/dependent-function-types-spec.md +++ b/docs/_docs/reference/new-types/dependent-function-types-spec.md @@ -4,7 +4,7 @@ title: "Dependent Function Types - More Details" nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/dependent-function-types-spec.html --- -Initial implementation in [PR #3464](https://github.com/lampepfl/dotty/pull/3464). +Initial implementation in [PR #3464](https://github.com/scala/scala3/pull/3464). ## Syntax @@ -46,7 +46,7 @@ same way that other functions do, see The example below defines a trait `C` and the two dependent function types `DF` and `IDF` and prints the results of the respective function applications: -[depfuntype.scala]: https://github.com/lampepfl/dotty/blob/main/tests/pos/depfuntype.scala +[depfuntype.scala]: https://github.com/scala/scala3/blob/main/tests/pos/depfuntype.scala ```scala trait C { type M; val m: M } @@ -70,7 +70,7 @@ type IDF = (x: C) ?=> x.M In the following example the depend type `f.Eff` refers to the effect type `CanThrow`: -[eff-dependent.scala]: https://github.com/lampepfl/dotty/blob/main/tests/run/eff-dependent.scala +[eff-dependent.scala]: https://github.com/scala/scala3/blob/main/tests/run/eff-dependent.scala ```scala trait Effect diff --git a/docs/_docs/reference/new-types/intersection-types-spec.md b/docs/_docs/reference/new-types/intersection-types-spec.md index 4e26626c0b36..723720fdef89 100644 --- a/docs/_docs/reference/new-types/intersection-types-spec.md +++ b/docs/_docs/reference/new-types/intersection-types-spec.md @@ -97,7 +97,7 @@ glb(A, _) = A // use first In the above, `|T|` means the erased type of `T`, `JArray` refers to the type of Java Array. -See also: [`TypeErasure#erasedGlb`](https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/core/TypeErasure.scala#L289). +See also: [`TypeErasure#erasedGlb`](https://github.com/scala/scala3/blob/main/compiler/src/dotty/tools/dotc/core/TypeErasure.scala#L289). ## Relationship with Compound Type (`with`) diff --git a/docs/_docs/reference/new-types/polymorphic-function-types.md b/docs/_docs/reference/new-types/polymorphic-function-types.md index 1754bf844831..04f4a3483896 100644 --- a/docs/_docs/reference/new-types/polymorphic-function-types.md +++ b/docs/_docs/reference/new-types/polymorphic-function-types.md @@ -33,7 +33,7 @@ In Scala 3 this is now possible. The type of the `bar` value above is This type describes function values which take a type `A` as a parameter, then take a list of type `List[A]`, and return a list of the same type `List[A]`. -[More details](https://github.com/lampepfl/dotty/pull/4672) +[More details](https://github.com/scala/scala3/pull/4672) ## Example Usage diff --git a/docs/_docs/reference/other-new-features/open-classes.md b/docs/_docs/reference/other-new-features/open-classes.md index 10af6ead669e..ff2dbac27b3b 100644 --- a/docs/_docs/reference/other-new-features/open-classes.md +++ b/docs/_docs/reference/other-new-features/open-classes.md @@ -77,4 +77,4 @@ A class that is neither `abstract` nor `open` is similar to a `sealed` class: it ## Migration -`open` is a new modifier in Scala 3. To allow cross compilation between Scala 2.13 and Scala 3.0 without warnings, the feature warning for ad-hoc extensions is produced only under `-source future`. It will be produced by default [from Scala 3.4 on](https://github.com/lampepfl/dotty/issues/16334). +`open` is a new modifier in Scala 3. To allow cross compilation between Scala 2.13 and Scala 3.0 without warnings, the feature warning for ad-hoc extensions is produced only under `-source future`. It will be produced by default [from Scala 3.4 on](https://github.com/scala/scala3/issues/16334). diff --git a/docs/_docs/reference/other-new-features/parameter-untupling-spec.md b/docs/_docs/reference/other-new-features/parameter-untupling-spec.md index fd462dd610c8..c9e1033f5ea6 100644 --- a/docs/_docs/reference/other-new-features/parameter-untupling-spec.md +++ b/docs/_docs/reference/other-new-features/parameter-untupling-spec.md @@ -56,4 +56,4 @@ Obsolete conversions could be detected and fixed by [`Scalafix`](https://scalace ## Reference -For more information, see [Issue #897](https://github.com/lampepfl/dotty/issues/897). +For more information, see [Issue #897](https://github.com/scala/scala3/issues/897). diff --git a/docs/_docs/reference/other-new-features/parameter-untupling.md b/docs/_docs/reference/other-new-features/parameter-untupling.md index e1e7afcad8fe..27e3850b309c 100644 --- a/docs/_docs/reference/other-new-features/parameter-untupling.md +++ b/docs/_docs/reference/other-new-features/parameter-untupling.md @@ -75,4 +75,4 @@ cannot subvert untupling. For more information see: * [More details](./parameter-untupling-spec.md) -* [Issue #897](https://github.com/lampepfl/dotty/issues/897). +* [Issue #897](https://github.com/scala/scala3/issues/897). diff --git a/docs/_docs/reference/overview.md b/docs/_docs/reference/overview.md index b1e8281dfc16..bdb8aa74c1aa 100644 --- a/docs/_docs/reference/overview.md +++ b/docs/_docs/reference/overview.md @@ -91,7 +91,7 @@ These constructs are proposed to be dropped without a new construct replacing th - [Auto application](dropped-features/auto-apply.md), - [Weak conformance](dropped-features/weak-conformance.md), - Compound types (replaced by [Intersection types](new-types/intersection-types.md)), -- [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged). +- [Auto tupling](https://github.com/scala/scala3/pull/4311) (implemented, but not merged). The date when these constructs are dropped varies. The current status is: diff --git a/docs/_docs/release-notes-0.1.2.md b/docs/_docs/release-notes-0.1.2.md index 98f359c83a15..c6bc9846bf07 100644 --- a/docs/_docs/release-notes-0.1.2.md +++ b/docs/_docs/release-notes-0.1.2.md @@ -18,7 +18,7 @@ Dotty 0.1.2 targets Java 8. We don't have plans to add support for earlier versi # Reporting Bugs / Known Issues -Please [file](https://github.com/lampepfl/dotty/issues) any bugs you encounter. If you’re unsure whether something is a bug, +Please [file](https://github.com/scala/scala3/issues) any bugs you encounter. If you’re unsure whether something is a bug, please ask on the Dotty [gitter channel](https://github.com/lampepfl/dotty). # Dotty Doc @@ -86,27 +86,27 @@ This release ships with the following features: [9]: http://docs.scala-lang.org/sips/pending/static-members.html [10]: http://docs.scala-lang.org/sips/pending/improved-lazy-val-initialization.html [11]: http://magarciaepfl.github.io/scala/ -[12]: https://github.com/lampepfl/dotty/commit/b2215ed23311b2c99ea638f9d7fcad9737dba588 -[13]: https://github.com/lampepfl/dotty/pull/187 -[14]: https://github.com/lampepfl/dotty/pull/217 +[12]: https://github.com/scala/scala3/commit/b2215ed23311b2c99ea638f9d7fcad9737dba588 +[13]: https://github.com/scala/scala3/pull/187 +[14]: https://github.com/scala/scala3/pull/217 [15]: reference/other-new-features/trait-parameters.html -[16]: https://github.com/lampepfl/dotty/commit/89540268e6c49fb92b9ca61249e46bb59981bf5a -[17]: https://github.com/lampepfl/dotty/pull/174 -[18]: https://github.com/lampepfl/dotty/pull/488 -[19]: https://github.com/lampepfl/dotty/pull/174 -[20]: https://github.com/lampepfl/dotty/pull/411 -[21]: https://github.com/lampepfl/dotty/pull/1364 -[22]: https://github.com/lampepfl/dotty/pull/1227 -[23]: https://github.com/lampepfl/dotty/pull/117 -[24]: https://github.com/lampepfl/dotty/pull/2532 -[25]: https://github.com/lampepfl/dotty/pull/2194 -[26]: https://github.com/lampepfl/dotty/pull/213 -[27]: https://github.com/lampepfl/dotty/pull/2513 -[28]: https://github.com/lampepfl/dotty/pull/2361 -[29]: https://github.com/lampepfl/dotty/pull/1453 +[16]: https://github.com/scala/scala3/commit/89540268e6c49fb92b9ca61249e46bb59981bf5a +[17]: https://github.com/scala/scala3/pull/174 +[18]: https://github.com/scala/scala3/pull/488 +[19]: https://github.com/scala/scala3/pull/174 +[20]: https://github.com/scala/scala3/pull/411 +[21]: https://github.com/scala/scala3/pull/1364 +[22]: https://github.com/scala/scala3/pull/1227 +[23]: https://github.com/scala/scala3/pull/117 +[24]: https://github.com/scala/scala3/pull/2532 +[25]: https://github.com/scala/scala3/pull/2194 +[26]: https://github.com/scala/scala3/pull/213 +[27]: https://github.com/scala/scala3/pull/2513 +[28]: https://github.com/scala/scala3/pull/2361 +[29]: https://github.com/scala/scala3/pull/1453 [30]: reference/contextual/context-functions.html -[31]: https://github.com/lampepfl/dotty/pull/2136 -[32]: https://github.com/lampepfl/dotty/pull/1758 +[31]: https://github.com/scala/scala3/pull/2136 +[32]: https://github.com/scala/scala3/pull/1758 [33]: reference/metaprogramming/inline.html # Contributors diff --git a/docs/_spec/APPLIEDreference/dropped-features/auto-apply.md b/docs/_spec/APPLIEDreference/dropped-features/auto-apply.md index b9aedb9f046b..95366b5e8f78 100644 --- a/docs/_spec/APPLIEDreference/dropped-features/auto-apply.md +++ b/docs/_spec/APPLIEDreference/dropped-features/auto-apply.md @@ -93,4 +93,4 @@ stricter checking. ## Reference -For more information, see [Issue #2570](https://github.com/lampepfl/dotty/issues/2570) and [PR #2716](https://github.com/lampepfl/dotty/pull/2716). +For more information, see [Issue #2570](https://github.com/scala/scala3/issues/2570) and [PR #2716](https://github.com/scala/scala3/pull/2716). diff --git a/docs/_spec/APPLIEDreference/dropped-features/this-qualifier.md b/docs/_spec/APPLIEDreference/dropped-features/this-qualifier.md index 3fcaefb7e0d8..9eb0a77e2b69 100644 --- a/docs/_spec/APPLIEDreference/dropped-features/this-qualifier.md +++ b/docs/_spec/APPLIEDreference/dropped-features/this-qualifier.md @@ -4,7 +4,7 @@ title: "Dropped: private[this] and protected[this]" nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/this-qualifier.html --- -The `private[this]` and `protected[this]` access modifiers will be deprecated and phased out. +The `private[this]` and `protected[this]` access modifiers will be deprecated and phased out. Migration warning will be shown in Scala 3.4+. Previously, these modifiers were needed for diff --git a/docs/_spec/APPLIEDreference/enums/enums.md b/docs/_spec/APPLIEDreference/enums/enums.md index bcab50d3a36d..d8fdbe9f1db2 100644 --- a/docs/_spec/APPLIEDreference/enums/enums.md +++ b/docs/_spec/APPLIEDreference/enums/enums.md @@ -178,5 +178,5 @@ scala> Color.Red.compareTo(Color.Green) val res15: Int = -1 ``` -For a more in-depth example of using Scala 3 enums from Java, see [this test](https://github.com/lampepfl/dotty/tree/main/tests/run/enum-java). +For a more in-depth example of using Scala 3 enums from Java, see [this test](https://github.com/scala/scala3/tree/main/tests/run/enum-java). In the test, the enums are defined in the `MainScala.scala` file and used from a Java source, `Test.java`. diff --git a/docs/_spec/APPLIEDreference/new-types/union-types.md b/docs/_spec/APPLIEDreference/new-types/union-types.md index 152505d7fc8d..f59bb6f6b851 100644 --- a/docs/_spec/APPLIEDreference/new-types/union-types.md +++ b/docs/_spec/APPLIEDreference/new-types/union-types.md @@ -59,8 +59,8 @@ be changed in the future. For example by not widening unions that have been explicitly written down by the user and not inferred, or by not widening a type argument when the corresponding type parameter is covariant. -See [PR #2330](https://github.com/lampepfl/dotty/pull/2330) and -[Issue #4867](https://github.com/lampepfl/dotty/issues/4867) for further discussions. +See [PR #2330](https://github.com/scala/scala3/pull/2330) and +[Issue #4867](https://github.com/scala/scala3/issues/4867) for further discussions. ### Example diff --git a/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md b/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md index a62d45df9e11..fa5c1e57a066 100644 --- a/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md +++ b/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md @@ -74,4 +74,4 @@ The method value syntax `m _` is deprecated. ## Reference -For more information, see [PR #2701](https://github.com/lampepfl/dotty/pull/2701). +For more information, see [PR #2701](https://github.com/scala/scala3/pull/2701). diff --git a/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md b/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md index dc19e10c8b8f..a70321b70c15 100644 --- a/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md +++ b/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md @@ -114,4 +114,4 @@ changes to implicit resolution, refer to the [Changes in Implicit Resolution](im ## Reference For more information about implicit resolution, see [Changes in Implicit Resolution](implicit-resolution.md). -Other details are available in [PR #2065](https://github.com/lampepfl/dotty/pull/2065). +Other details are available in [PR #2065](https://github.com/scala/scala3/pull/2065). diff --git a/docs/_spec/TODOreference/changed-features/structural-types-spec.md b/docs/_spec/TODOreference/changed-features/structural-types-spec.md index d456932649fb..cb48a593e831 100644 --- a/docs/_spec/TODOreference/changed-features/structural-types-spec.md +++ b/docs/_spec/TODOreference/changed-features/structural-types-spec.md @@ -16,7 +16,7 @@ RefineStat ::= ‘val’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl ## Implementation of Structural Types The standard library defines a universal marker trait -[`scala.Selectable`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/Selectable.scala): +[`scala.Selectable`](https://github.com/scala/scala3/blob/main/library/src/scala/Selectable.scala): ```scala trait Selectable extends Any @@ -150,4 +150,4 @@ conversion that can turn `v` into a `Selectable`, and the selection methods coul ## Context -For more information, see [Rethink Structural Types](https://github.com/lampepfl/dotty/issues/1886). +For more information, see [Rethink Structural Types](https://github.com/scala/scala3/issues/1886). diff --git a/docs/_spec/TODOreference/contextual/by-name-context-parameters.md b/docs/_spec/TODOreference/contextual/by-name-context-parameters.md index 3004bfb2c4c2..7a80b20592ea 100644 --- a/docs/_spec/TODOreference/contextual/by-name-context-parameters.md +++ b/docs/_spec/TODOreference/contextual/by-name-context-parameters.md @@ -61,5 +61,5 @@ No local given instance was generated because the synthesized argument is not re ## Reference -For more information, see [Issue #1998](https://github.com/lampepfl/dotty/issues/1998) +For more information, see [Issue #1998](https://github.com/scala/scala3/issues/1998) and the associated [Scala SIP](https://docs.scala-lang.org/sips/byname-implicits.html). diff --git a/docs/_spec/TODOreference/contextual/multiversal-equality.md b/docs/_spec/TODOreference/contextual/multiversal-equality.md index e9a81b95f472..fa729fda8e61 100644 --- a/docs/_spec/TODOreference/contextual/multiversal-equality.md +++ b/docs/_spec/TODOreference/contextual/multiversal-equality.md @@ -25,7 +25,7 @@ the program will still typecheck, since values of all types can be compared with But it will probably give unexpected results and fail at runtime. Multiversal equality is an opt-in way to make universal equality safer. -It uses a binary type class [`scala.CanEqual`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/CanEqual.scala) +It uses a binary type class [`scala.CanEqual`](https://github.com/scala/scala3/blob/main/library/src/scala/CanEqual.scala) to indicate that values of two given types can be compared with each other. The example above would not typecheck if `S` or `T` was a class that derives `CanEqual`, e.g. @@ -70,7 +70,7 @@ given CanEqual[A, B] = CanEqual.derived given CanEqual[B, A] = CanEqual.derived ``` -The [`scala.CanEqual`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/CanEqual.scala) +The [`scala.CanEqual`](https://github.com/scala/scala3/blob/main/library/src/scala/CanEqual.scala) object defines a number of `CanEqual` given instances that together define a rule book for what standard types can be compared (more details below). @@ -224,4 +224,4 @@ work under `-language:strictEquality`, since otherwise the universal `Eq[Any]` i More on multiversal equality is found in a [blog post](http://www.scala-lang.org/blog/2016/05/06/multiversal-equality.html) -and a [GitHub issue](https://github.com/lampepfl/dotty/issues/1247). +and a [GitHub issue](https://github.com/scala/scala3/issues/1247). diff --git a/docs/_spec/TODOreference/dropped-features/type-projection.md b/docs/_spec/TODOreference/dropped-features/type-projection.md index 08b5ffb34eca..2c3e82ce99b8 100644 --- a/docs/_spec/TODOreference/dropped-features/type-projection.md +++ b/docs/_spec/TODOreference/dropped-features/type-projection.md @@ -9,7 +9,7 @@ and `A` names a type member of `T`. Scala 3 disallows this if `T` is an abstract type (class types and type aliases are fine). This change was made because unrestricted type projection -is [unsound](https://github.com/lampepfl/dotty/issues/1050). +is [unsound](https://github.com/scala/scala3/issues/1050). This restriction rules out the [type-level encoding of a combinator calculus](https://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/). diff --git a/docs/_spec/TODOreference/experimental/explicit-nulls.md b/docs/_spec/TODOreference/experimental/explicit-nulls.md index b3fa53429cfe..3be83afe967e 100644 --- a/docs/_spec/TODOreference/experimental/explicit-nulls.md +++ b/docs/_spec/TODOreference/experimental/explicit-nulls.md @@ -431,7 +431,7 @@ When dealing with local mutable variables, there are two questions: x = null ``` -See [more examples](https://github.com/lampepfl/dotty/blob/main/tests/explicit-nulls/neg/flow-varref-in-closure.scala). +See [more examples](https://github.com/scala/scala3/blob/main/tests/explicit-nulls/neg/flow-varref-in-closure.scala). Currently, we are unable to track paths with a mutable variable prefix. For example, `x.a` if `x` is mutable. diff --git a/docs/_spec/TODOreference/experimental/tupled-function.md b/docs/_spec/TODOreference/experimental/tupled-function.md index da108fc832ad..e01570e9e8a6 100644 --- a/docs/_spec/TODOreference/experimental/tupled-function.md +++ b/docs/_spec/TODOreference/experimental/tupled-function.md @@ -34,7 +34,7 @@ The compiler will synthesize an instance of `TupledFunction[F, G]` if: Examples -------- `TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities. -The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-tupled.scala)). +The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-tupled.scala)). ```scala /** Creates a tupled version of this function: instead of N arguments, @@ -48,7 +48,7 @@ extension [F, Args <: Tuple, R](f: F) def tupled(using tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) ``` -`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-untupled.scala)) +`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-untupled.scala)) ```scala /** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements, @@ -64,7 +64,7 @@ extension [F, Args <: Tuple, R](f: Args => R) def untupled(using tf: TupledFunction[F, Args => R]): F = tf.untupled(f) ``` -`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. +`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/scala/scala3/blob/main/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. ```scala /** Composes two instances of TupledFunction into a new TupledFunction, with this function applied last. diff --git a/docs/_spec/TODOreference/features-classification.md b/docs/_spec/TODOreference/features-classification.md index 36cea3b9e72d..550130780b44 100644 --- a/docs/_spec/TODOreference/features-classification.md +++ b/docs/_spec/TODOreference/features-classification.md @@ -72,7 +72,7 @@ These constructs are restricted to make the language safer. - [Given Imports](contextual/given-imports.md): implicits now require a special form of import, to make the import clearly visible. - [Type Projection](dropped-features/type-projection.md): only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound. - [Multiversal equality](contextual/multiversal-equality.md) implements an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`. - - [infix](https://github.com/lampepfl/dotty/pull/5975) + - [infix](https://github.com/scala/scala3/pull/5975) makes method application syntax uniform across code bases. Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other constructs in the list above are available only under `-source 3.0-migration`. @@ -100,7 +100,7 @@ These constructs are proposed to be dropped without a new construct replacing th - [Auto application](dropped-features/auto-apply.md), - [Weak conformance](dropped-features/weak-conformance.md), - [Compound types](new-types/intersection-types.md), - - [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged). + - [Auto tupling](https://github.com/scala/scala3/pull/4311) (implemented, but not merged). The date when these constructs are dropped varies. The current status is: @@ -148,7 +148,7 @@ These are additions to the language that make it more powerful or pleasant to us - [Enums](enums/enums.md) provide concise syntax for enumerations and [algebraic data types](enums/adts.md). - [Parameter untupling](other-new-features/parameter-untupling.md) avoids having to use `case` for tupled parameter destructuring. - [Dependent function types](new-types/dependent-function-types.md) generalize dependent methods to dependent function values and types. - - [Polymorphic function types](https://github.com/lampepfl/dotty/pull/4672) generalize polymorphic methods to dependent function values and types. _Current status_: There is a proposal, and a prototype implementation, but the implementation has not been finalized or merged yet. + - [Polymorphic function types](https://github.com/scala/scala3/pull/4672) generalize polymorphic methods to dependent function values and types. _Current status_: There is a proposal, and a prototype implementation, but the implementation has not been finalized or merged yet. - [Kind polymorphism](other-new-features/kind-polymorphism.md) allows the definition of operators working equally on types and type constructors. **Status: mixed** diff --git a/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md b/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md index a43c941ae943..782cd72886d5 100644 --- a/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md +++ b/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md @@ -290,5 +290,5 @@ val notMissing : NotMissing = summonInlineCheck(3) ## Reference -For more information about compile-time operations, see [PR #4768](https://github.com/lampepfl/dotty/pull/4768), -which explains how `summonFrom`'s predecessor (implicit matches) can be used for typelevel programming and code specialization and [PR #7201](https://github.com/lampepfl/dotty/pull/7201) which explains the new `summonFrom` syntax. +For more information about compile-time operations, see [PR #4768](https://github.com/scala/scala3/pull/4768), +which explains how `summonFrom`'s predecessor (implicit matches) can be used for typelevel programming and code specialization and [PR #7201](https://github.com/scala/scala3/pull/7201) which explains the new `summonFrom` syntax. diff --git a/docs/_spec/TODOreference/metaprogramming/staging.md b/docs/_spec/TODOreference/metaprogramming/staging.md index 6d9166e8249e..073012761513 100644 --- a/docs/_spec/TODOreference/metaprogramming/staging.md +++ b/docs/_spec/TODOreference/metaprogramming/staging.md @@ -108,7 +108,11 @@ to get a source-like representation of the expression. import scala.quoted.* // make available the necessary compiler for runtime code generation -given staging.Compiler = staging.Compiler.make(getClass.getClassLoader) +given staging.Compiler = + // We need an instance of a class that is defined in the current application (not the standard library) + // `this` can be used instead of an instance of `Dummy` if the Compiler is instantiated within one of the application classes. + object Dummy + staging.Compiler.make(Dummy.getClass.getClassLoader) val f: Array[Int] => Int = staging.run { val stagedSum: Expr[Array[Int] => Int] = diff --git a/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md b/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md index f3237ddf7b9a..b27346a687d6 100644 --- a/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md +++ b/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md @@ -4,7 +4,7 @@ title: "Dependent Function Types - More Details" nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/dependent-function-types-spec.html --- -Initial implementation in [PR #3464](https://github.com/lampepfl/dotty/pull/3464). +Initial implementation in [PR #3464](https://github.com/scala/scala3/pull/3464). ## Syntax @@ -46,7 +46,7 @@ same way that other functions do, see The example below defines a trait `C` and the two dependent function types `DF` and `IDF` and prints the results of the respective function applications: -[depfuntype.scala]: https://github.com/lampepfl/dotty/blob/main/tests/pos/depfuntype.scala +[depfuntype.scala]: https://github.com/scala/scala3/blob/main/tests/pos/depfuntype.scala ```scala trait C { type M; val m: M } @@ -70,7 +70,7 @@ type IDF = (x: C) ?=> x.M In the following example the depend type `f.Eff` refers to the effect type `CanThrow`: -[eff-dependent.scala]: https://github.com/lampepfl/dotty/blob/main/tests/run/eff-dependent.scala +[eff-dependent.scala]: https://github.com/scala/scala3/blob/main/tests/run/eff-dependent.scala ```scala trait Effect diff --git a/docs/_spec/TODOreference/new-types/polymorphic-function-types.md b/docs/_spec/TODOreference/new-types/polymorphic-function-types.md index 1754bf844831..04f4a3483896 100644 --- a/docs/_spec/TODOreference/new-types/polymorphic-function-types.md +++ b/docs/_spec/TODOreference/new-types/polymorphic-function-types.md @@ -33,7 +33,7 @@ In Scala 3 this is now possible. The type of the `bar` value above is This type describes function values which take a type `A` as a parameter, then take a list of type `List[A]`, and return a list of the same type `List[A]`. -[More details](https://github.com/lampepfl/dotty/pull/4672) +[More details](https://github.com/scala/scala3/pull/4672) ## Example Usage diff --git a/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md b/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md index e5165550fc0d..6133012463a1 100644 --- a/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md +++ b/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md @@ -86,4 +86,4 @@ Obsolete conversions could be detected and fixed by [`Scalafix`](https://scalace ## Reference -For more information, see [Issue #897](https://github.com/lampepfl/dotty/issues/897). +For more information, see [Issue #897](https://github.com/scala/scala3/issues/897). diff --git a/docs/_spec/TODOreference/other-new-features/parameter-untupling.md b/docs/_spec/TODOreference/other-new-features/parameter-untupling.md index fcc1fa11d519..09806fc169eb 100644 --- a/docs/_spec/TODOreference/other-new-features/parameter-untupling.md +++ b/docs/_spec/TODOreference/other-new-features/parameter-untupling.md @@ -74,4 +74,4 @@ cannot subvert untupling. For more information see: * [More details](./parameter-untupling-spec.md) -* [Issue #897](https://github.com/lampepfl/dotty/issues/897). +* [Issue #897](https://github.com/scala/scala3/issues/897). diff --git a/docs/_spec/TODOreference/overview.md b/docs/_spec/TODOreference/overview.md index b1e8281dfc16..bdb8aa74c1aa 100644 --- a/docs/_spec/TODOreference/overview.md +++ b/docs/_spec/TODOreference/overview.md @@ -91,7 +91,7 @@ These constructs are proposed to be dropped without a new construct replacing th - [Auto application](dropped-features/auto-apply.md), - [Weak conformance](dropped-features/weak-conformance.md), - Compound types (replaced by [Intersection types](new-types/intersection-types.md)), -- [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged). +- [Auto tupling](https://github.com/scala/scala3/pull/4311) (implemented, but not merged). The date when these constructs are dropped varies. The current status is: diff --git a/docs/_spec/_layouts/default.yml b/docs/_spec/_layouts/default.yml index 5d597cb5ea96..0f7fb24d7ce2 100644 --- a/docs/_spec/_layouts/default.yml +++ b/docs/_spec/_layouts/default.yml @@ -27,7 +27,7 @@ <header class="hidden-print"> <nav id="chapters"> <a href="{{site.baseurl}}/" title="Table of Contents">Scala {{ site.thisScalaVersion }}</a> - <a id="github" href="https://github.com/lampepfl/dotty/tree/main/docs/_spec"><img src="public/images/github-logo@2x.png" alt="Edit at GitHub"></a> + <a id="github" href="https://github.com/scala/scala3/tree/main/docs/_spec"><img src="public/images/github-logo@2x.png" alt="Edit at GitHub"></a> {% assign sorted_pages = site.pages | sort:"name" %} {% for post in sorted_pages %} {% if post.chapter >= 0 %} diff --git a/docs/_spec/_layouts/toc.yml b/docs/_spec/_layouts/toc.yml index 58d2de609d60..cfb407a8af71 100644 --- a/docs/_spec/_layouts/toc.yml +++ b/docs/_spec/_layouts/toc.yml @@ -20,7 +20,7 @@ <div id="header-main"> <img id="scala-logo" src="public/images/scala-spiral-white.png" /> <span id="title">Scala Language Specification</span> - <a id="github" href="https://github.com/lampepfl/dotty/tree/main/docs/_spec"><img src="public/images/github-logo@2x.png" alt="Edit at GitHub"></a> + <a id="github" href="https://github.com/scala/scala3/tree/main/docs/_spec"><img src="public/images/github-logo@2x.png" alt="Edit at GitHub"></a> </div> <div id="header-sub">Version {{ site.thisScalaVersion }}</div> </header> diff --git a/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala b/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala index 903a5ae3b36a..3604e38375e7 100644 --- a/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala +++ b/language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala @@ -552,13 +552,18 @@ class DottyLanguageServer extends LanguageServer override def signatureHelp(params: TextDocumentPositionParams) = computeAsync { canceltoken => val uri = new URI(params.getTextDocument.getUri) val driver = driverFor(uri) - implicit def ctx: Context = driver.currentCtx - val pos = sourcePosition(driver, uri, params.getPosition) - val trees = driver.openedTrees(uri) - val path = Interactive.pathTo(trees, pos) - val (paramN, callableN, signatures) = Signatures.signatureHelp(path, pos.span) - new SignatureHelp(signatures.map(signatureToSignatureInformation).asJava, callableN, paramN) + driver.compilationUnits.get(uri) match + case Some(unit) => + given newCtx: Context = driver.currentCtx.fresh.setCompilationUnit(unit) + val pos = sourcePosition(driver, uri, params.getPosition) + val adjustedSpan = pos.span.withEnd(pos.span.end + 1) + val path = Interactive.pathTo(ctx.compilationUnit.tpdTree, adjustedSpan) + val (paramN, callableN, signatures) = Signatures.signatureHelp(path, adjustedSpan) + + new SignatureHelp(signatures.map(signatureToSignatureInformation).asJava, callableN, paramN) + + case _ => new SignatureHelp() } @@ -930,23 +935,25 @@ object DottyLanguageServer { /** Convert `signature` to a `SignatureInformation` */ def signatureToSignatureInformation(signature: Signatures.Signature): lsp4j.SignatureInformation = { - val tparams = signature.tparams.map(Signatures.Param("", _)) val paramInfoss = - (tparams ::: signature.paramss.flatten).map(paramToParameterInformation) + (signature.paramss.flatten).map(paramToParameterInformation) val paramLists = - if signature.paramss.forall(_.isEmpty) && tparams.nonEmpty then - "" - else - signature.paramss - .map { paramList => - val labels = paramList.map(_.show) - val prefix = if paramList.exists(_.isImplicit) then "using " else "" - labels.mkString(prefix, ", ", "") - } - .mkString("(", ")(", ")") - val tparamsLabel = if (signature.tparams.isEmpty) "" else signature.tparams.mkString("[", ", ", "]") + signature.paramss + .map { paramList => + val labels = paramList.map(_.show) + val isImplicit = paramList.exists: + case p: Signatures.MethodParam => p.isImplicit + case _ => false + val prefix = if isImplicit then "using " else "" + val isTypeParams = paramList.forall(_.isInstanceOf[Signatures.TypeParam]) && paramList.nonEmpty + val wrap: String => String = label => if isTypeParams then + s"[$label]" + else + s"($label)" + wrap(labels.mkString(prefix, ", ", "")) + }.mkString val returnTypeLabel = signature.returnType.map(t => s": $t").getOrElse("") - val label = s"${signature.name}$tparamsLabel$paramLists$returnTypeLabel" + val label = s"${signature.name}$paramLists$returnTypeLabel" val documentation = signature.doc.map(DottyLanguageServer.markupContent) val sig = new lsp4j.SignatureInformation(label) sig.setParameters(paramInfoss.asJava) diff --git a/language-server/test/dotty/tools/languageserver/CompletionTest.scala b/language-server/test/dotty/tools/languageserver/CompletionTest.scala index eaff8c307843..f3794c6f3468 100644 --- a/language-server/test/dotty/tools/languageserver/CompletionTest.scala +++ b/language-server/test/dotty/tools/languageserver/CompletionTest.scala @@ -35,6 +35,20 @@ class CompletionTest { .completion(("Conversion", Class, "Conversion")) } + @Test def implicitSearchCrash: Unit = + code""" + |object Test: + | trait Foo: + | def test(): String + | given Int = ??? + | given (using ev: Int): Conversion[String, Foo] = ??? + | + | val test = { + | "".tes$m1 + | 1 + | }""" + .completion(("test", Method, "(): String")) + @Test def completionFromScalaPackageObject: Unit = { code"class Foo { val foo: BigD${m1} }" .completion( @@ -1019,11 +1033,11 @@ class CompletionTest { | val x = Bar.${m1}""" .completion( ("getClass", Method, "[X0 >: Foo.Bar.type](): Class[? <: X0]"), - ("ensuring", Method, "(cond: Boolean): A"), + ("ensuring", Method, "(cond: Boolean): Foo.Bar.type"), ("##", Method, "=> Int"), ("nn", Method, "=> Foo.Bar.type"), ("==", Method, "(x$0: Any): Boolean"), - ("ensuring", Method, "(cond: Boolean, msg: => Any): A"), + ("ensuring", Method, "(cond: Boolean, msg: => Any): Foo.Bar.type"), ("ne", Method, "(x$0: Object): Boolean"), ("valueOf", Method, "($name: String): Foo.Bar"), ("equals", Method, "(x$0: Any): Boolean"), @@ -1031,21 +1045,21 @@ class CompletionTest { ("hashCode", Method, "(): Int"), ("notifyAll", Method, "(): Unit"), ("values", Method, "=> Array[Foo.Bar]"), - ("→", Method, "[B](y: B): (A, B)"), + ("→", Method, "[B](y: B): (Foo.Bar.type, B)"), ("!=", Method, "(x$0: Any): Boolean"), ("fromOrdinal", Method, "(ordinal: Int): Foo.Bar"), ("asInstanceOf", Method, "[X0]: X0"), - ("->", Method, "[B](y: B): (A, B)"), + ("->", Method, "[B](y: B): (Foo.Bar.type, B)"), ("wait", Method, "(x$0: Long, x$1: Int): Unit"), ("`back-tick`", Field, "Foo.Bar"), ("notify", Method, "(): Unit"), ("formatted", Method, "(fmtstr: String): String"), - ("ensuring", Method, "(cond: A => Boolean, msg: => Any): A"), + ("ensuring", Method, "(cond: Foo.Bar.type => Boolean, msg: => Any): Foo.Bar.type"), ("wait", Method, "(): Unit"), ("isInstanceOf", Method, "[X0]: Boolean"), ("`match`", Field, "Foo.Bar"), ("toString", Method, "(): String"), - ("ensuring", Method, "(cond: A => Boolean): A"), + ("ensuring", Method, "(cond: Foo.Bar.type => Boolean): Foo.Bar.type"), ("eq", Method, "(x$0: Object): Boolean"), ("synchronized", Method, "[X0](x$0: X0): X0") ) @@ -1576,6 +1590,61 @@ class CompletionTest { |""" .completion(m1, Set(("TTT", Field, "T.TTT"))) + @Test def properTypeVariable: Unit = + code"""|object M: + | List(1,2,3).filterNo$m1 + |""" + .completion(m1, Set(("filterNot", Method, "(p: Int => Boolean): List[Int]"))) + + @Test def properTypeVariableForExtensionMethods: Unit = + code"""|object M: + | extension [T](x: List[T]) def test(aaa: T): T = ??? + | List(1,2,3).tes$m1 + | + |""" + .completion(m1, Set(("test", Method, "(aaa: Int): Int"))) + + @Test def properTypeVariableForExtensionMethodsByName: Unit = + code"""|object M: + | extension [T](xs: List[T]) def test(p: T => Boolean): List[T] = ??? + | List(1,2,3).tes$m1 + |""" + .completion(m1, Set(("test", Method, "(p: Int => Boolean): List[Int]"))) + + @Test def genericExtensionTypeParameterInference: Unit = + code"""|object M: + | extension [T](xs: T) def test(p: T): T = ??? + | 3.tes$m1 + |""" + .completion(m1, Set(("test", Method, "(p: Int): Int"))) + + @Test def genericExtensionTypeParameterInferenceByName: Unit = + code"""|object M: + | extension [T](xs: T) def test(p: T => Boolean): T = ??? + | 3.tes$m1 + |""" + .completion(m1, Set(("test", Method, "(p: Int => Boolean): Int"))) + + @Test def properTypeVariableForImplicitDefs: Unit = + code"""|object M: + | implicit class ListUtils[T](xs: List[T]) { + | def test(p: T => Boolean): List[T] = ??? + | } + | List(1,2,3).tes$m1 + |""" + .completion(m1, Set(("test", Method, "(p: Int => Boolean): List[Int]"))) + + @Test def properTypeParameterForImplicitDefs: Unit = + code"""|object M: + | implicit class ListUtils[T](xs: T) { + | def test(p: T => Boolean): T = ??? + | } + | new ListUtils(1).tes$m1 + | 1.tes$m2 + |""" + .completion(m1, Set(("test", Method, "(p: Int => Boolean): Int"))) + .completion(m2, Set(("test", Method, "(p: Int => Boolean): Int"))) + @Test def selectDynamic: Unit = code"""|import scala.language.dynamics |class Foo extends Dynamic { @@ -1591,4 +1660,37 @@ class CompletionTest { |""" .completion(m1, Set(("selectDynamic", Method, "(field: String): Foo"))) .completion(m2, Set(("banana", Method, "=> Int"))) + + @Test def shadowedImport: Unit = + code"""| + |import Matches.* + |object Matches { + | val Number = "".r + |} + |object Main { + | Num$m1 + |} + |""".completion(m1, Set( + ("Number", Field, "scala.util.matching.Regex"), + ("NumberFormatException", Module, "NumberFormatException"), + ("Numeric", Field, "scala.math.Numeric") + )) + + @Test def shadowedImportType: Unit = + code"""| + |import Matches.* + |object Matches { + | val Number = "".r + |} + |object Main { + | val x: Num$m1 + |} + |""".completion(m1, Set( + ("Number", Class, "Number"), + ("Number", Field, "scala.util.matching.Regex"), + ("NumberFormatException", Module, "NumberFormatException"), + ("NumberFormatException", Field, "NumberFormatException"), + ("Numeric", Field, "Numeric"), + ("Numeric", Field, "scala.math.Numeric") + )) } diff --git a/language-server/test/dotty/tools/languageserver/SignatureHelpTest.scala b/language-server/test/dotty/tools/languageserver/SignatureHelpTest.scala index 78fd99d0c3ed..433b2665c4c1 100644 --- a/language-server/test/dotty/tools/languageserver/SignatureHelpTest.scala +++ b/language-server/test/dotty/tools/languageserver/SignatureHelpTest.scala @@ -4,38 +4,21 @@ import org.junit.Test import dotty.tools.languageserver.util.Code._ -import dotty.tools.dotc.util.Signatures.{Param => P, Signature => S} +import dotty.tools.dotc.util.Signatures.{TypeParam => TP, MethodParam => P, Signature => S} class SignatureHelpTest { @Test def fromJava: Unit = { val signature = - S("codePointAt", Nil, List(List(P("x$0", "Int"))), Some("Int")) + S("codePointAt", List(List(P("x$0", "Int"))), Some("Int")) code"""object O { "hello".codePointAt($m1) }""" .signatureHelp(m1, List(signature), Some(0), 0) } - @Test def properFunctionReturnWithoutParenthesis: Unit = { - val listSignature = S("apply", List("A"), List(List(P("elems", "A*"))), Some("List[A]")) - val optionSignature = S("apply", List("A"), List(List(P("x", "A"))), Some("Option[A]")) - code"""object O { - | List(1, 2$m1 - |} - |object T { - | List(Option(1$m2 - |} - |object Z { - | List(Option(1)$m3 - |}""" - .signatureHelp(m1, List(listSignature), Some(0), 1) - .signatureHelp(m2, List(optionSignature), Some(0), 1) - .signatureHelp(m3, List(listSignature), Some(0), 1) - } - @Test def errorTypeParameter: Unit = { - val emptySignature = S("empty", List("K", "V"), Nil, Some("Map[K, V]")) + val emptySignature = S("empty", List(List(TP("K"), TP("V"))), Some("Map[K, V]")) code"""object O: | Map.empty[WrongType, $m1] """ @@ -43,8 +26,8 @@ class SignatureHelpTest { } @Test def methodTypeParameter: Unit = { - val applySignature = S("apply", List("K", "V"), List(List(P("elems", "(K, V)*"))), Some("Map[K, V]")) - val emptySignature = S("empty", List("K", "V"), Nil, Some("Map[K, V]")) + val applySignature = S("apply", List(List(TP("K"), TP("V")), List(P("elems", "(K, V)*"))), Some("Map[K, V]")) + val emptySignature = S("empty", List(List(TP("K"), TP("V"))), Some("Map[K, V]")) code"""object O: | Map[$m1] | Map.empty[$m2] @@ -56,7 +39,7 @@ class SignatureHelpTest { } @Test def classTypeParameter: Unit = { - val signature = S("Test", List("K", "V"), Nil, Some("Test")) + val signature = S("Test", List(List(TP("K"), TP("V"))), Some("Test")) code"""object O: | class Test[K, V] {} | new Test[$m1] @@ -67,7 +50,7 @@ class SignatureHelpTest { } @Test def traitTypeParameter: Unit = { - val signature = S("Test", List("K", "V"), Nil, Some("Test")) + val signature = S("Test", List(List(TP("K"), TP("V"))), Some("Test")) code"""object O: | trait Test[K, V] {} | new Test[$m1] {} @@ -78,7 +61,7 @@ class SignatureHelpTest { } @Test def typeAliasTypeParameter: Unit = { - val signature = S("Test", List("K"), Nil, Some("Test")) + val signature = S("Test", List(List(TP("K"))), Some("Test")) code"""object O: | type Test[K] = List[K] | def test(x: Test[$m1]) @@ -87,7 +70,7 @@ class SignatureHelpTest { } @Test def typeParameterIndex: Unit = { - val mapSignature = S("map", List("B"), List(List(P("f", "Int => B"))), Some("List[B]")) + val mapSignature = S("map", List(List(TP("B")), List(P("f", "Int => B"))), Some("List[B]")) code"""object O { List(1, 2, 3).map[$m1]($m2) }""" @@ -96,18 +79,18 @@ class SignatureHelpTest { } @Test def partialyFailedCurriedFunctions: Unit = { - val listSignature = S("curry", Nil, List(List(P("a", "Int"), P("b", "Int")), List(P("c", "Int"))), Some("Int")) + val listSignature = S("curry", List(List(P("a", "Int"), P("b", "Int")), List(P("c", "Int"))), Some("Int")) code"""object O { |def curry(a: Int, b: Int)(c: Int) = a | curry(1$m1)$m2(3$m3) |}""" .signatureHelp(m1, List(listSignature), Some(0), 0) - .signatureHelp(m2, List(listSignature), Some(0), 0) + .signatureHelp(m2, List(listSignature), Some(0), 2) .signatureHelp(m3, List(listSignature), Some(0), 2) } @Test def optionProperSignature: Unit = { - val signature = S("apply", List("A"), List(List(P("x", "A"))), Some("Option[A]")) + val signature = S("apply", List(List(TP("A")), List(P("x", "A"))), Some("Option[A]")) code"""object O { | Option(1, 2, 3, $m1) |}""" @@ -123,8 +106,8 @@ class SignatureHelpTest { } @Test def fromScala2: Unit = { - val applySig = S("apply", List("A"), List(List(P("elems", "A*"))), Some("List[A]")) - val mapSig = S("map", List("B"), List(List(P("f", "Int => B"))), Some("List[B]")) + val applySig = S("apply", List(List(TP("A")), List(P("elems", "A*"))), Some("List[A]")) + val mapSig = S("map", List(List(TP("B")), List(P("f", "Int => B"))), Some("List[B]")) code"""object O { List($m1) List(1, 2, 3).map($m2) @@ -134,14 +117,14 @@ class SignatureHelpTest { } @Test def typeParameterMethodApply: Unit = { - val testSig = S("method", Nil, List(List()), Some("Int")) + val testSig = S("method", List(List()), Some("Int")) code"""case class Foo[A](test: A) { | def method(): A = ??? |} |object O { | Foo(5).method($m1) |}""" - .signatureHelp(m1, List(testSig), Some(0), 0) + .signatureHelp(m1, List(testSig), Some(0), -1) } @Test def unapplyBooleanReturn: Unit = { @@ -153,11 +136,11 @@ class SignatureHelpTest { | case s @ Even(${m1}) => println(s"s has an even number of characters") | case s => println(s"s has an odd number of characters") """ - .signatureHelp(m1, Nil, Some(0), 0) + .signatureHelp(m1, Nil, Some(0), -1) } @Test def unapplyCustomClass: Unit = { - val signature = S("", Nil, List(List(P("", "Int"))), None) + val signature = S("", List(List(P("", "Int"))), None) code"""class Nat(val x: Int): | def get: Int = x @@ -174,7 +157,7 @@ class SignatureHelpTest { } @Test def unapplyTypeClass: Unit = { - val signature = S("", Nil, List(List(P("", "Int"), P("", "String"))), None) + val signature = S("", List(List(P("", "Int"), P("", "String"))), None) code"""class Two[A, B](a: A, b: B) |object Two { @@ -192,9 +175,9 @@ class SignatureHelpTest { } @Test def nestedUnapplySignature: Unit = { - val signatureOneTwo = S("", Nil, List(List(P("a", "One"), P("b", "Two"))), None) - val signatureOne = S("", Nil, List(List(P("c", "Int"))), None) - val signatureTwo = S("", Nil, List(List(P("d", "Int"))), None) + val signatureOneTwo = S("", List(List(P("a", "One"), P("b", "Two"))), None) + val signatureOne = S("", List(List(P("c", "Int"))), None) + val signatureTwo = S("", List(List(P("d", "Int"))), None) code"""case class One(c: Int) |case class Two(d: Int) @@ -216,7 +199,7 @@ class SignatureHelpTest { } @Test def properParameterIndexTest: Unit = { - val signature = S("", Nil, List(List(P("a", "Int"), P("b", "String"))), None) + val signature = S("", List(List(P("a", "Int"), P("b", "String"))), None) code"""case class Two(a: Int, b: String) | |object Main { @@ -226,13 +209,13 @@ class SignatureHelpTest { | } |}""" .signatureHelp(m1, List(signature), Some(0), 0) - .signatureHelp(m2, List(signature), Some(0), -1) - .signatureHelp(m3, List(signature), Some(0), -1) - .signatureHelp(m4, List(signature), Some(0), -1) + .signatureHelp(m2, List(signature), Some(0), 1) + .signatureHelp(m3, List(signature), Some(0), 1) + .signatureHelp(m4, List(), Some(0), 0) } @Test def unapplyClass: Unit = { - val signature = S("", Nil, List(List(P("", "Int"), P("", "String"))), None) + val signature = S("", List(List(P("", "Int"), P("", "String"))), None) code"""class Two(a: Int, b: String) |object Two { @@ -250,7 +233,7 @@ class SignatureHelpTest { } @Test def productMatch: Unit = { - val signature = S("", Nil, List(List(P("", "Char"), P("", "Char"))), None) + val signature = S("", List(List(P("", "Char"), P("", "Char"))), None) code"""class FirstChars(s: String) extends Product: | def _1 = s.charAt(0) @@ -268,7 +251,7 @@ class SignatureHelpTest { } @Test def noUnapplySignatureWhenApplyingUnapply: Unit = { - val signature = S("unapply", List("A"), List(List(P("a", "A"))), Some("Some[(A, A)]")) + val signature = S("unapply", List(List(TP("A")), List(P("a", "A"))), Some("Some[(A, A)]")) code""" |object And { @@ -282,7 +265,7 @@ class SignatureHelpTest { } @Test def nestedOptionReturnedInUnapply: Unit = { - val signature = S("", Nil, List(List(P("", "Option[Int]"))), None) + val signature = S("", List(List(P("", "Option[Int]"))), None) code"""object OpenBrowserCommand { | def unapply(command: String): Option[Option[Int]] = { @@ -298,8 +281,8 @@ class SignatureHelpTest { } @Test def unknownTypeUnapply: Unit = { - val signature = S("", Nil, List(List(P("a", "A"), P("b", "B"))), None) - val signature2 = S("", Nil, List(List(P("a", "Int"), P("b", "Any"))), None) + val signature = S("", List(List(P("a", "A"), P("b", "B"))), None) + val signature2 = S("", List(List(P("a", "Int"), P("b", "Any"))), None) code"""case class Two[A, B](a: A, b: B) |object Main { @@ -318,24 +301,22 @@ class SignatureHelpTest { } @Test def sequenceMatchUnapply: Unit = { - val signatureSeq = S("", Nil, List(List(P("", "Seq[Int]"))), None) - val signatureVariadicExtractor = S("", Nil, List(List(P("", "Int"), P("","List[Int]"))), None) + val signatureSeq = S("", List(List(P("", "Seq[Int]"))), None) + val signatureVariadicExtractor = S("", List(List(P("", "Int"), P("","List[Int]"))), None) code"""case class Two[A, B](a: A, b: B) |object Main { | Seq(1,2,3) match { | case Seq($m1) => - | case h$m2 :: t$m3 => + | case h :: t => | } |} """ .signatureHelp(m1, List(signatureSeq), Some(0), 0) - .signatureHelp(m2, List(signatureVariadicExtractor), Some(0), 0) - .signatureHelp(m3, List(signatureVariadicExtractor), Some(0), 1) } @Test def productTypeClassMatch: Unit = { - val signature = S("", Nil, List(List(P("", "String"), P("", "String"))), None) + val signature = S("", List(List(P("", "String"), P("", "String"))), None) code"""class FirstChars[A](s: A) extends Product: | def _1 = s @@ -353,8 +334,8 @@ class SignatureHelpTest { } @Test def nameBasedMatch: Unit = { - val nameBasedMatch = S("", Nil, List(List(P("", "Int"), P("", "String"))), None) - val singleMatch = S("", Nil, List(List(P("", "ProdEmpty.type"))), None) + val nameBasedMatch = S("", List(List(P("", "Int"), P("", "String"))), None) + val singleMatch = S("", List(List(P("", "ProdEmpty.type"))), None) code"""object ProdEmpty: | def _1: Int = ??? @@ -375,8 +356,8 @@ class SignatureHelpTest { } @Test def nameBasedMatchWithWrongGet: Unit = { - val nameBasedMatch = S("", Nil, List(List(P("", "Int"))), None) - val singleMatch = S("", Nil, List(List(P("", "Int"))), None) + val nameBasedMatch = S("", List(List(P("", "Int"))), None) + val singleMatch = S("", List(List(P("", "Int"))), None) code"""object ProdEmpty: | def _1: Int = ??? @@ -392,12 +373,12 @@ class SignatureHelpTest { | case _ => () """ .signatureHelp(m1, List(nameBasedMatch), Some(0), 0) - .signatureHelp(m2, List(nameBasedMatch), Some(0), -1) + .signatureHelp(m2, List(nameBasedMatch), Some(0), 0) .signatureHelp(m3, List(singleMatch), Some(0), 0) } @Test def nameBasedSingleMatchOrder: Unit = { - val signature = S("", Nil, List(List(P("", "String"))), None) + val signature = S("", List(List(P("", "String"))), None) code"""object ProdEmpty: | def _1: Int = 1 @@ -414,7 +395,7 @@ class SignatureHelpTest { } @Test def getObjectMatch: Unit = { - val signature = S("", Nil, List(List(P("", "String"))), None) + val signature = S("", List(List(P("", "String"))), None) code"""object ProdEmpty: | def isEmpty = true @@ -430,7 +411,7 @@ class SignatureHelpTest { } @Test def customSequenceMatch: Unit = { - val signature = S("", Nil, List(List(P("", "Seq[Char]"))), None) + val signature = S("", List(List(P("", "Seq[Char]"))), None) code"""object CharList: | def unapplySeq(s: String): Option[Seq[Char]] = Some(s.toList) @@ -448,7 +429,7 @@ class SignatureHelpTest { } @Test def productSequenceMatch: Unit = { - val signature = S("", Nil, List(List(P("", "String"), P("", "Seq[Int]"))), None) + val signature = S("", List(List(P("", "String"), P("", "Seq[Int]"))), None) code"""class Foo(val name: String, val children: Int*) |object Foo: @@ -468,7 +449,7 @@ class SignatureHelpTest { } @Test def productSequenceMatchForCaseClass: Unit = { - val signature = S("", Nil, List(List(P("name", "String"), P("children", "Seq[Int]"))), None) + val signature = S("", List(List(P("name", "String"), P("children", "Seq[Int]"))), None) code"""case class Foo(val name: String, val children: Int*) | @@ -485,7 +466,7 @@ class SignatureHelpTest { } @Test def unapplyManyType: Unit = { - val signature = S("", Nil, List(List(P("", "Int"), P("", "String"))), None) + val signature = S("", List(List(P("", "Int"), P("", "String"))), None) code""" |object Opt { @@ -502,7 +483,7 @@ class SignatureHelpTest { } @Test def unapplyTypeCaseClass: Unit = { - val signature = S("", Nil, List(List(P("a", "Int"), P("b", "String"))), None) + val signature = S("", List(List(P("a", "Int"), P("b", "String"))), None) code"""case class Two[A, B](a: A, b: B) | @@ -517,7 +498,7 @@ class SignatureHelpTest { } @Test def unapplyForTuple: Unit = { - val signature = S("", Nil, List(List(P("", "Int"), P("", "Int"))), None) + val signature = S("", List(List(P("", "Int"), P("", "Int"))), None) code"""object Main { | (1, 2) match | case (x${m1}, ${m2}) => @@ -527,7 +508,7 @@ class SignatureHelpTest { } @Test def unapplyCaseClass: Unit = { - val signature = S("", Nil, List(List(P("a", "Int"), P("b", "String"))), None) + val signature = S("", List(List(P("a", "Int"), P("b", "String"))), None) code"""case class Two(a: Int, b: String) | @@ -542,7 +523,7 @@ class SignatureHelpTest { } @Test def unapplyOption: Unit = { - val signature = S("", Nil, List(List(P("", "Int"))), None) + val signature = S("", List(List(P("", "Int"))), None) code"""|object Main { | Option(1) match { @@ -553,7 +534,7 @@ class SignatureHelpTest { } @Test def unapplyWithImplicits: Unit = { - val signature = S("", Nil, List(List(P("", "Int"))), None) + val signature = S("", List(List(P("", "Int"))), None) code"""| |object Opt: | def unapply[A](using String)(a: Option[A])(using Int) = a @@ -570,7 +551,7 @@ class SignatureHelpTest { } @Test def unapplyWithMultipleImplicits: Unit = { - val signature = S("", Nil, List(List(P("", "Int"))), None) + val signature = S("", List(List(P("", "Int"))), None) code"""| |object Opt: | def unapply[A](using String)(using Int)(a: Option[A]) = a @@ -587,15 +568,10 @@ class SignatureHelpTest { /** Implicit parameter lists consisting solely of DummyImplicits are hidden. */ @Test def hiddenDummyParams: Unit = { - val foo1Sig = - S("foo1", Nil, List(List(P("param0", "Int"))), Some("Int")) - val foo2Sig = - S("foo2", Nil, List(List(P("param0", "Int"))), Some("Int")) - val foo3Sig = - S("foo3", Nil, List(List(P("param0", "Int")), - List(P("dummy", "DummyImplicit"))), Some("Int")) - val foo4Sig = - S("foo4", Nil, List(List(P("param0", "Int")), + val foo1Sig = S("foo1", List(List(P("param0", "Int"))), Some("Int")) + val foo2Sig = S("foo2", List(List(P("param0", "Int"))), Some("Int")) + val foo3Sig = S("foo3", List(List(P("param0", "Int")), List(P("dummy", "DummyImplicit"))), Some("Int")) + val foo4Sig = S("foo4", List(List(P("param0", "Int")), List(P("x", "Int", isImplicit = true), P("dummy", "DummyImplicit", isImplicit = true))), Some("Int")) code"""object O { def foo1(param0: Int)(implicit dummy: DummyImplicit): Int = ??? @@ -615,7 +591,7 @@ class SignatureHelpTest { @Test def singleParam: Unit = { val signature = - S("foo", Nil, List(List(P("param0", "Int"))), Some("Int")) + S("foo", List(List(P("param0", "Int"))), Some("Int")) code"""object O { def foo(param0: Int): Int = ??? foo($m1) @@ -626,7 +602,7 @@ class SignatureHelpTest { } @Test def twoParams: Unit = { - val signature = S("foo", Nil, List(List(P("param0", "Int"), P("param1", "String"))), Some("Int")) + val signature = S("foo", List(List(P("param0", "Int"), P("param1", "String"))), Some("Int")) code"""object O { def foo(param0: Int, param1: String): Int = ??? foo($m1) @@ -639,8 +615,8 @@ class SignatureHelpTest { } @Test def noMatchingOverload: Unit = { - val sig0 = S("foo", Nil, List(List(P("param0", "Int"))), Some("Nothing")) - val sig1 = S("foo", Nil, List(List(P("param1", "String"))), Some("Nothing")) + val sig0 = S("foo", List(List(P("param0", "Int"))), Some("Nothing")) + val sig1 = S("foo", List(List(P("param1", "String"))), Some("Nothing")) code"""object O { def foo(param0: Int): Nothing = ??? @@ -655,8 +631,8 @@ class SignatureHelpTest { } @Test def singleMatchingOverload: Unit = { - val sig0 = S("foo", Nil, List(List(P("param0", "Int"), P("param1", "String"))), Some("Nothing")) - val sig1 = S("foo", Nil, List(List(P("param0", "String"), P("param1", "Int"))), Some("Nothing")) + val sig0 = S("foo", List(List(P("param0", "Int"), P("param1", "String"))), Some("Nothing")) + val sig1 = S("foo", List(List(P("param0", "String"), P("param1", "Int"))), Some("Nothing")) code"""object O { def foo(param0: Int, param1: String): Nothing = ??? def foo(param0: String, param1: Int): Nothing = ??? @@ -674,9 +650,9 @@ class SignatureHelpTest { } @Test def multipleMatchingOverloads: Unit = { - val sig0 = S("foo", Nil, List(List(P("param0", "Int"), P("param1", "Int"))), Some("Nothing")) - val sig1 = S("foo", Nil, List(List(P("param0", "Int"), P("param1", "Boolean"))), Some("Nothing")) - val sig2 = S("foo", Nil, List(List(P("param0", "String"), P("param1", "Int"))), Some("Nothing")) + val sig0 = S("foo", List(List(P("param0", "Int"), P("param1", "Int"))), Some("Nothing")) + val sig1 = S("foo", List(List(P("param0", "Int"), P("param1", "Boolean"))), Some("Nothing")) + val sig2 = S("foo", List(List(P("param0", "String"), P("param1", "Int"))), Some("Nothing")) val sigs = List(sig0, sig1, sig2) code"""object O { def foo(param0: Int, param1: Int): Nothing = ??? @@ -702,8 +678,8 @@ class SignatureHelpTest { } @Test def ambiguousOverload: Unit = { - val sig0 = S("foo", Nil, List(List(P("param0", "String")), List(P("param1", "String"))), Some("Nothing")) - val sig1 = S("foo", Nil, List(List(P("param0", "String"))), Some("Nothing")) + val sig0 = S("foo", List(List(P("param0", "String")), List(P("param1", "String"))), Some("Nothing")) + val sig1 = S("foo", List(List(P("param0", "String"))), Some("Nothing")) code"""object O { def foo(param0: String)(param1: String): Nothing = ??? def foo(param0: String): Nothing = ??? @@ -713,13 +689,12 @@ class SignatureHelpTest { }""" .signatureHelp(m1, List(sig0, sig1), None, 0) .signatureHelp(m2, List(sig0, sig1), None, 0) - .signatureHelp(m3, List(sig0, sig1), Some(1), 1) + .signatureHelp(m3, List(sig0, sig1), Some(0), 1) } @Test def multipleParameterLists: Unit = { val signature = S("foo", - Nil, List( List(P("param0", "Int"), P("param1", "Int")), List(P("param2", "Int")), @@ -744,7 +719,6 @@ class SignatureHelpTest { @Test def implicitParams: Unit = { val signature = S("foo", - Nil, List( List(P("param0", "Int"), P("param1", "Int")), List(P("param2", "Int", isImplicit = true)) @@ -764,8 +738,8 @@ class SignatureHelpTest { @Test def typeParameters: Unit = { val signature = S("foo", - List("M[X]", "T[Z] <: M[Z]", "U >: T"), List( + List(TP("M[X]"), TP("T[Z] <: M[Z]"), TP("U >: T")), List(P("p0", "M[Int]"), P("p1", "T[Int]"), P("p2", "U")) ), Some("Int")) @@ -779,7 +753,6 @@ class SignatureHelpTest { @Test def constructorCall: Unit = { val signature = S("Foo", - Nil, List( List(P("x", "Int"), P("y", "String")), List(P("z", "String")) @@ -799,7 +772,6 @@ class SignatureHelpTest { @Test def overloadedConstructorCall: Unit = { val sig0 = S("Foo", - Nil, List( List(P("x", "Int"), P("y", "String")), List(P("z", "Int")) @@ -807,7 +779,6 @@ class SignatureHelpTest { None) val sig1 = S("Foo", - Nil, List( List(P("x", "Int"), P("y", "Int")) ), @@ -829,8 +800,8 @@ class SignatureHelpTest { @Test def constructorCallDoc: Unit = { val signatures = List( - S("Foo", Nil, List(List(P("x", "Int", Some("An int")), P("y", "String", Some("A string")))), None, Some("A Foo")), - S("Foo", Nil, List(List(P("z", "Boolean", Some("A boolean")), P("foo", "Foo", Some("A Foo")))), None, Some("An alternative constructor for Foo")) + S("Foo", List(List(P("x", "Int", Some("An int")), P("y", "String", Some("A string")))), None, Some("A Foo")), + S("Foo", List(List(P("z", "Boolean", Some("A boolean")), P("foo", "Foo", Some("A Foo")))), None, Some("An alternative constructor for Foo")) ) code"""/** @@ -869,8 +840,8 @@ class SignatureHelpTest { @Test def classTypeParameters: Unit = { val signature = S("Foo", - List("M[X]", "T[Z] <: M[Z]", "U"), List( + List(TP("M[X]"), TP("T[Z] <: M[Z]"), TP("U")), List(P("p0", "M[Int]"), P("p1", "T[Int]"), P("p2", "U")), List(P("p3", "Int")) ), @@ -893,7 +864,7 @@ class SignatureHelpTest { /** Hello, world! */ def foo(param0: Int): Int = 0 foo($m1) }""" - .signatureHelp(m1, List(S("foo", Nil, List(List(P("param0", "Int"))), Some("Int"), Some("Hello, world!"))), None, 0) + .signatureHelp(m1, List(S("foo", List(List(P("param0", "Int"))), Some("Int"), Some("Hello, world!"))), None, 0) } @Test def showParamDoc: Unit = { @@ -909,7 +880,7 @@ class SignatureHelpTest { | buzz($m1) |}""" .signatureHelp(m1, List( - S("buzz", Nil, List(List( + S("buzz", List(List( P("fizz", "Int", Some("The fizz to buzz")), P("bar", "Int", Some("Buzzing limit")) )), Some("Int"), Some("Buzzes a fizz up to bar")) @@ -918,9 +889,9 @@ class SignatureHelpTest { @Test def nestedApplySignatures: Unit = { val signatures = (1 to 5).map { i => - S(s"foo$i", Nil, List(List(P("x", "Int"))), Some("Int")) + S(s"foo$i", List(List(P("x", "Int"))), Some("Int")) } - val booSignature = S(s"boo", Nil, List(List(P("x", "Int"), P("y", "Int"))), Some("Int")) + val booSignature = S(s"boo", List(List(P("x", "Int"), P("y", "Int"))), Some("Int")) code"""|object O: | def foo1(x: Int): Int = ??? | def foo2(x: Int): Int = ??? @@ -939,8 +910,8 @@ class SignatureHelpTest { } @Test def multipleNestedApplySignatures: Unit = { - val simpleSignature = S(s"simpleFoo", Nil, List(List(P("x", "Int"))), Some("Int")) - val complicatedSignature = S(s"complicatedFoo", Nil, List(List(P("x", "Int"), P("y", "Int"), P("z", "Int"))), Some("Int")) + val simpleSignature = S(s"simpleFoo", List(List(P("x", "Int"))), Some("Int")) + val complicatedSignature = S(s"complicatedFoo", List(List(P("x", "Int"), P("y", "Int"), P("z", "Int"))), Some("Int")) code"""|object O: | def simpleFoo(x: Int): Int = ??? | def complicatedFoo(x: Int, y: Int, z: Int): Int = ??? @@ -966,7 +937,7 @@ class SignatureHelpTest { } @Test def noHelpSignatureWithPositionedOnName: Unit = { - val signature = S(s"foo", Nil, List(List(P("x", "Int"))), Some("Int")) + val signature = S(s"foo", List(List(P("x", "Int"))), Some("Int")) code"""|object O: | def foo(x: Int): Int = ??? | f${m1}oo(${m2})""" @@ -974,4 +945,13 @@ class SignatureHelpTest { .signatureHelp(m2, List(signature), None, 0) } + @Test def instantiatedTypeVarInOldExtensionMethods: Unit = { + val signature = S(s"test", List(List(P("x", "Int"))), Some("List[Int]")) + code"""|object O: + | implicit class TypeVarTest[T](xs: List[T]): + | def test(x: T): List[T] = ??? + | List(1,2,3).test(${m1})""" + .signatureHelp(m1, List(signature), None, 0) + } + } diff --git a/library/src/scala/annotation/MacroAnnotation.scala b/library/src/scala/annotation/MacroAnnotation.scala index 999bc3095a69..a76289ecea61 100644 --- a/library/src/scala/annotation/MacroAnnotation.scala +++ b/library/src/scala/annotation/MacroAnnotation.scala @@ -25,7 +25,7 @@ trait MacroAnnotation extends StaticAnnotation: * #### Restrictions * - All definitions in the result must have the same owner. The owner can be recovered from `Symbol.spliceOwner`. * - Special case: an annotated top-level `def`, `val`, `var`, `lazy val` can return a `class`/`object` -definition that is owned by the package or package object. + * definition that is owned by the package or package object. * - Can not return a `type`. * - Annotated top-level `class`/`object` can not return top-level `def`, `val`, `var`, `lazy val`. * - Can not see new definition in user written code. diff --git a/library/src/scala/annotation/internal/reach.scala b/library/src/scala/annotation/internal/reachCapability.scala similarity index 100% rename from library/src/scala/annotation/internal/reach.scala rename to library/src/scala/annotation/internal/reachCapability.scala diff --git a/library/src/scala/annotation/retains.scala b/library/src/scala/annotation/retains.scala index 0387840ea8bd..4fa14e635136 100644 --- a/library/src/scala/annotation/retains.scala +++ b/library/src/scala/annotation/retains.scala @@ -13,3 +13,11 @@ package scala.annotation */ @experimental class retains(xs: Any*) extends annotation.StaticAnnotation + +/** Equivalent in meaning to `@retains(cap)`, but consumes less bytecode. + */ +@experimental +class retainsCap() extends annotation.StaticAnnotation + // This special case is needed to be able to load standard library modules without + // cyclic reference errors. Specifically, load sequences involving IterableOnce. + diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index f496d9cae2b2..fa96b73551d1 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -1637,10 +1637,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * val q: Quotes = summon[Quotes] * import q.reflect._ * //} - * val intArgs = List(Literal(Constant(1)), Literal(Constant(2))) + * val intArgs = List(Literal(IntConstant(1)), Literal(IntConstant(2))) * Typed( - * Repeated(intArgs, TypeTree.of[Int]), - * Inferred(defn.RepeatedParamClass.typeRef.appliedTo(TypeRepr.of[Int])) + * Repeated(intArgs, TypeTree.of[Int]), + * Inferred(defn.RepeatedParamClass.typeRef.appliedTo(TypeRepr.of[Int])) + * ) * //{ * } * //} diff --git a/library/src/scala/runtime/stdLibPatches/language.scala b/library/src/scala/runtime/stdLibPatches/language.scala index c0dd8a74419e..70d5f2d41907 100644 --- a/library/src/scala/runtime/stdLibPatches/language.scala +++ b/library/src/scala/runtime/stdLibPatches/language.scala @@ -13,7 +13,7 @@ object language: * code should not rely on them. * * Programmers are encouraged to try out experimental features and - * [[http://issues.scala-lang.org report any bugs or API inconsistencies]] + * [[https://github.com/scala/scala3/issues report any bugs or API inconsistencies]] * they encounter so they can be improved in future releases. * * @group experimental diff --git a/library/src/scala/util/boundary.scala b/library/src/scala/util/boundary.scala index 2edd754bbb93..3039fc70be90 100644 --- a/library/src/scala/util/boundary.scala +++ b/library/src/scala/util/boundary.scala @@ -15,14 +15,16 @@ import scala.annotation.implicitNotFound * be rewritten to jumps. * * Example usage: + * + * ```scala + * import scala.util.boundary, boundary.break * - * import scala.util.boundary, boundary.break - * - * def firstIndex[T](xs: List[T], elem: T): Int = - * boundary: - * for (x, i) <- xs.zipWithIndex do - * if x == elem then break(i) - * -1 + * def firstIndex[T](xs: List[T], elem: T): Int = + * boundary: + * for (x, i) <- xs.zipWithIndex do + * if x == elem then break(i) + * -1 + * ``` */ object boundary: diff --git a/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala b/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala index d217a0acd9b1..231960ec5116 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala @@ -9,6 +9,7 @@ import scala.meta.pc.* import scala.util.control.NonFatal import dotty.tools.dotc.core.Contexts.* +import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Names.* import dotty.tools.dotc.core.Symbols.* @@ -19,8 +20,14 @@ class CompilerSearchVisitor( val logger: Logger = Logger.getLogger(classOf[CompilerSearchVisitor].getName().nn).nn + private def isAccessibleImplicitClass(sym: Symbol) = + val owner = sym.maybeOwner + owner != NoSymbol && owner.isClass && + owner.is(Flags.Implicit) && + owner.isStatic && owner.isPublic + private def isAccessible(sym: Symbol): Boolean = try - sym != NoSymbol && sym.isPublic && sym.isStatic + sym != NoSymbol && sym.isPublic && sym.isStatic || isAccessibleImplicitClass(sym) catch case err: AssertionError => logger.log(Level.WARNING, err.getMessage()) @@ -51,6 +58,7 @@ class CompilerSearchVisitor( .filter(denot => denot.exists) .map(_.symbol) .filter(isAccessible) + .filter(!_.is(Flags.Given)) } loop(next, tl) case Nil => owners diff --git a/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala index 817ab5402c00..00bfe17cb21b 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala @@ -35,7 +35,7 @@ final class ConvertToNamedArgumentsProvider( val tree = Interactive.pathTo(trees, pos)(using newctx).headOption def paramss(fun: tpd.Tree)(using Context): List[String] = - fun.tpe match + fun.typeOpt match case m: MethodType => m.paramNamess.flatten.map(_.toString) case _ => fun.symbol.rawParamss.flatten diff --git a/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala index 0b5fd1b06a8f..55c4e4d9e4b6 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala @@ -128,7 +128,7 @@ final class ExtractMethodProvider( yield val defnPos = stat.sourcePos val extractedPos = head.sourcePos.withEnd(expr.sourcePos.end) - val exprType = prettyPrint(expr.tpe.widen) + val exprType = prettyPrint(expr.typeOpt.widen) val name = genName(indexedCtx.scopeSymbols.map(_.decodedName).toSet, "newMethod") val (methodParams, typeParams) = diff --git a/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala index 545607c0b8ff..6f39b4871a06 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala @@ -36,16 +36,20 @@ object HoverProvider: val text = params.text().nn val sourceFile = SourceFile.virtual(uri, text) driver.run(uri, sourceFile) + val unit = driver.compilationUnits.get(uri) - given ctx: Context = driver.currentCtx + given ctx: Context = + val ctx = driver.currentCtx + unit.map(ctx.fresh.setCompilationUnit).getOrElse(ctx) val pos = driver.sourcePosition(params) - val trees = driver.openedTrees(uri) + val path = unit + .map(unit => Interactive.pathTo(unit.tpdTree, pos.span)) + .getOrElse(Interactive.pathTo(driver.openedTrees(uri), pos)) val indexedContext = IndexedContext(ctx) def typeFromPath(path: List[Tree]) = - if path.isEmpty then NoType else path.head.tpe + if path.isEmpty then NoType else path.head.typeOpt - val path = Interactive.pathTo(trees, pos) val tp = typeFromPath(path) val tpw = tp.widenTermRefExpr // For expression we need to find all enclosing applies to get the exact generic type @@ -72,7 +76,10 @@ object HoverProvider: |path: |- ${path.map(_.toString()).mkString("\n- ")} |trees: - |- ${trees.map(_.toString()).mkString("\n- ")} + |- ${unit + .map(u => List(u.tpdTree)) + .getOrElse(driver.openedTrees(uri).map(_.tree)) + .map(_.toString()).mkString("\n- ")} |""".stripMargin, s"$uri::$posId" ) @@ -83,15 +90,9 @@ object HoverProvider: val skipCheckOnName = !pos.isPoint // don't check isHoveringOnName for RangeHover - val printerContext = - driver.compilationUnits.get(uri) match - case Some(unit) => - val newctx = - ctx.fresh.setCompilationUnit(unit) - Interactive.contextOfPath(enclosing)(using newctx) - case None => ctx + val printerCtx = Interactive.contextOfPath(path) val printer = ShortenedTypePrinter(search, IncludeDefaultParam.Include)( - using IndexedContext(printerContext) + using IndexedContext(printerCtx) ) MetalsInteractive.enclosingSymbolsWithExpressionType( enclosing, @@ -108,7 +109,7 @@ object HoverProvider: val exprTpw = tpe.widenTermRefExpr.metalsDealias val hoverString = tpw match - // https://github.com/lampepfl/dotty/issues/8891 + // https://github.com/scala/scala3/issues/8891 case tpw: ImportType => printer.hoverSymbol(symbol, symbol.paramRef) case _ => @@ -142,7 +143,8 @@ object HoverProvider: expressionType = Some(expressionType), symbolSignature = Some(hoverString), docstring = Some(docString), - forceExpressionType = forceExpressionType + forceExpressionType = forceExpressionType, + contextInfo = printer.getUsedRenamesInfo ) ).nn case _ => @@ -176,13 +178,14 @@ object HoverProvider: new ScalaHover( expressionType = Some(tpeString), symbolSignature = Some(s"$valOrDef $name$tpeString"), + contextInfo = printer.getUsedRenamesInfo ) ) case RefinedType(parent, _, _) => findRefinement(parent) case _ => None - val refTpe = sel.tpe.widen.metalsDealias match + val refTpe = sel.typeOpt.widen.metalsDealias match case r: RefinedType => Some(r) case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.metalsDealias) case _ => None diff --git a/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala b/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala index e31f4756b220..ad6fe9420a81 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala @@ -10,6 +10,7 @@ import dotty.tools.dotc.core.Names.* import dotty.tools.dotc.core.Scopes.EmptyScope import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.core.Types.* +import dotty.tools.dotc.interactive.Interactive import dotty.tools.dotc.typer.ImportInfo import dotty.tools.pc.IndexedContext.Result import dotty.tools.pc.utils.MtagsEnrichments.* @@ -31,16 +32,33 @@ sealed trait IndexedContext: case Some(symbols) if symbols.exists(_ == sym) => Result.InScope case Some(symbols) - if symbols - .exists(s => isTypeAliasOf(s, sym) || isTermAliasOf(s, sym)) => - Result.InScope + if symbols.exists(s => isNotConflictingWithDefault(s, sym) || isTypeAliasOf(s, sym) || isTermAliasOf(s, sym)) => + Result.InScope // when all the conflicting symbols came from an old version of the file - case Some(symbols) if symbols.nonEmpty && symbols.forall(_.isStale) => - Result.Missing + case Some(symbols) if symbols.nonEmpty && symbols.forall(_.isStale) => Result.Missing case Some(_) => Result.Conflict case None => Result.Missing end lookupSym + /** + * Scala by default imports following packages: + * https://scala-lang.org/files/archive/spec/3.4/02-identifiers-names-and-scopes.html + * import java.lang.* + * { + * import scala.* + * { + * import Predef.* + * { /* source */ } + * } + * } + * + * This check is necessary for proper scope resolution, because when we compare symbols from + * index including the underlying type like scala.collection.immutable.List it actually + * is in current scope in form of type forwarder imported from Predef. + */ + private def isNotConflictingWithDefault(sym: Symbol, queriedSym: Symbol): Boolean = + sym.info.widenDealias =:= queriedSym.info.widenDealias && (Interactive.isImportedByDefault(sym)) + final def hasRename(sym: Symbol, as: String): Boolean = rename(sym) match case Some(v) => v == as @@ -49,15 +67,15 @@ sealed trait IndexedContext: // detects import scope aliases like // object Predef: // val Nil = scala.collection.immutable.Nil - private def isTermAliasOf(termAlias: Symbol, sym: Symbol): Boolean = + private def isTermAliasOf(termAlias: Symbol, queriedSym: Symbol): Boolean = termAlias.isTerm && ( - sym.info match + queriedSym.info match case clz: ClassInfo => clz.appliedRef =:= termAlias.info.resultType case _ => false ) - private def isTypeAliasOf(alias: Symbol, sym: Symbol): Boolean = - alias.isAliasType && alias.info.metalsDealias.typeSymbol == sym + private def isTypeAliasOf(alias: Symbol, queriedSym: Symbol): Boolean = + alias.isAliasType && alias.info.metalsDealias.typeSymbol == queriedSym final def isEmpty: Boolean = this match case IndexedContext.Empty => true diff --git a/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala index 69d89d5b0d13..b37b1b6dff6c 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala @@ -138,7 +138,7 @@ final class InferredTypeProvider( adjustOpt.foreach(adjust => endPos.setEnd(adjust.adjustedEndPos)) new TextEdit( endPos, - ": " + printType(optDealias(tpt.tpe)) + { + ": " + printType(optDealias(tpt.typeOpt)) + { if withParens then ")" else "" } ) @@ -211,7 +211,7 @@ final class InferredTypeProvider( adjustOpt.foreach(adjust => end.setEnd(adjust.adjustedEndPos)) new TextEdit( end, - ": " + printType(optDealias(tpt.tpe)) + ": " + printType(optDealias(tpt.typeOpt)) ) end typeNameEdit @@ -241,7 +241,7 @@ final class InferredTypeProvider( def baseEdit(withParens: Boolean) = new TextEdit( bind.endPos.toLsp, - ": " + printType(optDealias(body.tpe)) + { + ": " + printType(optDealias(body.typeOpt)) + { if withParens then ")" else "" } ) @@ -274,7 +274,7 @@ final class InferredTypeProvider( case Some(i @ Ident(name)) => val typeNameEdit = new TextEdit( i.endPos.toLsp, - ": " + printType(optDealias(i.tpe.widen)) + ": " + printType(optDealias(i.typeOpt.widen)) ) typeNameEdit :: imports diff --git a/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala b/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala index 076c1d9a9b88..381e0eaec6a5 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala @@ -1,19 +1,14 @@ -package dotty.tools.pc +package dotty.tools +package pc import scala.annotation.tailrec -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.ast.tpd.* -import dotty.tools.dotc.ast.untpd -import dotty.tools.dotc.core.Contexts.* -import dotty.tools.dotc.core.Flags.* -import dotty.tools.dotc.core.Names.Name -import dotty.tools.dotc.core.StdNames -import dotty.tools.dotc.core.Symbols.* -import dotty.tools.dotc.core.Types.Type -import dotty.tools.dotc.interactive.SourceTree -import dotty.tools.dotc.util.SourceFile -import dotty.tools.dotc.util.SourcePosition +import dotc.* +import ast.*, tpd.* +import core.*, Contexts.*, Decorators.*, Flags.*, Names.*, Symbols.*, Types.* +import interactive.* +import util.* +import util.SourcePosition object MetalsInteractive: @@ -190,7 +185,7 @@ object MetalsInteractive: */ case (tpt: TypeTree) :: parent :: _ if tpt.span != parent.span && !tpt.symbol.is(Synthetic) => - List((tpt.symbol, tpt.tpe)) + List((tpt.symbol, tpt.typeOpt)) /* TypeTest class https://dotty.epfl.ch/docs/reference/other-new-features/type-test.html * compiler automatically adds unapply if possible, we need to find the type symbol @@ -205,7 +200,10 @@ object MetalsInteractive: Nil case path @ head :: tail => - if head.symbol.is(Synthetic) then + if head.symbol.is(Exported) then + val sym = head.symbol.sourceSymbol + List((sym, sym.info)) + else if head.symbol.is(Synthetic) then enclosingSymbolsWithExpressionType( tail, pos, @@ -222,7 +220,7 @@ object MetalsInteractive: then List((head.symbol, head.typeOpt)) /* Type tree for List(1) has an Int type variable, which has span * but doesn't exist in code. - * https://github.com/lampepfl/dotty/issues/15937 + * https://github.com/scala/scala3/issues/15937 */ else if head.isInstanceOf[TypeTree] then enclosingSymbolsWithExpressionType(tail, pos, indexed) diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala index 310edd60d87e..60def237badb 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala @@ -57,13 +57,13 @@ abstract class PcCollector[T]( .pathTo(driver.openedTrees(uri), pos)(using driver.currentCtx) .dropWhile(t => // NamedArg anyway doesn't have symbol t.symbol == NoSymbol && !t.isInstanceOf[NamedArg] || - // same issue https://github.com/lampepfl/dotty/issues/15937 as below + // same issue https://github.com/scala/scala3/issues/15937 as below t.isInstanceOf[TypeTree] ) val path = rawPath match // For type it will sometimes go into the wrong tree since TypeTree also contains the same span - // https://github.com/lampepfl/dotty/issues/15937 + // https://github.com/scala/scala3/issues/15937 case TypeApply(sel: Select, _) :: tail if sel.span.contains(pos.span) => Interactive.pathTo(sel, pos.span) ::: rawPath case _ => rawPath @@ -583,7 +583,7 @@ abstract class PcCollector[T]( t } - // NOTE: Connected to https://github.com/lampepfl/dotty/issues/16771 + // NOTE: Connected to https://github.com/scala/scala3/issues/16771 // `sel.nameSpan` is calculated incorrectly in (1 + 2).toString // See test DocumentHighlightSuite.select-parentheses private def selectNameSpan(sel: Select): Span = diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala index f010c8b2d95a..0de81ec39711 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala @@ -108,7 +108,7 @@ class PcDefinitionProvider( case Nil => path.headOption match case Some(value: Literal) => - definitionsForSymbol(List(value.tpe.widen.typeSymbol), pos) + definitionsForSymbol(List(value.typeOpt.widen.typeSymbol), pos) case _ => DefinitionResultImpl.empty case _ => definitionsForSymbol(typeSymbols, pos) @@ -124,7 +124,7 @@ class PcDefinitionProvider( val isLocal = sym.source == pos.source if isLocal then val defs = - Interactive.findDefinitions(List(sym), driver, false, false) + Interactive.findDefinitions(List(sym), driver, false, false).filter(_.source == sym.source) defs.headOption match case Some(srcTree) => val pos = srcTree.namePos diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcSyntheticDecorationProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/PcSyntheticDecorationProvider.scala index 1ff410ad7f10..d810ce5b07cc 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcSyntheticDecorationProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcSyntheticDecorationProvider.scala @@ -39,6 +39,8 @@ final class PcSyntheticDecorationsProvider( val source = SourceFile.virtual(filePath.toString, sourceText) driver.run(uri, source) + + given InferredType.Text = InferredType.Text(text) given ctx: Context = driver.currentCtx val unit = driver.currentCtx.run.nn.units.head @@ -112,7 +114,7 @@ final class PcSyntheticDecorationsProvider( ): String = val tpdPath = Interactive.pathTo(unit.tpdTree, pos.span) - + val indexedCtx = IndexedContext(Interactive.contextOfPath(tpdPath)) val printer = ShortenedTypePrinter( symbolSearch @@ -208,7 +210,7 @@ object TypeParameters: case sel: Select if sel.isInfix => sel.sourcePos.withEnd(sel.nameSpan.end) case _ => fun.sourcePos - val tpes = args.map(_.tpe.stripTypeVar.widen.finalResultType) + val tpes = args.map(_.typeOpt.stripTypeVar.widen.finalResultType) Some((tpes, pos.endPos, fun)) case _ => None private def inferredTypeArgs(args: List[Tree]): Boolean = @@ -219,13 +221,18 @@ object TypeParameters: end TypeParameters object InferredType: - def unapply(tree: Tree)(using Context) = + opaque type Text = Array[Char] + object Text: + def apply(text: Array[Char]): Text = text + + def unapply(tree: Tree)(using text: Text, cxt: Context) = tree match case vd @ ValDef(_, tpe, _) if isValidSpan(tpe.span, vd.nameSpan) && - !vd.symbol.is(Flags.Enum) => + !vd.symbol.is(Flags.Enum) && + !isValDefBind(text, vd) => if vd.symbol == vd.symbol.sourceSymbol then - Some(tpe.tpe, tpe.sourcePos.withSpan(vd.nameSpan), vd) + Some(tpe.typeOpt, tpe.sourcePos.withSpan(vd.nameSpan), vd) else None case vd @ DefDef(_, _, tpe, _) if isValidSpan(tpe.span, vd.nameSpan) && @@ -233,7 +240,7 @@ object InferredType: !vd.symbol.isConstructor && !vd.symbol.is(Flags.Mutable) => if vd.symbol == vd.symbol.sourceSymbol then - Some(tpe.tpe, tpe.sourcePos, vd) + Some(tpe.typeOpt, tpe.sourcePos, vd) else None case bd @ Bind( name, @@ -247,6 +254,14 @@ object InferredType: nameSpan.exists && !nameSpan.isZeroExtent + /* If is left part of val definition bind: + * val <<t>> @ ... = + */ + def isValDefBind(text: Text, vd: ValDef)(using Context) = + val afterDef = text.drop(vd.nameSpan.end) + val index = afterDef.indexAfterSpacesAndComments + index >= 0 && index < afterDef.size && afterDef(index) == '@' + end InferredType case class Synthetics( @@ -275,4 +290,4 @@ case class Synthetics( end Synthetics object Synthetics: - def empty: Synthetics = Synthetics(Nil, Set.empty) \ No newline at end of file + def empty: Synthetics = Synthetics(Nil, Set.empty) diff --git a/presentation-compiler/src/main/dotty/tools/pc/SemanticdbSymbols.scala b/presentation-compiler/src/main/dotty/tools/pc/SemanticdbSymbols.scala index c6e43186cef2..d298a88fc655 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/SemanticdbSymbols.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/SemanticdbSymbols.scala @@ -49,7 +49,16 @@ object SemanticdbSymbols: // however in scalac this method is defined only in `module Files` if typeSym.is(JavaDefined) then typeSym :: owner.info.decl(termName(value)).symbol :: Nil + /** + * Looks like decl doesn't work for: + * package a: + * implicit class <<A>> (i: Int): + * def inc = i + 1 + */ + else if typeSym == NoSymbol then + owner.info.member(typeName(value)).symbol :: Nil else typeSym :: Nil + end if case Descriptor.Term(value) => val outSymbol = owner.info.decl(termName(value)).symbol if outSymbol.exists @@ -92,6 +101,8 @@ object SemanticdbSymbols: .map(_.symbol) .filter(sym => symbolName(sym) == s) .toList + end match + end tryMember parentSymbol.flatMap(tryMember) try @@ -107,8 +118,8 @@ object SemanticdbSymbols: b.toString /** - * Taken from https://github.com/lampepfl/dotty/blob/2db43dae1480825227eb30d291b0dd0f0494e0f6/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala#L293 - * In future might be replaced by usage of compiler implementation after merging https://github.com/lampepfl/dotty/pull/12885 + * Taken from https://github.com/scala/scala3/blob/2db43dae1480825227eb30d291b0dd0f0494e0f6/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala#L293 + * In future might be replaced by usage of compiler implementation after merging https://github.com/scala/scala3/pull/12885 */ private def addSymName(b: StringBuilder, sym: Symbol)(using Context): Unit = diff --git a/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala index bfaa56138547..f7797efbfb27 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala @@ -1,134 +1,149 @@ package dotty.tools.pc -import scala.jdk.CollectionConverters._ -import scala.meta.pc.OffsetParams -import scala.meta.pc.SymbolDocumentation -import scala.meta.pc.SymbolSearch - -import dotty.tools.dotc.ast.Trees.AppliedTypeTree -import dotty.tools.dotc.ast.Trees.TypeApply -import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Contexts.* import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.interactive.Interactive import dotty.tools.dotc.interactive.InteractiveDriver +import dotty.tools.dotc.parsing.Tokens.closingRegionTokens +import dotty.tools.dotc.reporting.ErrorMessageID +import dotty.tools.dotc.reporting.ExpectedTokenButFound import dotty.tools.dotc.util.Signatures -import dotty.tools.dotc.util.Signatures.Signature import dotty.tools.dotc.util.SourceFile -import dotty.tools.dotc.util.SourcePosition +import dotty.tools.dotc.util.Spans +import dotty.tools.dotc.util.Spans.Span +import dotty.tools.pc.printer.ShortenedTypePrinter +import dotty.tools.pc.printer.ShortenedTypePrinter.IncludeDefaultParam import dotty.tools.pc.utils.MtagsEnrichments.* - import org.eclipse.lsp4j as l +import scala.jdk.CollectionConverters.* +import scala.jdk.OptionConverters.* +import scala.meta.internal.metals.ReportContext +import scala.meta.pc.OffsetParams +import scala.meta.pc.SymbolDocumentation +import scala.meta.pc.SymbolSearch + object SignatureHelpProvider: def signatureHelp( driver: InteractiveDriver, params: OffsetParams, search: SymbolSearch - ) = - val uri = params.uri() - val sourceFile = SourceFile.virtual(params.uri().nn, params.text().nn) + )(using ReportContext): l.SignatureHelp = + val uri = params.uri().nn + val text = params.text().nn + val sourceFile = SourceFile.virtual(uri, text) driver.run(uri.nn, sourceFile) - given ctx: Context = driver.currentCtx - - val pos = driver.sourcePosition(params) - val trees = driver.openedTrees(uri.nn) - - val path = Interactive.pathTo(trees, pos) - - val (paramN, callableN, alternatives) = - Signatures.signatureHelp(path, pos.span) - val infos = alternatives.flatMap { signature => - signature.denot.map { - (signature, _) - } - } - - val signatureInfos = infos.map { case (signature, denot) => - search.symbolDocumentation(denot.symbol) match - case Some(doc) => - withDocumentation( - doc, - signature, - denot.symbol.is(Flags.JavaDefined) - ).getOrElse(signature) - case _ => signature - - } - - /* Versions prior to 3.2.1 did not support type parameters - * so we need to skip them. - */ - new l.SignatureHelp( - signatureInfos.map(signatureToSignatureInformation).asJava, - callableN, - paramN - ) + driver.compilationUnits.get(uri) match + case Some(unit) => + + val pos = driver.sourcePosition(params, isZeroExtent = false) + val path = Interactive.pathTo(unit.tpdTree, pos.span)(using driver.currentCtx) + + val localizedContext = Interactive.contextOfPath(path)(using driver.currentCtx) + val indexedContext = IndexedContext(driver.currentCtx) + + given Context = localizedContext.fresh + .setCompilationUnit(unit) + .setPrinterFn(_ => ShortenedTypePrinter(search, IncludeDefaultParam.Never)(using indexedContext)) + + val (paramN, callableN, alternatives) = Signatures.signatureHelp(path, pos.span) + + val infos = alternatives.flatMap: signature => + signature.denot.map(signature -> _) + + val signatureInfos = infos.map { case (signature, denot) => + search.symbolDocumentation(denot.symbol) match + case Some(doc) => + withDocumentation( + doc, + signature, + denot.symbol.is(Flags.JavaDefined) + ).getOrElse(signature) + case _ => signature + + } + + new l.SignatureHelp( + signatureInfos.map(signatureToSignatureInformation).asJava, + callableN, + paramN + ) + case _ => new l.SignatureHelp() end signatureHelp private def withDocumentation( info: SymbolDocumentation, signature: Signatures.Signature, isJavaSymbol: Boolean - ): Option[Signature] = - val allParams = info.parameters().nn.asScala - def updateParams( - params: List[Signatures.Param], - index: Int - ): List[Signatures.Param] = + ): Option[Signatures.Signature] = + val methodParams = info.parameters().nn.asScala + val typeParams = info.typeParameters().nn.asScala + + def updateParams(params: List[Signatures.Param], typeParamIndex: Int, methodParamIndex: Int): List[Signatures.Param] = params match - case Nil => Nil - case head :: tail => - val rest = updateParams(tail, index + 1) - allParams.lift(index) match + case (head: Signatures.MethodParam) :: tail => + val rest = updateParams(tail, typeParamIndex, methodParamIndex + 1) + methodParams.lift(methodParamIndex) match case Some(paramDoc) => val newName = if isJavaSymbol && head.name.startsWith("x$") then paramDoc.nn.displayName() else head.name - head.copy( - doc = Some(paramDoc.docstring.nn), - name = newName.nn - ) :: rest + head.copy(name = newName.nn, doc = Some(paramDoc.docstring.nn)) :: rest + case _ => head :: rest + case (head: Signatures.TypeParam) :: tail => + val rest = updateParams(tail, typeParamIndex + 1, methodParamIndex) + typeParams.lift(typeParamIndex) match + case Some(paramDoc) => + head.copy(doc = Some(paramDoc.docstring.nn)) :: rest case _ => head :: rest + case _ => Nil def updateParamss( params: List[List[Signatures.Param]], - index: Int + typeParamIndex: Int, + methodParamIndex: Int ): List[List[Signatures.Param]] = params match case Nil => Nil case head :: tail => - val updated = updateParams(head, index) - updated :: updateParamss(tail, index + head.size) - val updatedParams = updateParamss(signature.paramss, 0) + val updated = updateParams(head, typeParamIndex, methodParamIndex) + val (nextTypeParamIndex, nextMethodParamIndex) = head match + case (_: Signatures.MethodParam) :: _ => (typeParamIndex, methodParamIndex + head.size) + case (_: Signatures.TypeParam) :: _ => (typeParamIndex + head.size, methodParamIndex) + case _ => (typeParamIndex, methodParamIndex) + updated :: updateParamss(tail, nextTypeParamIndex, nextMethodParamIndex) + val updatedParams = updateParamss(signature.paramss, 0, 0) Some(signature.copy(doc = Some(info.docstring().nn), paramss = updatedParams)) end withDocumentation private def signatureToSignatureInformation( signature: Signatures.Signature ): l.SignatureInformation = - val tparams = signature.tparams.map(Signatures.Param("", _)) - val paramInfoss = - (tparams ::: signature.paramss.flatten).map(paramToParameterInformation) + val paramInfoss = (signature.paramss.flatten).map(paramToParameterInformation) val paramLists = - if signature.paramss.forall(_.isEmpty) && tparams.nonEmpty then "" - else - signature.paramss - .map { paramList => - val labels = paramList.map(_.show) - val prefix = if paramList.exists(_.isImplicit) then "using " else "" - labels.mkString(prefix, ", ", "") - } - .mkString("(", ")(", ")") - val tparamsLabel = - if signature.tparams.isEmpty then "" - else signature.tparams.mkString("[", ", ", "]") + signature.paramss + .map { paramList => + val labels = paramList.map(_.show) + val isImplicit = paramList.exists: + case p: Signatures.MethodParam => p.isImplicit + case _ => false + val prefix = if isImplicit then "using " else "" + val isTypeParams = paramList.forall(_.isInstanceOf[Signatures.TypeParam]) && paramList.nonEmpty + val wrap: String => String = label => if isTypeParams then + s"[$label]" + else + s"($label)" + wrap(labels.mkString(prefix, ", ", "")) + }.mkString + + val returnTypeLabel = signature.returnType.map(t => s": $t").getOrElse("") - val label = s"${signature.name}$tparamsLabel$paramLists$returnTypeLabel" + val label = s"${signature.name}$paramLists$returnTypeLabel" val documentation = signature.doc.map(markupContent) val sig = new l.SignatureInformation(label) sig.setParameters(paramInfoss.asJava) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala index a0cf6bafcf46..53d867c924a6 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala @@ -5,22 +5,20 @@ import java.net.URI import scala.meta.pc.OffsetParams -import dotty.tools.dotc.ast.tpd.* +import dotty.tools.dotc.ast.untpd.* import dotty.tools.dotc.ast.untpd.ImportSelector import dotty.tools.dotc.core.Contexts.* import dotty.tools.dotc.core.StdNames.* import dotty.tools.dotc.util.Chars import dotty.tools.dotc.util.SourcePosition import dotty.tools.dotc.util.Spans +import dotty.tools.dotc.interactive.Completion import dotty.tools.pc.utils.MtagsEnrichments.* import org.eclipse.lsp4j as l - -enum CompletionKind: - case Empty, Scope, Members +import scala.annotation.tailrec case class CompletionPos( - kind: CompletionKind, start: Int, end: Int, query: String, @@ -39,27 +37,21 @@ object CompletionPos: def infer( cursorPos: SourcePosition, offsetParams: OffsetParams, - treePath: List[Tree] + adjustedPath: List[Tree] )(using Context): CompletionPos = - infer(cursorPos, offsetParams.uri().nn, offsetParams.text().nn, treePath) + infer(cursorPos, offsetParams.uri().nn, offsetParams.text().nn, adjustedPath) def infer( cursorPos: SourcePosition, uri: URI, text: String, - treePath: List[Tree] + adjustedPath: List[Tree] )(using Context): CompletionPos = - val start = inferIdentStart(cursorPos, text, treePath) - val end = inferIdentEnd(cursorPos, text) - val query = text.substring(start, end) - val prevIsDot = - if start - 1 >= 0 then text.charAt(start - 1) == '.' else false - val kind = - if query.nn.isEmpty() && !prevIsDot then CompletionKind.Empty - else if prevIsDot then CompletionKind.Members - else CompletionKind.Scope + val identEnd = inferIdentEnd(cursorPos, text) + val query = Completion.completionPrefix(adjustedPath, cursorPos) + val start = cursorPos.point - query.length() - CompletionPos(kind, start, end, query.nn, cursorPos, uri) + CompletionPos(start, identEnd, query.nn, cursorPos, uri) end infer /** @@ -84,42 +76,6 @@ object CompletionPos: (i, tabIndented) end inferIndent - /** - * Returns the start offset of the identifier starting as the given offset position. - */ - private def inferIdentStart( - pos: SourcePosition, - text: String, - path: List[Tree] - )(using Context): Int = - def fallback: Int = - var i = pos.point - 1 - while i >= 0 && Chars.isIdentifierPart(text.charAt(i)) do i -= 1 - i + 1 - def loop(enclosing: List[Tree]): Int = - enclosing match - case Nil => fallback - case head :: tl => - if !head.sourcePos.contains(pos) then loop(tl) - else - head match - case i: Ident => i.sourcePos.point - case s: Select => - if s.name.toTermName == nme.ERROR || s.span.exists && pos.span.point < s.span.point - then fallback - else s.span.point - case Import(_, sel) => - sel - .collectFirst { - case ImportSelector(imported, renamed, _) - if imported.sourcePos.contains(pos) => - imported.sourcePos.point - } - .getOrElse(fallback) - case _ => fallback - loop(path) - end inferIdentStart - /** * Returns the end offset of the identifier starting as the given offset position. */ diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala index f008ea5a9dbb..710e91750362 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala @@ -13,6 +13,7 @@ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Phases import dotty.tools.dotc.core.StdNames import dotty.tools.dotc.interactive.Interactive import dotty.tools.dotc.interactive.InteractiveDriver @@ -53,14 +54,16 @@ class CompletionProvider( val (items, isIncomplete) = driver.compilationUnits.get(uri) match case Some(unit) => - val newctx = ctx.fresh.setCompilationUnit(unit) + val newctx = ctx.fresh.setCompilationUnit(unit).withPhase(Phases.typerPhase(using ctx)) val tpdPath = Interactive.pathTo(newctx.compilationUnit.tpdTree, pos.span)(using newctx) + val adjustedPath = Interactive.resolveTypedOrUntypedPath(tpdPath, pos)(using newctx) - val locatedCtx = - Interactive.contextOfPath(tpdPath)(using newctx) + val locatedCtx = Interactive.contextOfPath(tpdPath)(using newctx) val indexedCtx = IndexedContext(locatedCtx) + val completionPos = - CompletionPos.infer(pos, params, tpdPath)(using newctx) + CompletionPos.infer(pos, params, adjustedPath)(using locatedCtx) + val autoImportsGen = AutoImports.generator( completionPos.sourcePos, text, @@ -69,16 +72,18 @@ class CompletionProvider( indexedCtx, config ) + val (completions, searchResult) = new Completions( pos, text, - ctx.fresh.setCompilationUnit(unit), + locatedCtx, search, buildTargetIdentifier, completionPos, indexedCtx, tpdPath, + adjustedPath, config, folderPath, autoImportsGen, @@ -94,7 +99,7 @@ class CompletionProvider( completionPos, tpdPath, indexedCtx - )(using newctx) + )(using locatedCtx) } val isIncomplete = searchResult match case SymbolSearch.Result.COMPLETE => false @@ -152,7 +157,7 @@ class CompletionProvider( // For overloaded signatures we get multiple symbols, so we need // to recalculate the description - // related issue https://github.com/lampepfl/dotty/issues/11941 + // related issue https://github.com/scala/scala3/issues/11941 lazy val kind: CompletionItemKind = completion.completionItemKind val description = completion.description(printer) val label = completion.labelWithDescription(printer) @@ -215,7 +220,7 @@ class CompletionProvider( def mkItemWithImports( v: CompletionValue.Workspace | CompletionValue.Extension | - CompletionValue.Interpolator + CompletionValue.Interpolator | CompletionValue.ImplicitClass ) = val sym = v.symbol path match @@ -238,21 +243,29 @@ class CompletionProvider( r match case IndexedContext.Result.InScope => mkItem( - ident.backticked(backtickSoftKeyword) + completionTextSuffix + v.insertText.getOrElse( + ident.backticked( + backtickSoftKeyword + ) + completionTextSuffix + ), + range = v.range, ) case _ if isInStringInterpolation => mkItem( - "{" + sym.fullNameBackticked + completionTextSuffix + "}" + "{" + sym.fullNameBackticked + completionTextSuffix + "}", + range = v.range ) case _ if v.isExtensionMethod => mkItem( - ident.backticked(backtickSoftKeyword) + completionTextSuffix + ident.backticked(backtickSoftKeyword) + completionTextSuffix, + range = v.range ) case _ => mkItem( sym.fullNameBackticked( backtickSoftKeyword - ) + completionTextSuffix + ) + completionTextSuffix, + range = v.range ) end match end match @@ -260,7 +273,7 @@ class CompletionProvider( end mkItemWithImports completion match - case v: (CompletionValue.Workspace | CompletionValue.Extension) => + case v: (CompletionValue.Workspace | CompletionValue.Extension | CompletionValue.ImplicitClass) => mkItemWithImports(v) case v: CompletionValue.Interpolator if v.isWorkspace || v.isExtension => mkItemWithImports(v) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala index a5b2fb40f418..2810fe728b9a 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala @@ -4,7 +4,9 @@ package completions import scala.meta.internal.pc.CompletionItemData import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Denotations.Denotation import dotty.tools.dotc.core.Flags.* +import dotty.tools.dotc.core.StdNames.nme import dotty.tools.dotc.core.Symbols.Symbol import dotty.tools.dotc.core.Types.Type import dotty.tools.pc.printer.ShortenedTypePrinter @@ -33,6 +35,7 @@ enum CompletionSource: case MatchCompletionKind case CaseKeywordKind case DocumentKind + case ImplicitClassKind sealed trait CompletionValue: def label: String @@ -61,7 +64,8 @@ end CompletionValue object CompletionValue: sealed trait Symbolic extends CompletionValue: - def symbol: Symbol + def denotation: Denotation + val symbol = denotation.symbol def isFromWorkspace: Boolean = false override def completionItemDataKind = CompletionItemData.None def isExtensionMethod: Boolean = false @@ -105,7 +109,7 @@ object CompletionValue: s"${label}${description(printer)}" else s"$label: ${description(printer)}" - private def labelWithSuffix(printer: ShortenedTypePrinter)(using Context): String = + protected def labelWithSuffix(printer: ShortenedTypePrinter)(using Context): String = if snippetSuffix.addLabelSnippet then val printedParams = symbol.info.typeParams.map(p => @@ -114,41 +118,60 @@ object CompletionValue: s"${label}${printedParams.mkString("[", ",", "]")}" else label - override def description(printer: ShortenedTypePrinter)( - using Context - ): String = - printer.completionSymbol(symbol) + override def description(printer: ShortenedTypePrinter)(using Context): String = + printer.completionSymbol(denotation) + end Symbolic case class Compiler( label: String, - symbol: Symbol, + denotation: Denotation, override val snippetSuffix: CompletionSuffix - ) extends Symbolic { + ) extends Symbolic: override def completionItemDataKind: Integer = CompletionSource.CompilerKind.ordinal - } + case class Scope( label: String, - symbol: Symbol, + denotation: Denotation, override val snippetSuffix: CompletionSuffix, - ) extends Symbolic { + ) extends Symbolic: override def completionItemDataKind: Integer = CompletionSource.ScopeKind.ordinal - } + case class Workspace( label: String, - symbol: Symbol, + denotation: Denotation, override val snippetSuffix: CompletionSuffix, override val importSymbol: Symbol ) extends Symbolic: override def isFromWorkspace: Boolean = true override def completionItemDataKind: Integer = CompletionSource.WorkspaceKind.ordinal + override def labelWithDescription(printer: ShortenedTypePrinter)(using Context): String = + if symbol.is(Method) && symbol.name != nme.apply then + s"${labelWithSuffix(printer)} - ${printer.fullNameString(symbol.effectiveOwner)}" + else super.labelWithDescription(printer) + + /** + * CompletionValue for old implicit classes methods via SymbolSearch + */ + case class ImplicitClass( + label: String, + denotation: Denotation, + override val snippetSuffix: CompletionSuffix, + override val importSymbol: Symbol, + ) extends Symbolic: + override def completionItemKind(using Context): CompletionItemKind = + CompletionItemKind.Method + override def completionItemDataKind: Integer = CompletionSource.ImplicitClassKind.ordinal + override def description(printer: ShortenedTypePrinter)(using Context): String = + s"${printer.completionSymbol(denotation)} (implicit)" + /** * CompletionValue for extension methods via SymbolSearch */ case class Extension( label: String, - symbol: Symbol, + denotation: Denotation, override val snippetSuffix: CompletionSuffix ) extends Symbolic: override def completionItemKind(using Context): CompletionItemKind = @@ -156,7 +179,7 @@ object CompletionValue: override def completionItemDataKind: Integer = CompletionSource.ExtensionKind.ordinal override def isExtensionMethod: Boolean = true override def description(printer: ShortenedTypePrinter)(using Context): String = - s"${printer.completionSymbol(symbol)} (extension)" + s"${printer.completionSymbol(denotation)} (extension)" /** * @param shortenedNames shortened type names by `Printer`. This field should be used for autoImports @@ -169,7 +192,7 @@ object CompletionValue: case class Override( label: String, value: String, - symbol: Symbol, + denotation: Denotation, override val additionalEdits: List[TextEdit], override val filterText: Option[String], override val range: Option[Range] @@ -185,7 +208,7 @@ object CompletionValue: case class NamedArg( label: String, tpe: Type, - symbol: Symbol + denotation: Denotation ) extends Symbolic: override def insertText: Option[String] = Some(label.replace("$", "$$").nn) override def completionItemDataKind: Integer = CompletionSource.OverrideKind.ordinal @@ -235,7 +258,7 @@ object CompletionValue: CompletionItemKind.Folder case class Interpolator( - symbol: Symbol, + denotation: Denotation, label: String, override val insertText: Option[String], override val additionalEdits: List[TextEdit], @@ -251,6 +274,7 @@ object CompletionValue: )(using Context): String = if isExtension then s"${printer.completionSymbol(symbol)} (extension)" else super.description(printer) + override def isExtensionMethod: Boolean = isExtension end Interpolator case class MatchCompletion( @@ -266,7 +290,7 @@ object CompletionValue: desc case class CaseKeyword( - symbol: Symbol, + denotation: Denotation, label: String, override val insertText: Option[String], override val additionalEdits: List[TextEdit], diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala index 1e2dbb5cdaa1..d6ca15b35129 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala @@ -12,6 +12,7 @@ import scala.meta.internal.pc.{IdentifierComparator, MemberOrdering} import scala.meta.pc.* import dotty.tools.dotc.ast.tpd.* +import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.ast.NavigateAST import dotty.tools.dotc.core.Comments.Comment import dotty.tools.dotc.core.Constants.Constant @@ -27,13 +28,13 @@ import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.interactive.Completion import dotty.tools.dotc.interactive.Completion.Mode import dotty.tools.dotc.util.SourcePosition -import dotty.tools.dotc.util.Spans -import dotty.tools.dotc.util.Spans.Span import dotty.tools.dotc.util.SrcPos import dotty.tools.pc.AutoImports.AutoImportsGenerator import dotty.tools.pc.completions.OverrideCompletions.OverrideExtractor import dotty.tools.pc.buildinfo.BuildInfo import dotty.tools.pc.utils.MtagsEnrichments.* +import dotty.tools.dotc.core.Denotations.SingleDenotation +import dotty.tools.dotc.interactive.Interactive class Completions( pos: SourcePosition, @@ -44,6 +45,7 @@ class Completions( completionPos: CompletionPos, indexedContext: IndexedContext, path: List[Tree], + adjustedPath: List[untpd.Tree], config: PresentationCompilerConfig, workspace: Option[Path], autoImports: AutoImportsGenerator, @@ -51,16 +53,10 @@ class Completions( options: List[String] )(using ReportContext): - implicit val context: Context = ctx + given context: Context = ctx - val coursierComplete = new CoursierComplete(BuildInfo.scalaVersion) - - private lazy val adjustedPath = Completion.resolveTypedOrUntypedPath(path, pos) - private lazy val completionMode = - val mode = Completion.completionMode(adjustedPath, pos) - path match - case Literal(Constant(_: String)) :: _ => Mode.Term // literal completions - case _ => mode + private lazy val coursierComplete = new CoursierComplete(BuildInfo.scalaVersion) + private lazy val completionMode = Completion.completionMode(adjustedPath, pos) private lazy val shouldAddSnippet = path match @@ -72,8 +68,8 @@ class Completions( case _ :: (withcursor @ Select(fun, name)) :: (appl: GenericApply) :: _ if appl.fun == withcursor && name.decoded == Cursor.value => false - case (_: Import) :: _ => false - case _ :: (_: Import) :: _ => false + case (_: (Import | Export)) :: _ => false + case _ :: (_: (Import | Export)) :: _ => false case (_: Ident) :: (_: SeqLiteral) :: _ => false case _ => true @@ -122,17 +118,19 @@ class Completions( // should not show completions for toplevel case Nil | (_: PackageDef) :: _ if pos.source.file.extension != "sc" => (allAdvanced, SymbolSearch.Result.COMPLETE) - case Select(qual, _) :: _ if qual.tpe.isErroneous => + case Select(qual, _) :: _ if qual.typeOpt.isErroneous => (allAdvanced, SymbolSearch.Result.COMPLETE) case Select(qual, _) :: _ => - val (_, compilerCompletions) = Completion.completions(pos) + val compilerCompletions = Completion.rawCompletions(pos, completionMode, completionPos.query, path, adjustedPath) val (compiler, result) = compilerCompletions + .toList .flatMap(toCompletionValues) .filterInteresting(qual.typeOpt.widenDealias) (allAdvanced ++ compiler, result) case _ => - val (_, compilerCompletions) = Completion.completions(pos) + val compilerCompletions = Completion.rawCompletions(pos, completionMode, completionPos.query, path, adjustedPath) val (compiler, result) = compilerCompletions + .toList .flatMap(toCompletionValues) .filterInteresting() (allAdvanced ++ compiler, result) @@ -140,20 +138,21 @@ class Completions( val application = CompletionApplication.fromPath(path) val ordering = completionOrdering(application) - val values = application.postProcess(all.sorted(ordering)) + val sorted = all.sorted(ordering) + val values = application.postProcess(sorted) (values, result) end completions private def toCompletionValues( - completion: Completion + completion: Name, + denots: Seq[SingleDenotation] ): List[CompletionValue] = - completion.symbols.flatMap( + denots.toList.flatMap: denot => completionsWithSuffix( - _, - completion.label, - CompletionValue.Compiler(_, _, _) + denot, + completion.show, + (label, denot, suffix) => CompletionValue.Compiler(label, denot, suffix) ) - ) end toCompletionValues inline private def undoBacktick(label: String): String = @@ -228,35 +227,33 @@ class Completions( end findSuffix def completionsWithSuffix( - sym: Symbol, + denot: SingleDenotation, label: String, - toCompletionValue: (String, Symbol, CompletionSuffix) => CompletionValue + toCompletionValue: (String, SingleDenotation, CompletionSuffix) => CompletionValue ): List[CompletionValue] = - // workaround for earlier versions that force correctly detecting Java flags - - def companionSynthetic = sym.companion.exists && sym.companion.is(Synthetic) + val sym = denot.symbol // find the apply completion that would need a snippet - val methodSymbols = + val methodDenots: List[SingleDenotation] = if shouldAddSnippet && completionMode.is(Mode.Term) && - (sym.is(Flags.Module) || sym.isClass && !sym.is(Flags.Trait)) && !sym.is(Flags.JavaDefined) + (sym.is(Flags.Module) || sym.isField || sym.isClass && !sym.is(Flags.Trait)) && !sym.is(Flags.JavaDefined) then val info = /* Companion will be added even for normal classes now, * but it will not show up from classpath. We can suggest * constructors based on those synthetic applies. */ - if sym.isClass && companionSynthetic then sym.companionModule.info - else sym.info - val applSymbols = info.member(nme.apply).allSymbols - sym :: applSymbols - else List(sym) - - methodSymbols.map { methodSymbol => - val suffix = findSuffix(methodSymbol) + if sym.isClass && sym.companionModule.exists then sym.companionModule.info + else denot.info + val applyDenots = info.member(nme.apply).allSymbols.map(_.asSeenFrom(info).asSingleDenotation) + denot :: applyDenots + else denot :: Nil + + methodDenots.map { methodDenot => + val suffix = findSuffix(methodDenot.symbol) val name = undoBacktick(label) toCompletionValue( name, - methodSymbol, + methodDenot, suffix ) } @@ -441,6 +438,10 @@ class Completions( true, ) + case (tree: (Import | Export)) :: _ + if tree.selectors.exists(_.renamed.sourcePos.contains(pos)) => + (List.empty, true) + // From Scala 3.1.3-RC3 (as far as I know), path contains // `Literal(Constant(null))` on head for an incomplete program, in this case, just ignore the head. case Literal(Constant(null)) :: tl => @@ -494,44 +495,64 @@ class Completions( qualType: Type = ctx.definitions.AnyType ): Option[SymbolSearch.Result] = val query = completionPos.query - completionPos.kind match - case CompletionKind.Empty => - val filtered = indexedContext.scopeSymbols - .filter(sym => - !sym.isConstructor && (!sym.is(Synthetic) || sym.is(Module)) - ) - - filtered.map { sym => - visit(CompletionValue.Scope(sym.decodedName, sym, findSuffix(sym))) - } - Some(SymbolSearch.Result.INCOMPLETE) - case CompletionKind.Scope => - val visitor = new CompilerSearchVisitor(sym => - indexedContext.lookupSym(sym) match - case IndexedContext.Result.InScope => - visit(CompletionValue.Scope(sym.decodedName, sym, findSuffix(sym))) - case _ => - completionsWithSuffix( - sym, - sym.decodedName, - CompletionValue.Workspace(_, _, _, sym) - ).map(visit).forall(_ == true), - ) - Some(search.search(query, buildTargetIdentifier, visitor).nn) - case CompletionKind.Members => - val visitor = new CompilerSearchVisitor(sym => - if sym.is(ExtensionMethod) && - qualType.widenDealias <:< sym.extensionParam.info.widenDealias - then + if completionMode.is(Mode.Scope) && query.nonEmpty then + val visitor = new CompilerSearchVisitor(sym => + indexedContext.lookupSym(sym) match + case IndexedContext.Result.InScope => false + case _ => completionsWithSuffix( sym, sym.decodedName, - CompletionValue.Extension(_, _, _) - ).map(visit).forall(_ == true) - else false, - ) - Some(search.searchMethods(query, buildTargetIdentifier, visitor).nn) - end match + CompletionValue.Workspace(_, _, _, sym) + ).map(visit).forall(_ == true), + ) + Some(search.search(query, buildTargetIdentifier, visitor).nn) + else if completionMode.is(Mode.Member) then + val visitor = new CompilerSearchVisitor(sym => + def isExtensionMethod = sym.is(ExtensionMethod) && + qualType.widenDealias <:< sym.extensionParam.info.widenDealias + def isImplicitClass(owner: Symbol) = + val constructorParam = + owner.info + .membersBasedOnFlags( + Flags.ParamAccessor, + Flags.EmptyFlags, + ) + .headOption + .map(_.info) + owner.isClass && owner.is(Flags.Implicit) && + constructorParam.exists(p => + qualType.widenDealias <:< p.widenDealias + ) + end isImplicitClass + + def isImplicitClassMethod = sym.is(Flags.Method) && !sym.isConstructor && + isImplicitClass(sym.maybeOwner) + + if isExtensionMethod then + completionsWithSuffix( + sym, + sym.decodedName, + CompletionValue.Extension(_, _, _) + ).map(visit).forall(_ == true) + else if isImplicitClassMethod then + completionsWithSuffix( + sym, + sym.decodedName, + CompletionValue.ImplicitClass(_, _, _, sym.maybeOwner), + ).map(visit).forall(_ == true) + else false, + ) + Some(search.searchMethods(query, buildTargetIdentifier, visitor).nn) + else + val filtered = indexedContext.scopeSymbols + .filter(sym => !sym.isConstructor && (!sym.is(Synthetic) || sym.is(Module))) + + filtered.map { sym => + visit(CompletionValue.Scope(sym.decodedName, sym, findSuffix(sym))) + } + Some(SymbolSearch.Result.INCOMPLETE) + end enrichWithSymbolSearch extension (s: SrcPos) @@ -692,8 +713,8 @@ class Completions( // show the abstract members first if !ov.symbol.is(Deferred) then penalty |= MemberOrdering.IsNotAbstract penalty - case CompletionValue.Workspace(_, sym, _, _) => - symbolRelevance(sym) | (IsWorkspaceSymbol + sym.name.show.length()) + case CompletionValue.Workspace(_, denot, _, _) => + symbolRelevance(denot.symbol) | (IsWorkspaceSymbol + denot.name.show.length()) case sym: CompletionValue.Symbolic => symbolRelevance(sym.symbol) case _ => @@ -723,7 +744,7 @@ class Completions( items def forSelect(sel: Select): CompletionApplication = - val tpe = sel.qualifier.tpe + val tpe = sel.qualifier.typeOpt val members = tpe.allMembers.map(_.symbol).toSet new CompletionApplication: @@ -734,11 +755,11 @@ class Completions( isMember(symbol) && symbol.owner != tpe.typeSymbol def postProcess(items: List[CompletionValue]): List[CompletionValue] = items.map { - case CompletionValue.Compiler(label, sym, suffix) - if isMember(sym) => + case completion @ CompletionValue.Compiler(label, denot, suffix) + if isMember(completion.symbol) => CompletionValue.Compiler( label, - substituteTypeVars(sym), + substituteTypeVars(completion.symbol), suffix ) case other => other @@ -767,7 +788,8 @@ class Completions( val fuzzyCache = mutable.Map.empty[CompletionValue, Int] def compareLocalSymbols(s1: Symbol, s2: Symbol): Int = - if s1.isLocal && s2.isLocal then + if s1.isLocal && s2.isLocal && s1.sourcePos.exists && s2.sourcePos.exists + then val firstIsAfter = s1.srcPos.isAfter(s2.srcPos) if firstIsAfter then -1 else 1 else 0 @@ -809,6 +831,16 @@ class Completions( priority(o1) - priority(o2) end compareInApplyParams + def prioritizeKeywords(o1: CompletionValue, o2: CompletionValue): Int = + def priority(v: CompletionValue): Int = + v match + case _: CompletionValue.CaseKeyword => 0 + case _: CompletionValue.NamedArg => 1 + case _: CompletionValue.Keyword => 2 + case _ => 3 + + priority(o1) - priority(o2) + end prioritizeKeywords /** * Some completion values should be shown first such as CaseKeyword and * NamedArg @@ -885,7 +917,10 @@ class Completions( case _ => val byApplyParams = compareInApplyParams(o1, o2) if byApplyParams != 0 then byApplyParams - else compareByRelevance(o1, o2) + else + val keywords = prioritizeKeywords(o1, o2) + if keywords != 0 then keywords + else compareByRelevance(o1, o2) end compare end Completions diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala index 1d063bc6d873..95fbeec0cac0 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala @@ -83,14 +83,13 @@ object InterpolatorCompletions: case _: Select => true case _ => false } => - val allLiterals = parent match - case SeqLiteral(elems, _) => - elems - case _ => Nil - expr.elems.zip(allLiterals.tail).collectFirst { - case (i: (Ident | Select), literal) if literal == lit => - i - } + parent match + case SeqLiteral(elems, _) if elems.size > 0 => + expr.elems.zip(elems.tail).collectFirst { + case (i: (Ident | Select), literal) if literal == lit => + i + } + case _ => None end interpolatorMemberArg /** @@ -161,16 +160,16 @@ object InterpolatorCompletions: completions.completionsWithSuffix( sym, label, - (name, s, suffix) => + (name, denot, suffix) => CompletionValue.Interpolator( - s, + denot.symbol, label, Some(newText(name, suffix.toEditOpt, identOrSelect)), Nil, Some(cursor.withStart(identOrSelect.span.start).toLsp), // Needed for VS Code which will not show the completion otherwise Some(identOrSelect.name.toString() + "." + label), - s, + denot.symbol, isExtension = isExtension ), ) @@ -291,9 +290,9 @@ object InterpolatorCompletions: completions.completionsWithSuffix( sym, label, - (name, s, suffix) => + (name, denot, suffix) => CompletionValue.Interpolator( - s, + denot.symbol, label, Some(newText(name, suffix.toEditOpt)), additionalEdits(), diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala index a052a0a2c8eb..e912bc49032f 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala @@ -12,7 +12,6 @@ import dotty.tools.dotc.core.Comments import dotty.tools.dotc.core.Comments.Comment import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.util.SourcePosition -import dotty.tools.dotc.util.Spans.Span object KeywordsCompletions: diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala index a3d5d8814c48..edb489228d92 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala @@ -14,6 +14,7 @@ import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Definitions +import dotty.tools.dotc.core.Denotations.Denotation import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.StdNames @@ -74,8 +75,8 @@ object CaseKeywordCompletion: val parents: Parents = selector match case EmptyTree => val seenFromType = parent match - case TreeApply(fun, _) if !fun.tpe.isErroneous => fun.tpe - case _ => parent.tpe + case TreeApply(fun, _) if !fun.typeOpt.isErroneous => fun.typeOpt + case _ => parent.typeOpt seenFromType.paramInfoss match case (head :: Nil) :: _ if definitions.isFunctionType(head) || head.isRef( @@ -84,7 +85,7 @@ object CaseKeywordCompletion: val argTypes = head.argTypes.init new Parents(argTypes, definitions) case _ => new Parents(NoType, definitions) - case sel => new Parents(sel.tpe, definitions) + case sel => new Parents(sel.typeOpt, definitions) val selectorSym = parents.selector.widen.metalsDealias.typeSymbol @@ -163,13 +164,17 @@ object CaseKeywordCompletion: (si, label) } } - val caseItems = res.map((si, label) => - completionGenerator.toCompletionValue( - si.sym, - label, - autoImportsGen.renderImports(si.importSel.toList) - ) - ) + val caseItems = + if res.isEmpty then completionGenerator.caseKeywordOnly + else + res.map((si, label) => + completionGenerator.toCompletionValue( + si.sym, + label, + autoImportsGen.renderImports(si.importSel.toList), + ) + ) + includeExhaustive match // In `List(foo).map { cas@@} we want to provide also `case (exhaustive)` completion // which works like exhaustive match. @@ -240,7 +245,7 @@ object CaseKeywordCompletion: completionPos, clientSupportsSnippets ) - val tpe = selector.tpe.widen.metalsDealias.bounds.hi match + val tpe = selector.typeOpt.widen.metalsDealias.bounds.hi match case tr @ TypeRef(_, _) => tr.underlying case t => t @@ -440,8 +445,22 @@ class CompletionValueGenerator( end if end labelForCaseMember + def caseKeywordOnly: List[CompletionValue.Keyword] = + if patternOnly.isEmpty then + val label = "case" + val suffix = + if clientSupportsSnippets then " $0 =>" + else " " + List( + CompletionValue.Keyword( + label, + Some(label + suffix), + ) + ) + else Nil + def toCompletionValue( - sym: Symbol, + denot: Denotation, label: String, autoImport: Option[l.TextEdit] ): CompletionValue.CaseKeyword = @@ -449,7 +468,7 @@ class CompletionValueGenerator( (if patternOnly.nonEmpty then "" else " ") + (if clientSupportsSnippets then "$0" else "") CompletionValue.CaseKeyword( - sym, + denot, label, Some(label + cursorSuffix), autoImport.toList, diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala index e4ae4070edb9..6f244d9a3414 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala @@ -9,7 +9,6 @@ import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.ContextOps.localContext import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Definitions import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Flags.Method import dotty.tools.dotc.core.NameKinds.DefaultGetterName @@ -17,6 +16,7 @@ import dotty.tools.dotc.core.Names.Name import dotty.tools.dotc.core.StdNames.* import dotty.tools.dotc.core.SymDenotations.NoDenotation import dotty.tools.dotc.core.Symbols +import dotty.tools.dotc.core.Symbols.defn import dotty.tools.dotc.core.Symbols.NoSymbol import dotty.tools.dotc.core.Symbols.Symbol import dotty.tools.dotc.core.Types.AndType @@ -309,15 +309,17 @@ object NamedArgCompletions: val completionSymbols = indexedContext.scopeSymbols def matchingTypesInScope(paramType: Type): List[String] = - completionSymbols - .collect { - case sym - if sym.info <:< paramType && sym.isTerm && !sym.info.isErroneous && !sym.info.isNullType && !sym.info.isNothingType && !sym - .is(Flags.Method) && !sym.is(Flags.Synthetic) => - sym.decodedName - } - .filter(name => name != "Nil" && name != "None") - .sorted + if paramType != defn.AnyType then + completionSymbols + .collect { + case sym + if sym.info <:< paramType && sym.isTerm && !sym.info.isErroneous && !sym.info.isNullType && !sym.info.isNothingType && !sym + .is(Flags.Method) && !sym.is(Flags.Synthetic) => + sym.decodedName + } + .filter(name => name != "Nil" && name != "None") + .sorted + else Nil def findDefaultValue(param: ParamSymbol): String = val matchingType = matchingTypesInScope(param.info) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala index e7b1acb9aa87..8d96396999da 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala @@ -95,7 +95,7 @@ object OverrideCompletions: // not using `td.tpe.abstractTermMembers` because those members includes // the abstract members in `td.tpe`. For example, when we type `def foo@@`, // `td.tpe.abstractTermMembers` contains `method foo: <error>` and it overrides the parent `foo` method. - val overridables = td.tpe.parents + val overridables = td.typeOpt.parents .flatMap { parent => parent.membersBasedOnFlags( flags, @@ -279,7 +279,7 @@ object OverrideCompletions: else "" (indent, indent, lastIndent) end calcIndent - val abstractMembers = defn.tpe.abstractTermMembers.map(_.symbol) + val abstractMembers = defn.typeOpt.abstractTermMembers.map(_.symbol) val caseClassOwners = Set("Product", "Equals") val overridables = @@ -307,7 +307,7 @@ object OverrideCompletions: if edits.isEmpty then Nil else // A list of declarations in the class/object to implement - val decls = defn.tpe.decls.toList + val decls = defn.typeOpt.decls.toList .filter(sym => !sym.isPrimaryConstructor && !sym.isTypeParam && @@ -418,7 +418,7 @@ object OverrideCompletions: // `iterator` method in `new Iterable[Int] { def iterato@@ }` // should be completed as `def iterator: Iterator[Int]` instead of `Iterator[A]`. val seenFrom = - val memInfo = defn.tpe.memberInfo(sym.symbol) + val memInfo = defn.typeOpt.memberInfo(sym.symbol) if memInfo.isErroneous || memInfo.finalResultType.isAny then sym.info.widenTermRefExpr else memInfo diff --git a/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala b/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala index 9c255d20d212..3b763523f9e6 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala @@ -7,6 +7,7 @@ import scala.meta.pc.SymbolDocumentation import scala.meta.pc.SymbolSearch import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Denotations.Denotation import dotty.tools.dotc.core.Flags import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.NameKinds.ContextBoundParamName @@ -36,7 +37,7 @@ import org.eclipse.lsp4j.TextEdit * A type printer that shortens types by replacing fully qualified names with shortened versions. * * The printer supports symbol renames found in scope and will use the rename if it is available. - * It also handlse custom renames as specified in the `renameConfigMap` parameter. + * It also handle custom renames as specified in the `renameConfigMap` parameter. */ class ShortenedTypePrinter( symbolSearch: SymbolSearch, @@ -45,7 +46,7 @@ class ShortenedTypePrinter( isTextEdit: Boolean = false, renameConfigMap: Map[Symbol, String] = Map.empty )(using indexedCtx: IndexedContext, reportCtx: ReportContext) extends RefinedPrinter(indexedCtx.ctx): - private val missingImports: mutable.Set[ImportSel] = mutable.Set.empty + private val missingImports: mutable.Set[ImportSel] = mutable.LinkedHashSet.empty private val defaultWidth = 1000 private val methodFlags = @@ -63,6 +64,13 @@ class ShortenedTypePrinter( Lazy ) + private val foundRenames = collection.mutable.LinkedHashMap.empty[Symbol, String] + + def getUsedRenamesInfo(using Context): List[String] = + foundRenames.map { (from, to) => + s"type $to = ${from.showName}" + }.toList + def expressionType(tpw: Type)(using Context): Option[String] = tpw match case t: PolyType => @@ -117,8 +125,10 @@ class ShortenedTypePrinter( prefixIterator.flatMap { owner => val prefixAfterRename = ownersAfterRename(owner) + val ownerRename = indexedCtx.rename(owner) + ownerRename.foreach(rename => foundRenames += owner -> rename) val currentRenamesSearchResult = - indexedCtx.rename(owner).map(Found(owner, _, prefixAfterRename)) + ownerRename.map(Found(owner, _, prefixAfterRename)) lazy val configRenamesSearchResult = renameConfigMap.get(owner).map(Missing(owner, _, prefixAfterRename)) currentRenamesSearchResult orElse configRenamesSearchResult @@ -181,7 +191,9 @@ class ShortenedTypePrinter( override protected def selectionString(tp: NamedType): String = indexedCtx.rename(tp.symbol) match - case Some(value) => value + case Some(value) => + foundRenames += tp.symbol -> value + value case None => super.selectionString(tp) override def toText(tp: Type): Text = @@ -239,9 +251,10 @@ class ShortenedTypePrinter( lazy val effectiveOwner = sym.effectiveOwner sym.isType && (effectiveOwner == defn.ScalaPackageClass || effectiveOwner == defn.ScalaPredefModuleClass) - def completionSymbol(sym: Symbol): String = - val info = sym.info.widenTermRefExpr + def completionSymbol(denotation: Denotation): String = + val info = denotation.info.widenTermRefExpr val typeSymbol = info.typeSymbol + val sym = denotation.symbol lazy val typeEffectiveOwner = if typeSymbol != NoSymbol then " " + fullNameString(typeSymbol.effectiveOwner) @@ -492,7 +505,7 @@ class ShortenedTypePrinter( case head :: Nil => s": $head" case many => many.mkString(": ", ": ", "") s"$keywordName$paramTypeString$bounds" - else if param.is(Flags.Given) && param.name.toString.contains('$') then + else if param.isAllOf(Given | Param) && param.name.startsWith("x$") then // For Anonymous Context Parameters // print only type string // e.g. "using Ord[T]" instead of "using x$0: Ord[T]" diff --git a/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala b/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala index c006dda2c652..d6c8c10f8030 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala @@ -36,7 +36,8 @@ object MtagsEnrichments extends CommonMtagsEnrichments: extension (driver: InteractiveDriver) def sourcePosition( - params: OffsetParams + params: OffsetParams, + isZeroExtent: Boolean = true ): SourcePosition = val uri = params.uri() val source = driver.openedFiles(uri.nn) @@ -50,6 +51,7 @@ object MtagsEnrichments extends CommonMtagsEnrichments: case offset => Spans.Span(p.offset(), p.offset()) } + case _ if !isZeroExtent => Spans.Span(params.offset(), params.offset() + 1) case _ => Spans.Span(params.offset()) new SourcePosition(source, span) @@ -230,6 +232,34 @@ object MtagsEnrichments extends CommonMtagsEnrichments: def stripBackticks: String = s.stripPrefix("`").stripSuffix("`") + extension (text: Array[Char]) + def indexAfterSpacesAndComments: Int = { + var isInComment = false + var startedStateChange = false + val index = text.indexWhere { + case '/' if !isInComment && !startedStateChange => + startedStateChange = true + false + case '*' if !isInComment && startedStateChange => + startedStateChange = false + isInComment = true + false + case '/' if isInComment && startedStateChange => + startedStateChange = false + isInComment = false + false + case '*' if isInComment && !startedStateChange => + startedStateChange = true + false + case c if isInComment || c.isSpaceChar || c == '\t' => + startedStateChange = false + false + case _ => true + } + if (startedStateChange) index - 1 + else index + } + extension (search: SymbolSearch) def symbolDocumentation(symbol: Symbol)(using Context @@ -270,10 +300,10 @@ object MtagsEnrichments extends CommonMtagsEnrichments: def seenFrom(sym: Symbol)(using Context): (Type, Symbol) = try val pre = tree.qual - val denot = sym.denot.asSeenFrom(pre.tpe.widenTermRefExpr) + val denot = sym.denot.asSeenFrom(pre.typeOpt.widenTermRefExpr) (denot.info, sym.withUpdatedTpe(denot.info)) catch case NonFatal(e) => (sym.info, sym) - + def isInfix(using ctx: Context) = tree match case Select(New(_), _) => false @@ -327,7 +357,7 @@ object MtagsEnrichments extends CommonMtagsEnrichments: case t: GenericApply if t.fun.srcPos.span.contains( pos.span - ) && !t.tpe.isErroneous => + ) && !t.typeOpt.isErroneous => tryTail(tail).orElse(Some(enclosing)) case in: Inlined => tryTail(tail).orElse(Some(enclosing)) diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala index 0022be40a630..ca647502fabf 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala @@ -1,10 +1,11 @@ package dotty.tools.pc.base -import java.nio.file.Paths +import org.eclipse.lsp4j.SignatureHelp +import java.nio.file.Paths import scala.jdk.CollectionConverters.* -import scala.meta.internal.metals.CompilerOffsetParams import scala.language.unsafeNulls +import scala.meta.internal.metals.CompilerOffsetParams abstract class BaseSignatureHelpSuite extends BasePCSuite: def checkDoc( @@ -27,6 +28,10 @@ abstract class BaseSignatureHelpSuite extends BasePCSuite: ) .get() val out = new StringBuilder() + + // this is default SignatureHelp value which should only be returned on crash + assert(result != new SignatureHelp()) + if (result != null) { result.getSignatures.asScala.zipWithIndex.foreach { case (signature, i) => if (includeDocs) { @@ -38,10 +43,7 @@ abstract class BaseSignatureHelpSuite extends BasePCSuite: out .append(signature.getLabel) .append("\n") - if ( - result.getActiveSignature == i && result.getActiveParameter != null && signature.getParameters - .size() > 0 - ) { + if (result.getActiveSignature == i && result.getActiveParameter != null && signature.getParameters.size() > 0) { val param = signature.getParameters.get(result.getActiveParameter) val label = param.getLabel.getLeft() /* We need to find the label of the active parameter and show ^ at that spot diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala index 16d54cc124ca..61239b535e1c 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionArgSuite.scala @@ -1047,7 +1047,7 @@ class CompletionArgSuite extends BaseCompletionSuite: | bbb = 123, | aa@@ | ) - |} + |} |""".stripMargin, """|aaa = : Int |""".stripMargin, @@ -1063,7 +1063,7 @@ class CompletionArgSuite extends BaseCompletionSuite: | ccc = 123, | aa@@ | ) - |} + |} |""".stripMargin, """|aaa = : Int |""".stripMargin, @@ -1079,7 +1079,7 @@ class CompletionArgSuite extends BaseCompletionSuite: | ccc = 123, | aa@@ | ) - |} + |} |""".stripMargin, """|aaa = : Int |""".stripMargin, @@ -1105,4 +1105,18 @@ class CompletionArgSuite extends BaseCompletionSuite: """|str = : String | """.stripMargin, topLines = Some(1), + ) + + @Test def `comparison` = + check( + """package a + |object w { + | abstract class T(x: Int) { + | def met(x: Int): Unit = { + | println(x@@) + | } + | }} + |""".stripMargin, + """x: Int + |x = : Any""".stripMargin, ) \ No newline at end of file diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCaseSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCaseSuite.scala index b54915c56474..7a00c0397644 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCaseSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCaseSuite.scala @@ -542,7 +542,9 @@ class CompletionCaseSuite extends BaseCompletionSuite: | ca@@ | } |}""".stripMargin, - "" + """ + |case + |""".stripMargin ) @Test def `private-member-2` = @@ -721,4 +723,18 @@ class CompletionCaseSuite extends BaseCompletionSuite: |} |""".stripMargin, "case (Int, Int) => scala", - ) \ No newline at end of file + ) + + @Test def `keyword-only` = + check( + """ + |sealed trait Alpha + |object A { + | List.empty[Alpha].groupBy{ + | ca@@ + | } + |} + |""".stripMargin, + "case", + ) + diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala index c419ce3946d9..45f07b5fb7b1 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionDocSuite.scala @@ -16,14 +16,14 @@ class CompletionDocSuite extends BaseCompletionSuite: MockDocumentation("java/lang/String#join().", "join", Seq(), Seq("delimiter", "elements")), MockDocumentation("java/lang/String#substring().", "substring", Seq(), Seq("beginIndex")), MockDocumentation("java/lang/String#substring(+1).", "substring", Seq(), Seq("beginIndex", "endIndex")), - ScalaMockDocumentation("scala/collection/Iterator#sliding().", "sliding", List(MockParam("size"), MockParam("step", "1"))), - ScalaMockDocumentation("scala/collection/immutable/TreeMap#insert().", "insert", List(MockParam("key"), MockParam("value"))), + ScalaMockDocumentation("scala/collection/Iterator#sliding().", "sliding", List(), List(MockParam("size"), MockParam("step", "1"))), + ScalaMockDocumentation("scala/collection/immutable/TreeMap#insert().", "insert", List(), List(MockParam("key"), MockParam("value"))), ScalaMockDocumentation("scala/Option#isDefined().", "isDefined"), ScalaMockDocumentation("scala/util/DynamicVariable#", "DynamicVariable"), ScalaMockDocumentation("scala/util/DynamicVariable.", "DynamicVariable"), - ScalaMockDocumentation("scala/io/Source#reportWarning().", "reportWarning", List(MockParam("pos"), MockParam("msg"), MockParam("out", "Console.out"))), + ScalaMockDocumentation("scala/io/Source#reportWarning().", "reportWarning", List(), List(MockParam("pos"), MockParam("msg"), MockParam("out", "Console.out"))), ScalaMockDocumentation("scala/Predef.println().", "println"), - ScalaMockDocumentation("scala/Predef.println(+1).", "println", List(MockParam("x"))), + ScalaMockDocumentation("scala/Predef.println(+1).", "println", List(), List(MockParam("x"))), ScalaMockDocumentation("scala/Predef.", "Predef"), ScalaMockDocumentation("scala/runtime/stdLibPatches/Predef.", "Predef"), ScalaMockDocumentation("scala/util/control/Exception.Catch#", "Catch"), @@ -215,6 +215,7 @@ class CompletionDocSuite extends BaseCompletionSuite: """ |> Found documentation for scala/package.Vector. |Vector scala.collection.immutable + |Vector[A](elems: A*): Vector[A] |""".stripMargin, includeDocs = true ) @@ -316,5 +317,6 @@ class CompletionDocSuite extends BaseCompletionSuite: |} """.stripMargin, """|myNumbers: Vector[Int] + |myNumbers(i: Int): Int |""".stripMargin ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala index a260fe8b6e52..c01b38e7cf61 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionExtensionSuite.scala @@ -20,6 +20,20 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |""".stripMargin ) + @Test def `simple-old-syntax` = + check( + """|package example + | + |object Test: + | implicit class TestOps(a: Int): + | def testOps(b: Int): String = ??? + | + |def main = 100.test@@ + |""".stripMargin, + """|testOps(b: Int): String (implicit) + |""".stripMargin + ) + @Test def `simple2` = check( """|package example @@ -35,6 +49,21 @@ class CompletionExtensionSuite extends BaseCompletionSuite: filter = _.contains("(extension)") ) + @Test def `simple2-old-syntax` = + check( + """|package example + | + |object enrichments: + | implicit class TestOps(a: Int): + | def testOps(b: Int): String = ??? + | + |def main = 100.t@@ + |""".stripMargin, + """|testOps(b: Int): String (implicit) + |""".stripMargin, + filter = _.contains("(implicit)") + ) + @Test def `filter-by-type` = check( """|package example @@ -52,6 +81,22 @@ class CompletionExtensionSuite extends BaseCompletionSuite: filter = _.contains("(extension)") ) + @Test def `filter-by-type-old` = + check( + """|package example + | + |object enrichments: + | implicit class A(num: Int): + | def identity2: Int = num + 1 + | implicit class B(str: String): + | def identity: String = str + | + |def main = "foo".iden@@ + |""".stripMargin, + """|identity: String (implicit) + |""".stripMargin // identity2 won't be available + ) + @Test def `filter-by-type-subtype` = check( """|package example @@ -70,6 +115,24 @@ class CompletionExtensionSuite extends BaseCompletionSuite: filter = _.contains("(extension)") ) + @Test def `filter-by-type-subtype-old` = + check( + """|package example + | + |class A + |class B extends A + | + |object enrichments: + | implicit class Test(a: A): + | def doSomething: A = a + | + |def main = (new B).do@@ + |""".stripMargin, + """|doSomething: A (implicit) + |""".stripMargin, + filter = _.contains("(implicit)") + ) + @Test def `simple-edit` = checkEdit( """|package example @@ -92,6 +155,28 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |""".stripMargin ) + @Test def `simple-edit-old` = + checkEdit( + """|package example + | + |object enrichments: + | implicit class A (num: Int): + | def incr: Int = num + 1 + | + |def main = 100.inc@@ + |""".stripMargin, + """|package example + | + |import example.enrichments.A + | + |object enrichments: + | implicit class A (num: Int): + | def incr: Int = num + 1 + | + |def main = 100.incr + |""".stripMargin + ) + @Test def `simple-edit-suffix` = checkEdit( """|package example @@ -114,6 +199,28 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |""".stripMargin ) + @Test def `simple-edit-suffix-old` = + checkEdit( + """|package example + | + |object enrichments: + | implicit class A (val num: Int): + | def plus(other: Int): Int = num + other + | + |def main = 100.pl@@ + |""".stripMargin, + """|package example + | + |import example.enrichments.A + | + |object enrichments: + | implicit class A (val num: Int): + | def plus(other: Int): Int = num + other + | + |def main = 100.plus($0) + |""".stripMargin + ) + @Test def `simple-empty` = check( """|package example @@ -129,6 +236,21 @@ class CompletionExtensionSuite extends BaseCompletionSuite: filter = _.contains("(extension)") ) + @Test def `simple-empty-old` = + check( + """|package example + | + |object enrichments: + | implicit class TestOps(a: Int): + | def testOps(b: Int): String = ??? + | + |def main = 100.@@ + |""".stripMargin, + """|testOps(b: Int): String (implicit) + |""".stripMargin, + filter = _.contains("(implicit)") + ) + @Test def `directly-in-pkg1` = check( """| @@ -143,6 +265,20 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |""".stripMargin ) + @Test def `directly-in-pkg1-old` = + check( + """| + |package examples: + | implicit class A(num: Int): + | def incr: Int = num + 1 + | + |package examples2: + | def main = 100.inc@@ + |""".stripMargin, + """|incr: Int (implicit) + |""".stripMargin + ) + @Test def `directly-in-pkg2` = check( """|package example: @@ -157,6 +293,20 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |""".stripMargin ) + @Test def `directly-in-pkg2-old` = + check( + """|package examples: + | object X: + | def fooBar(num: Int) = num + 1 + | implicit class A (num: Int) { def incr: Int = num + 1 } + | + |package examples2: + | def main = 100.inc@@ + |""".stripMargin, + """|incr: Int (implicit) + |""".stripMargin + ) + @Test def `nested-pkg` = check( """|package a: // some comment @@ -175,7 +325,25 @@ class CompletionExtensionSuite extends BaseCompletionSuite: |""".stripMargin ) - @Test def `name-conflict` = + @Test def `nested-pkg-old` = + check( + """|package aa: // some comment + | package cc: + | implicit class A (num: Int): + | def increment2 = num + 2 + | implicit class A (num: Int): + | def increment = num + 1 + | + | + |package bb: + | def main: Unit = 123.incre@@ + |""".stripMargin, + """|increment: Int (implicit) + |increment2: Int (implicit) + |""".stripMargin + ) + + @Test def `name-conflict` = checkEdit( """ |package example diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionInterpolatorSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionInterpolatorSuite.scala index b5024e78f2e9..d70f28d08486 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionInterpolatorSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionInterpolatorSuite.scala @@ -635,7 +635,7 @@ class CompletionInterpolatorSuite extends BaseCompletionSuite: |""".stripMargin, """|class Paths |object Main { - | s"this is an interesting {java.nio.file.Paths}" + | s"this is an interesting ${java.nio.file.Paths}" |} |""".stripMargin, assertSingleItem = false, @@ -710,6 +710,26 @@ class CompletionInterpolatorSuite extends BaseCompletionSuite: filterText = "aaa.plus" ) + + @Test def `extension3` = + checkEdit( + """|trait Cursor + | + |extension (c: Cursor) def spelling: String = "hello" + |object Main { + | val c = new Cursor {} + | val x = s"$c.spelli@@" + |} + |""".stripMargin, + """|trait Cursor + | + |extension (c: Cursor) def spelling: String = "hello" + |object Main { + | val c = new Cursor {} + | val x = s"${c.spelling$0}" + |}""".stripMargin + ) + @Test def `filter-by-type` = check( """|package example diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala index 583b138a255b..dc972ec22533 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala @@ -38,7 +38,7 @@ class CompletionKeywordSuite extends BaseCompletionSuite: | // tr@@ |} |""".stripMargin, - "", + "transparentTrait - scala.annotation (commit: '')", includeCommitCharacter = true ) @@ -57,7 +57,7 @@ class CompletionKeywordSuite extends BaseCompletionSuite: | **/ |} |""".stripMargin, - "", + "transparentTrait - scala.annotation (commit: '')", includeCommitCharacter = true ) @@ -151,6 +151,8 @@ class CompletionKeywordSuite extends BaseCompletionSuite: """|value: Int |val |var + |varargs(): varargs + |varargs - scala.annotation |""".stripMargin ) @@ -167,6 +169,8 @@ class CompletionKeywordSuite extends BaseCompletionSuite: |""".stripMargin, """|val |var + |varargs(): varargs + |varargs - scala.annotation |""".stripMargin ) @@ -181,9 +185,10 @@ class CompletionKeywordSuite extends BaseCompletionSuite: | } |} |""".stripMargin, - """|given (commit: '') - |""".stripMargin, - includeCommitCharacter = true + """given (commit: '') + |""".stripMargin, + includeCommitCharacter = true, + topLines = Some(5) ) @Test def `val-arg` = @@ -198,8 +203,8 @@ class CompletionKeywordSuite extends BaseCompletionSuite: |} |""".stripMargin, """|value: Int - |""".stripMargin, - topLines = Some(1) + |varargs(): varargs + |varargs - scala.annotation""".stripMargin ) @Test def `val-trailing-space` = @@ -406,7 +411,10 @@ class CompletionKeywordSuite extends BaseCompletionSuite: | protected de@@ |} """.stripMargin, - "def" + """|def + |derived - scala.CanEqual + |deprecated - scala.runtime.stdLibPatches.language + |""".stripMargin, ) @Test def `protected-val` = @@ -418,9 +426,10 @@ class CompletionKeywordSuite extends BaseCompletionSuite: | protected va@@ |} """.stripMargin, - """val - |var - |""".stripMargin + """|val + |var + |varargs - scala.annotation + |""".stripMargin ) @Test def `topLevel` = @@ -458,8 +467,13 @@ class CompletionKeywordSuite extends BaseCompletionSuite: | def hello(u@@) |}""".stripMargin, """|using (commit: '') + |unsafe - scala.caps (commit: '') + |unsafeNulls - scala.runtime.stdLibPatches.language (commit: '') + |unused - scala.annotation (commit: '') + |unshared - scala.annotation.internal (commit: '') |""".stripMargin, - includeCommitCharacter = true + includeCommitCharacter = true, + topLines = Some(5) ) @Test def `not-using` = @@ -467,7 +481,12 @@ class CompletionKeywordSuite extends BaseCompletionSuite: """|object A{ | def hello(a: String, u@@) |}""".stripMargin, - "" + """|unsafe - scala.caps + |unsafeNulls - scala.runtime.stdLibPatches.language + |unused - scala.annotation + |unshared - scala.annotation.internal + |unspecialized - scala.annotation""".stripMargin, + topLines = Some(5) ) @Test def `extends-class` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionPatternSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionPatternSuite.scala index 6d2261bbfe66..df6a3f705be9 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionPatternSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionPatternSuite.scala @@ -54,7 +54,9 @@ class CompletionPatternSuite extends BaseCompletionSuite: | case ma@@ | } |}""".stripMargin, - "" + """|macros - scala.languageFeature.experimental + |macroImpl - scala.reflect.macros.internal + |""".stripMargin ) @Test def `bind2` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala index 586b70d54006..c3e3f374c23d 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSnippetSuite.scala @@ -3,6 +3,7 @@ package dotty.tools.pc.tests.completion import dotty.tools.pc.base.BaseCompletionSuite import org.junit.Test +import org.junit.Ignore class CompletionSnippetSuite extends BaseCompletionSuite: @@ -76,32 +77,65 @@ class CompletionSnippetSuite extends BaseCompletionSuite: // Dotty does not currently support fuzzy completions. Please take a look at // https://github.com/lampepfl/dotty-feature-requests/issues/314 + @Ignore("Fuzzy should be provided by dotty") @Test def `type-empty` = - checkSnippet( - """ - |object Main { - | type MyType = List[Int] - | def list : MT@@ - |} - |""".stripMargin, - """|MyType - |""".stripMargin - ) + if (scala.util.Properties.isJavaAtLeast("9")) { + checkSnippet( + """ + |object Main { + | type MyType = List[Int] + | def list : MT@@ + |} + |""".stripMargin, + """|MyType + |""".stripMargin + ) + } else { + checkSnippet( + """ + |object Main { + | type MyType = List[Int] + | def list : MT@@ + |} + |""".stripMargin, + """|MyType + |MTOM + |MTOMFeature + |""".stripMargin + ) + } // Dotty does not currently support fuzzy completions. Please take a look at // https://github.com/lampepfl/dotty-feature-requests/issues/314 + @Ignore("Fuzzy should be provided by dotty") @Test def `type-new-empty` = - checkSnippet( - """ - |object Main { - | class Gen[T] - | type MyType = Gen[Int] - | new MT@@ - |} - |""".stripMargin, - """|MyType - |""".stripMargin - ) + if (scala.util.Properties.isJavaAtLeast("9")) { + checkSnippet( + """ + |object Main { + | class Gen[T] + | type MyType = Gen[Int] + | new MT@@ + |} + |""".stripMargin, + """|MyType + |""".stripMargin + ) + } else { + checkSnippet( + """ + |object Main { + | class Gen[T] + | type MyType = Gen[Int] + | new MT@@ + |} + |""".stripMargin, + """|MyType + |MTOM + |MTOMFeature + |""".stripMargin + ) + } @Test def `type` = checkSnippet( @@ -323,7 +357,8 @@ class CompletionSnippetSuite extends BaseCompletionSuite: |Widget($0) - (age: Int): Widget |Widget($0) - (name: String, age: Int): Widget |""".stripMargin, - includeDetail = true + includeDetail = true, + topLines = Some(4) ) @Test def `no-apply` = @@ -335,8 +370,13 @@ class CompletionSnippetSuite extends BaseCompletionSuite: | Wi@@ |} |""".stripMargin, - "Widget - example", - includeDetail = true + """|Widget - example + |Window - java.awt + |WindowPeer - java.awt.peer + |WithFilter - scala.collection + |""".stripMargin, + includeDetail = true, + topLines = Some(4) ) // https://github.com/scalameta/metals/issues/4004 diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index 055363830a1b..68e9f7728a87 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -7,6 +7,7 @@ import dotty.tools.pc.base.BaseCompletionSuite import dotty.tools.pc.utils.MockEntries import org.junit.Test +import org.junit.Ignore class CompletionSuite extends BaseCompletionSuite: @@ -26,10 +27,10 @@ class CompletionSuite extends BaseCompletionSuite: |}""".stripMargin, """ |List scala.collection.immutable + |List[A](elems: A*): List[A] |List - java.awt |List - java.util - |List - scala.collection.immutable - |List[A](elems: A*): CC[A] + |ListMap[K, V](elems: (K, V)*): ListMap[K, V] |""".stripMargin, topLines = Some(5) ) @@ -109,17 +110,17 @@ class CompletionSuite extends BaseCompletionSuite: |tabulate[A](n: Int)(f: Int => A): List[A] |unapplySeq[A](x: List[A] @uncheckedVariance): UnapplySeqWrapper[A] |unfold[A, S](init: S)(f: S => Option[(A, S)]): List[A] - |->[B](y: B): (A, B) - |ensuring(cond: Boolean): A - |ensuring(cond: A => Boolean): A - |ensuring(cond: Boolean, msg: => Any): A - |ensuring(cond: A => Boolean, msg: => Any): A - |fromSpecific(from: From)(it: IterableOnce[A]): C - |fromSpecific(it: IterableOnce[A]): C - |nn: x.type & T - |toFactory(from: From): Factory[A, C] + |->[B](y: B): (List.type, B) + |ensuring(cond: Boolean): List.type + |ensuring(cond: List.type => Boolean): List.type + |ensuring(cond: Boolean, msg: => Any): List.type + |ensuring(cond: List.type => Boolean, msg: => Any): List.type + |fromSpecific(from: Any)(it: IterableOnce[Nothing]): List[Nothing] + |fromSpecific(it: IterableOnce[Nothing]): List[Nothing] + |nn: List.type & List.type + |toFactory(from: Any): Factory[Nothing, List[Nothing]] |formatted(fmtstr: String): String - |→[B](y: B): (A, B) + |→[B](y: B): (List.type, B) |iterableFactory[A]: Factory[A, List[A]] |asInstanceOf[X0]: X0 |equals(x$0: Any): Boolean @@ -146,6 +147,7 @@ class CompletionSuite extends BaseCompletionSuite: "XtensionMethod(a: Int): XtensionMethod" ) + @Ignore("This test should be handled by compiler fuzzy search") @Test def fuzzy = check( """ @@ -157,14 +159,14 @@ class CompletionSuite extends BaseCompletionSuite: |""".stripMargin ) + @Ignore("This test should be handled by compiler fuzzy search") @Test def fuzzy1 = check( """ |object A { - | new PBuil@@ + | new PBuilder@@ |}""".stripMargin, - """|ProcessBuilder java.lang - |ProcessBuilder - scala.sys.process + """|ProcessBuilder - scala.sys.process |ProcessBuilderImpl - scala.sys.process |""".stripMargin, filter = _.contains("ProcessBuilder") @@ -178,7 +180,7 @@ class CompletionSuite extends BaseCompletionSuite: | TrieMap@@ |}""".stripMargin, """|TrieMap scala.collection.concurrent - |TrieMap[K, V](elems: (K, V)*): CC[K, V] + |TrieMap[K, V](elems: (K, V)*): TrieMap[K, V] |""".stripMargin ) @@ -515,8 +517,8 @@ class CompletionSuite extends BaseCompletionSuite: """.stripMargin, """|until(end: Int): Range |until(end: Int, step: Int): Range - |until(end: T): Exclusive[T] - |until(end: T, step: T): Exclusive[T] + |until(end: Long): Exclusive[Long] + |until(end: Long, step: Long): Exclusive[Long] |""".stripMargin, postProcessObtained = _.replace("Float", "Double"), stableOrder = false @@ -618,9 +620,6 @@ class CompletionSuite extends BaseCompletionSuite: """|Some(value) scala |Some scala |Some[A](value: A): Some[A] - |SomeToExpr(x: Some[T])(using Quotes): Expr[Some[T]] - |SomeToExpr[T: Type: ToExpr]: SomeToExpr[T] - |SomeFromExpr[T](using Type[T], FromExpr[T]): SomeFromExpr[T] |""".stripMargin ) @@ -633,9 +632,6 @@ class CompletionSuite extends BaseCompletionSuite: |""".stripMargin, """|Some scala |Some[A](value: A): Some[A] - |SomeToExpr(x: Some[T])(using Quotes): Expr[Some[T]] - |SomeToExpr[T: Type: ToExpr]: SomeToExpr[T] - |SomeFromExpr[T](using Type[T], FromExpr[T]): SomeFromExpr[T] |""".stripMargin ) @@ -892,7 +888,7 @@ class CompletionSuite extends BaseCompletionSuite: topLines = Some(2) ) - // issues with scala 3 https://github.com/lampepfl/dotty/pull/13515 + // issues with scala 3 https://github.com/scala/scala3/pull/13515 @Test def ordering4 = check( s"""|class Main { @@ -1193,7 +1189,7 @@ class CompletionSuite extends BaseCompletionSuite: | val x = Bar[M](new Foo[Int]{}) | x.bar.m@@ |""".stripMargin, - """|map[B](f: A => B): Foo[B] + """|map[B](f: Int => B): Foo[B] |""".stripMargin, topLines = Some(1) ) @@ -1329,6 +1325,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension (x: Fo@@) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1349,6 +1355,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension [A <: Fo@@] |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1369,6 +1385,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension (using Fo@@) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1380,6 +1406,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension (x: Int)(using Fo@@) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1390,6 +1426,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension (using Fo@@)(x: Int)(using Foo) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1400,6 +1446,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension (using Foo)(x: Int)(using Fo@@) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1410,6 +1466,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension [A](x: Fo@@) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1420,6 +1486,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension [A](using Fo@@)(x: Int) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1430,6 +1506,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension [A](using Foo)(x: Fo@@) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1440,6 +1526,16 @@ class CompletionSuite extends BaseCompletionSuite: | extension [A](using Foo)(x: Fo@@)(using Foo) |""".stripMargin, """|Foo test + |Font - java.awt + |Form - java.text.Normalizer + |Format - java.text + |FontPeer - java.awt.peer + |FormView - javax.swing.text.html + |Formatter - java.util + |Formatter - java.util.logging + |FocusEvent - java.awt.event + |FontMetrics - java.awt + |Found - scala.collection.Searching |""".stripMargin ) @@ -1545,3 +1641,96 @@ class CompletionSuite extends BaseCompletionSuite: assertSingleItem = false ) + + @Test def `multi-export` = + check( + """export scala.collection.{AbstractMap, Set@@} + |""".stripMargin, + """Set scala.collection + |SetOps scala.collection + |""".stripMargin + ) + + @Test def `multi-imports` = + check( + """import scala.collection.{AbstractMap, Set@@} + |""".stripMargin, + """Set scala.collection + |SetOps scala.collection + |""".stripMargin, + ) + + + @Test def `multi-imports-empty-query` = + check( + """import scala.collection.{AbstractMap, @@} + |""".stripMargin, + """GenIterable scala.collection + |GenMap scala.collection + |GenSeq scala.collection + |GenSet scala.collection + |GenTraversable scala.collection + |""".stripMargin, + topLines = Some(5) + ) + + @Test def `import-rename` = + check( + """import scala.collection.{AbstractMap => Set@@} + |""".stripMargin, + "" + ) + + @Ignore + @Test def `dont-crash-implicit-search` = + check( + """object M: + | Array[Int].fi@@ + |""".stripMargin, + "" + ) + + @Test def `extension-definition-type-variable-inference` = + check( + """|object M: + | extension [T](xs: List[T]) def test(p: T => Boolean): List[T] = ??? + | List(1,2,3).tes@@ + |""".stripMargin, + """|test(p: Int => Boolean): List[Int] + |""".stripMargin + ) + + @Test def `old-style-extension-type-variable-inference` = + check( + """|object M: + | implicit class ListUtils[T](xs: List[T]) { + | def test(p: T => Boolean): List[T] = ??? + | } + | List(1,2,3).tes@@ + |""".stripMargin, + """|test(p: Int => Boolean): List[Int] + |""".stripMargin + ) + + @Test def `instantiate-type-vars-in-extra-apply-completions` = + check( + """|object M: + | val fooBar = List(123) + | foo@@ + |""".stripMargin, + """|fooBar: List[Int] + |fooBar(n: Int): Int + |""".stripMargin + ) + + @Test def `show-underlying-type-instead-of-CC` = + check( + """|object M: + | List@@ + |""".stripMargin, + """|List[A](elems: A*): List[A] + |ListMap[K, V](elems: (K, V)*): ListMap[K, V] + |""".stripMargin, + filter = _.contains("[") + ) + diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionWorkspaceSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionWorkspaceSuite.scala index 98d164db87f1..82085932247d 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionWorkspaceSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionWorkspaceSuite.scala @@ -768,12 +768,33 @@ class CompletionWorkspaceSuite extends BaseCompletionSuite: | def main: Unit = incre@@ |""".stripMargin, """|increment3: Int - |increment: Int - |increment2: Int + |increment - a: Int + |increment2 - a.c: Int |""".stripMargin ) - @Test def `case_class_param` = + @Test def `indent-method` = + check( + """|package a: + | val y = 123 + | given intGiven: Int = 123 + | type Alpha = String + | class Foo(x: Int) + | object X: + | val x = 123 + | def fooBar(x: Int) = x + 1 + | package b: + | def fooBar(x: String) = x.length + | + |package c: + | def main() = foo@@ + |""".stripMargin, + """|fooBar - a(x: Int): Int + |fooBar - a.b(x: String): Int + |""".stripMargin + ) + + @Test def `case-class-param` = check( """|case class Foo(fooBar: Int, gooBar: Int) |class Bar(val fooBaz: Int, val fooBal: Int) { @@ -790,6 +811,7 @@ class CompletionWorkspaceSuite extends BaseCompletionSuite: |""".stripMargin, """|fooBar: String |fooBar: List[Int] + |fooBar(n: Int): Int |""".stripMargin, ) @@ -825,7 +847,7 @@ class CompletionWorkspaceSuite extends BaseCompletionSuite: |MyType - demo.other""".stripMargin, ) - @Test def `method-name-conflict` = + @Test def `method-name-conflict` = checkEdit( """|package demo | @@ -847,5 +869,21 @@ class CompletionWorkspaceSuite extends BaseCompletionSuite: | } |} |""".stripMargin, - filter = _.contains("mmmm(x: Int)") + filter = _.contains("mmmm - demo.O") + ) + + @Test def `method-label` = + check( + """|package demo + | + |object O { + | def method(i: Int): Int = i + 1 + |} + | + |object Main { + | val x = meth@@ + |} + |""".stripMargin, + """|method - demo.O(i: Int): Int + |""".stripMargin ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/decorations/SyntheticDecorationsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/decorations/SyntheticDecorationsSuite.scala index 7d4cc3cf41a4..49ffb911aaa3 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/decorations/SyntheticDecorationsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/decorations/SyntheticDecorationsSuite.scala @@ -498,3 +498,31 @@ class SyntheticDecorationsSuite extends BaseSyntheticDecorationsSuite: |""".stripMargin ) + @Test def `val-def-with-bind` = + check( + """ + |object O { + | val tupleBound @ (one, two) = ("1", "2") + |} + |""".stripMargin, + """ + |object O { + | val tupleBound @ (one: String, two: String) = ("1", "2") + |} + |""".stripMargin + ) + + @Test def `val-def-with-bind-and-comment` = + check( + """ + |object O { + | val tupleBound /* comment */ @ (one, two) = ("1", "2") + |} + |""".stripMargin, + """ + |object O { + | val tupleBound /* comment */ @ (one: String, two: String) = ("1", "2") + |} + |""".stripMargin + ) + diff --git a/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala index 358e159eb539..9636aea77c2e 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala @@ -199,6 +199,81 @@ class PcDefinitionSuite extends BasePcDefinitionSuite: |""".stripMargin ) + @Test def exportType0 = + check( + """object Foo: + | trait <<Cat>> + |object Bar: + | export Foo.* + |class Test: + | import Bar.* + | def test = new Ca@@t {} + |""".stripMargin + ) + + @Test def exportType1 = + check( + """object Foo: + | trait <<Cat>>[A] + |object Bar: + | export Foo.* + |class Test: + | import Bar.* + | def test = new Ca@@t[Int] {} + |""".stripMargin + ) + + @Test def exportTerm0Nullary = + check( + """trait Foo: + | def <<meth>>: Int + |class Bar(val foo: Foo): + | export foo.* + | def test(bar: Bar) = bar.me@@th + |""".stripMargin + ) + + @Test def exportTerm0 = + check( + """trait Foo: + | def <<meth>>(): Int + |class Bar(val foo: Foo): + | export foo.* + | def test(bar: Bar) = bar.me@@th() + |""".stripMargin + ) + + @Test def exportTerm1 = + check( + """trait Foo: + | def <<meth>>(x: Int): Int + |class Bar(val foo: Foo): + | export foo.* + | def test(bar: Bar) = bar.me@@th(0) + |""".stripMargin + ) + + @Test def exportTerm1Poly = + check( + """trait Foo: + | def <<meth>>[A](x: A): A + |class Bar(val foo: Foo): + | export foo.* + | def test(bar: Bar) = bar.me@@th(0) + |""".stripMargin + ) + + @Test def exportTerm1Overload = + check( + """trait Foo: + | def <<meth>>(x: Int): Int + | def meth(x: String): String + |class Bar(val foo: Foo): + | export foo.* + | def test(bar: Bar) = bar.me@@th(0) + |""".stripMargin + ) + @Test def `named-arg-local` = check( """| diff --git a/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala index 5285be83b537..359a63442408 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala @@ -6,7 +6,6 @@ import java.util.concurrent.ExecutionException import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerOffsetParams import scala.meta.internal.pc.CodeActionErrorMessages -import scala.meta.pc.DisplayableException import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCodeActionSuite diff --git a/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala index d6707c54894e..f12cab7e65ef 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala @@ -789,6 +789,28 @@ class InsertInferredTypeSuite extends BaseCodeActionSuite: |""".stripMargin ) + @Test def `import-rename` = + checkEdit( + """ + |package a + |import scala.collection.{AbstractMap => AB} + | + |object Main { + | def test(): AB[Int, String] = ??? + | val <<x>> = test() + |} + |""".stripMargin, + """ + |package a + |import scala.collection.{AbstractMap => AB} + | + |object Main { + | def test(): AB[Int, String] = ??? + | val x: AB[Int, String] = test() + |} + |""".stripMargin + ) + def checkEdit( original: String, expected: String diff --git a/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala index 1dc2a7b156db..5d9893f6a1c1 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala @@ -1186,7 +1186,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |""".stripMargin, ) - @Test def `constructor` = + @Test def `constructor` = check( """ |object Main { @@ -1195,7 +1195,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor1` = + @Test def `constructor1` = check( """ |object Main { @@ -1204,7 +1204,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor2` = + @Test def `constructor2` = check( """ |object Main { @@ -1214,7 +1214,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor3` = + @Test def `constructor3` = check( """ |object Main { @@ -1224,7 +1224,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor4` = + @Test def `constructor4` = check( """ |object Main { @@ -1234,7 +1234,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor5` = + @Test def `constructor5` = check( """ |object Main { @@ -1246,7 +1246,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor6` = + @Test def `constructor6` = check( """ |class <<Abc>>[T](a: T) @@ -1256,7 +1256,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor7` = + @Test def `constructor7` = check( """ |object Bar { @@ -1268,7 +1268,7 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |}""".stripMargin ) - @Test def `constructor8` = + @Test def `constructor8` = check( """ |object Bar { @@ -1279,3 +1279,188 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: | val x = Bar.<<Ab@@c>>[Int](2) |}""".stripMargin ) + + @Test def `i5630` = + check( + """|class MyIntOut(val value: Int) + |object MyIntOut: + | extension (i: MyIntOut) def <<uneven>> = i.value % 2 == 1 + | + |val a = MyIntOut(1) + |val m = a.<<un@@even>> + |""".stripMargin + ) + + @Test def `i5630-2` = + check( + """|class MyIntOut(val value: Int) + |object MyIntOut: + | extension (i: MyIntOut) def <<uneven>>(u: Int) = i.value % 2 == 1 + | + |val a = MyIntOut(1).<<un@@even>>(3) + |""".stripMargin + ) + + @Test def `i5630-infix` = + check( + """|class MyIntOut(val value: Int) + |object MyIntOut: + | extension (i: MyIntOut) def <<++>>(u: Int) = i.value + u + | + |val a = MyIntOut(1) <<+@@+>> 3 + |""".stripMargin + ) + + @Test def `i5921-1` = + check( + """|object Logarithms: + | opaque type Logarithm = Double + | extension [K](vmap: Logarithm) + | def <<multiply>>(k: Logarithm): Logarithm = ??? + | + |object Test: + | val in: Logarithms.Logarithm = ??? + | in.<<multi@@ply>>(in) + |""".stripMargin + ) + + @Test def `i5921-2` = + check( + """|object Logarithms: + | opaque type Logarithm = Double + | extension [K](vmap: Logarithm) + | def <<mu@@ltiply>>(k: Logarithm): Logarithm = ??? + | + |object Test: + | val in: Logarithms.Logarithm = ??? + | in.<<multiply>>(in) + |""".stripMargin + ) + + @Test def `i5921-3` = + check( + """|object Logarithms: + | opaque type Logarithm = Double + | extension [K](vmap: Logarithm) + | def <<multiply>>(k: Logarithm): Logarithm = ??? + | (2.0).<<mult@@iply>>(1.0) + |""".stripMargin + ) + + @Test def `i5921-4` = + check( + """|object Logarithms: + | opaque type Logarithm = Double + | extension [K](vmap: Logarithm) + | def <<mult@@iply>>(k: Logarithm): Logarithm = ??? + | (2.0).<<multiply>>(1.0) + |""".stripMargin + ) + + @Test def `i5977` = + check( + """ + |sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def <<inferredTypeArg>>[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Int](_.<<infe@@rredTypeArg>>("str")) + | usage[Int](_.<<inferredTypeArg>>[String]("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>[String]("str")) + |} + |""".stripMargin + ) + + @Test def `i5977-1` = + check( + """ + |sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def <<inferredTypeArg>>[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Int](_.<<inferredTypeArg>>("str")) + | usage[Int](_.<<infe@@rredTypeArg>>[String]("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>[String]("str")) + |} + |""".stripMargin + ) + + @Test def `i5977-2` = + check( + """ + |sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def <<inferredTypeArg>>[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Int](_.<<inferredTypeArg>>("str")) + | usage[Int](_.<<inferredTypeArg>>[String]("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferr@@edTypeArg>>("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>[String]("str")) + |} + |""".stripMargin + ) + + @Test def `i5977-3` = + check( + """ + |sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def <<inferredTypeArg>>[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Int](_.<<inferredTypeArg>>("str")) + | usage[Int](_.<<inferredTypeArg>>[String]("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferred@@TypeArg>>[String]("str")) + |} + |""".stripMargin + ) + + @Test def `i5977-4` = + check( + """ + |sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def <<inferre@@dTypeArg>>[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Int](_.<<inferredTypeArg>>("str")) + | usage[Int](_.<<inferredTypeArg>>[String]("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>("str")) + | usage[Option[Int]](_.typeArg[Some[Int]].value.<<inferredTypeArg>>[String]("str")) + |} + |""".stripMargin + ) + + +end DocumentHighlightSuite diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala index 84af8f21f258..7a647fa40f5f 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala @@ -163,8 +163,7 @@ class HoverDefnSuite extends BaseHoverSuite: """package b.p@@kg |object Main |""".stripMargin, - // TODO, doesn's show information on packages - "" + "package b.pkg".hover, ) @Test def `pat-bind` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala index 06c629467166..fc9b6835e319 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDocSuite.scala @@ -10,10 +10,10 @@ class HoverDocSuite extends BaseHoverSuite: override protected def mockEntries: MockEntries = new MockEntries: override def documentations: Set[SymbolDocumentation] = Set( - ScalaMockDocumentation("java/lang/String#substring().", "substring", List(MockParam("beginIndex"))), + ScalaMockDocumentation("java/lang/String#substring().", "substring", List(), List(MockParam("beginIndex"))), ScalaMockDocumentation("java/util/Collections#emptyList().", "emptyList"), - ScalaMockDocumentation("_empty_/Alpha.apply().", "apply", List(MockParam("x"))), - ScalaMockDocumentation("_empty_/Alpha#", "init", List(MockParam("x"))), + ScalaMockDocumentation("_empty_/Alpha.apply().", "apply", List(), List(MockParam("x"))), + ScalaMockDocumentation("_empty_/Alpha#", "init", List(), List(MockParam("x"))), ScalaMockDocumentation("scala/collection/LinearSeqOps#headOption().", "headOption"), ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverNamedArgSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverNamedArgSuite.scala index f92ba9933be4..182f8e1e0644 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverNamedArgSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverNamedArgSuite.scala @@ -11,7 +11,7 @@ class HoverNamedArgSuite extends BaseHoverSuite: override protected def mockEntries: MockEntries = new MockEntries: override def documentations: Set[SymbolDocumentation] = Set( - ScalaMockDocumentation("a/b.foo().(named)", "foo", List(MockParam("named"))) + ScalaMockDocumentation("a/b.foo().(named)", "foo", List(), List(MockParam("named"))) ) @Test def `named` = diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala index 7ce81464fbd6..82fd0c657e67 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala @@ -112,7 +112,7 @@ class HoverTermSuite extends BaseHoverSuite: | } |} |""".stripMargin, - // https://github.com/lampepfl/dotty/issues/8835 + // https://github.com/scala/scala3/issues/8835 """|object num: a.Xtension |""".stripMargin.hover ) @@ -412,3 +412,228 @@ class HoverTermSuite extends BaseHoverSuite: |""".stripMargin, "def this(): tailrec".hover ) + + @Test def `i5630` = + check( + """class MyIntOut(val value: Int) + |object MyIntOut: + | extension (i: MyIntOut) def uneven = i.value % 2 == 1 + | + |object Test: + | val a = MyIntOut(1).un@@even + |""".stripMargin, + """extension (i: MyIntOut) def uneven: Boolean + |""".stripMargin.hover + ) + + @Test def `i5921` = + check( + """object Logarithms: + | trait Logarithm + | extension [K](vmap: Logarithm) + | def multiply(k: Logarithm): Logarithm = ??? + | + |object Test: + | val in: Logarithms.Logarithm = ??? + | in.multi@@ply(in) + |""".stripMargin, + "extension [K](vmap: Logarithm) def multiply(k: Logarithm): Logarithm".hover + ) + + @Test def `i5976` = + check( + """sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def noTypeArg: A + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Option[Int]](_.typeArg[Some[Int]].value.noTyp@@eArg.typeArg[Int]) + |} + |""".stripMargin, + """**Expression type**: + |```scala + |Int + |``` + |**Symbol signature**: + |```scala + |extension [A](self: A) def noTypeArg: A + |``` + |""".stripMargin + ) + + @Test def `i5976-1` = + check( + """sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def noTypeArg: A + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Option[Int]](_.type@@Arg[Some[Int]].value.noTypeArg.typeArg[Int]) + |} + |""".stripMargin, + """**Expression type**: + |```scala + |Some[Int] + |``` + |**Symbol signature**: + |```scala + |extension [A](self: A) def typeArg[B <: A]: B + |``` + |""".stripMargin + ) + + @Test def `i5977` = + check( + """sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def inferredTypeArg[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Option[Int]](_.infer@@redTypeArg("str")) + |} + |""".stripMargin, + """**Expression type**: + |```scala + |String + |``` + |**Symbol signature**: + |```scala + |extension [A](self: A) def inferredTypeArg[C](value: C): C + |``` + |""".stripMargin + ) + + @Test def `i5977-1` = + check( + """sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def inferredTypeArg[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Option[Int]](_.infer@@redTypeArg[String]("str")) + |} + |""".stripMargin, + """**Expression type**: + |```scala + |String + |``` + |**Symbol signature**: + |```scala + |extension [A](self: A) def inferredTypeArg[C](value: C): C + |``` + |""".stripMargin + ) + + @Test def `i5977-2` = + check( + """sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def inferredTypeArg[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Option[Int]](_.typeArg[Some[Int]].value.infer@@redTypeArg("str")) + |} + |""".stripMargin, + """**Expression type**: + |```scala + |String + |``` + |**Symbol signature**: + |```scala + |extension [A](self: A) def inferredTypeArg[C](value: C): C + |``` + |""".stripMargin + ) + + @Test def `i5977-3` = + check( + """sealed trait ExtensionProvider { + | extension [A] (self: A) { + | def typeArg[B <: A]: B + | def inferredTypeArg[C](value: C): C + | } + |} + | + |object Repro { + | def usage[A](f: ExtensionProvider ?=> A => Any): Any = ??? + | + | usage[Option[Int]](_.typeArg[Some[Int]].value.infer@@redTypeArg[String]("str")) + |} + |""".stripMargin, + """**Expression type**: + |```scala + |String + |``` + |**Symbol signature**: + |```scala + |extension [A](self: A) def inferredTypeArg[C](value: C): C + |``` + |""".stripMargin + ) + + @Test def `import-rename` = + check( + """ + |import scala.collection.{AbstractMap => AB} + |import scala.collection.{Set => S} + | + |object Main { + | def test(): AB[Int, String] = ??? + | <<val t@@t = test()>> + |} + |""".stripMargin, + """ + |```scala + |type AB = AbstractMap + |``` + | + |```scala + |val tt: AB[Int, String] + |```""".stripMargin, + ) + + @Test def `import-rename2` = + check( + """ + |import scala.collection.{AbstractMap => AB} + |import scala.collection.{Set => S} + | + |object Main { + | <<def te@@st(d: S[Int], f: S[Char]): AB[Int, String] = ???>> + |} + |""".stripMargin, + """ + |```scala + |type S = Set + |type AB = AbstractMap + |``` + | + |```scala + |def test(d: S[Int], f: S[Char]): AB[Int, String] + |```""".stripMargin, + ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala index 2157aa891bae..c6e2590f8f29 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala @@ -41,7 +41,7 @@ class HoverTypeSuite extends BaseHoverSuite: ) // We should produce a shorter type but: - // https://github.com/lampepfl/dotty/issues/11683 + // https://github.com/scala/scala3/issues/11683 @Test def `enums` = check( """| @@ -125,7 +125,7 @@ class HoverTypeSuite extends BaseHoverSuite: * As user can actually supply params to them by hand when * invoking the extension method, we always show them next to the * method itself. - * https://github.com/lampepfl/dotty/issues/13123 + * https://github.com/scala/scala3/issues/13123 */ @Test def `extension-methods-complex` = check( @@ -362,8 +362,35 @@ class HoverTypeSuite extends BaseHoverSuite: |object MyIntOut: | extension (i: MyIntOut) def uneven = i.value % 2 == 1 | - |val a = MyIntOut(1).un@@even + |object Test: + | val a = MyIntOut(1).un@@even |""".stripMargin, """|extension (i: MyIntOut) def uneven: Boolean |""".stripMargin.hover, ) + + @Test def `recursive-enum-without-type` = + check( + """class Wrapper(n: Int): + | extension (x: Int) + | def + (y: Int) = new Wrap@@per(x) + y + |""".stripMargin, + """```scala + |def this(n: Int): Wrapper + |``` + |""".stripMargin + ) + + @Test def `recursive-enum-without-type-1` = + check( + """class Wrapper(n: Int): + | def add(x: Int): Wrapper = ??? + | extension (x: Int) + | def + (y: Int) = Wrap@@per(x).add(5) + |""".stripMargin, + """```scala + |def this(n: Int): Wrapper + |``` + |""".stripMargin + ) + diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala index 7d36dc6ce23d..09b22559d35c 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpDocSuite.scala @@ -26,13 +26,13 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: MockDocumentation("java/io/File#`<init>`(+1).", "<init>", Seq(), Seq("parent", "child")), MockDocumentation("java/io/File#`<init>`(+2).", "<init>", Seq(), Seq("parent", "child")), MockDocumentation("java/io/File#`<init>`(+3).", "<init>", Seq(), Seq("uri")), - ScalaMockDocumentation("java/util/Collections#singleton().", "singleton", List(MockParam("o"))), + ScalaMockDocumentation("java/util/Collections#singleton().", "singleton", List(MockParam("T")), List(MockParam("o"))), ScalaMockDocumentation("scala/Some#", "Some"), - ScalaMockDocumentation("scala/Option#fold().", "fold", List(MockParam("ifEmpty"), MockParam("f"))), - ScalaMockDocumentation("scala/Option.apply().", "apply", List(MockParam("x"))), - ScalaMockDocumentation("scala/collection/immutable/List#map().", "map", List(MockParam("f"))), - ScalaMockDocumentation("scala/collection/LinearSeqOps#foldLeft().", "foldLeft", List(MockParam("z"), MockParam("op"))), - ScalaMockDocumentation("scala/util/control/Exception.Catch#", "Catch", List(MockParam("pf"), MockParam("fin"), MockParam("rethrow"))) + ScalaMockDocumentation("scala/Option#fold().", "fold", List(MockParam("B")), List(MockParam("ifEmpty"), MockParam("f"))), + ScalaMockDocumentation("scala/Option.apply().", "apply", List(), List(MockParam("x"))), + ScalaMockDocumentation("scala/collection/immutable/List#map().", "map", List(MockParam("B")), List(MockParam("f"))), + ScalaMockDocumentation("scala/collection/LinearSeqOps#foldLeft().", "foldLeft", List(MockParam("B")), List(MockParam("z"), MockParam("op"))), + ScalaMockDocumentation("scala/util/control/Exception.Catch#", "Catch", List(), List(MockParam("pf"), MockParam("fin"), MockParam("rethrow"))) ) @Test def `curry` = @@ -45,6 +45,7 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: s"""Found documentation for scala/Option#fold(). |fold[B](ifEmpty: => B)(f: Int => B): B | ^^^^^^^^^^^ + | @param B Found documentation for type param B | @param ifEmpty Found documentation for param ifEmpty | @param f Found documentation for param f """.stripMargin @@ -60,6 +61,7 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: s"""|Found documentation for scala/Option#fold(). |fold[B](ifEmpty: => B)(f: Int => B): B | ^^^^^^^^^^^^^ + | @param B Found documentation for type param B | @param ifEmpty Found documentation for param ifEmpty | @param f Found documentation for param f |""".stripMargin @@ -77,6 +79,7 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: """|Found documentation for scala/collection/LinearSeqOps#foldLeft(). |foldLeft[B](z: B)(op: (B, Int) => B): B | ^^^^^^^^^^^^^^^^^ + | @param B Found documentation for type param B | @param z Found documentation for param z | @param op Found documentation for param op |""".stripMargin @@ -106,6 +109,7 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: """|Found documentation for scala/collection/immutable/List#map(). |map[B](f: Int => B): List[B] | ^^^^^^^^^^^ + | @param B Found documentation for type param B | @param f Found documentation for param f |""".stripMargin ) @@ -134,6 +138,7 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: """|Found documentation for java/util/Collections#singleton(). |singleton[T](o: T): java.util.Set[T] | ^^^^ + | @param T Found documentation for type param T | @param o Found documentation for param o |""".stripMargin ) @@ -146,8 +151,8 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: |} """.stripMargin, """|Found documentation for scala/util/control/Exception.Catch# - |Catch[T](pf: scala.util.control.Exception.Catcher[T], fin: Option[scala.util.control.Exception.Finally], rethrow: Throwable => Boolean) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |Catch[T](pf: Catcher[T], fin: Option[Finally], rethrow: Throwable => Boolean) + | ^^^^^^^^^^^^^^ | @param pf Found documentation for param pf | @param fin Found documentation for param fin | @param rethrow Found documentation for param rethrow @@ -161,9 +166,9 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite: | new java.io.File(@@) |} """.stripMargin, - """|File(uri: java.net.URI) - | ^^^^^^^^^^^^^^^^^ - |File(parent: java.io.File, child: String) + """|File(uri: URI) + | ^^^^^^^^ + |File(parent: File, child: String) |File(parent: String, child: String) |File(pathname: String) |""".stripMargin diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpInterleavingSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpInterleavingSuite.scala new file mode 100644 index 000000000000..15546d086033 --- /dev/null +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpInterleavingSuite.scala @@ -0,0 +1,518 @@ +package dotty.tools.pc.tests.signaturehelp + +import dotty.tools.pc.base.BaseSignatureHelpSuite + +import org.junit.Test +import org.junit.Ignore +import java.nio.file.Path + +class SignatureHelpInterleavingSuite extends BaseSignatureHelpSuite: + + override protected def scalacOptions(classpath: Seq[Path]): Seq[String] = + List("-language:experimental.clauseInterleaving") + + @Test def `proper-position-1` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[@@Int](1)[String]("1") + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + + @Test def `proper-position-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](@@1)[String]("1") + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `proper-position-3` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](1)[@@String]("1") + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `proper-position-4` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](1)[String](@@"1") + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `not-fully-applied-1` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[@@Int] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + + @Test def `not-fully-applied-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](@@1) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `not-fully-applied-3` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](1)[@@String] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `error` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int][@@String] + """.stripMargin, + "" + ) + + @Test def `inferred-type-param-1` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair(1@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `inferred-type-param-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair(1)[String@@] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `inferred-type-param-3` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair(1)[String]("1"@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `inferred-type-param-4` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair(1)("1"@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-current-param-check` = + check( + """ + |object Test: + | def pair[A](a: A): A = ??? + | pair[@@] + """.stripMargin, + """ + |pair[A](a: A): A + | ^ + |""".stripMargin + ) + + @Test def `empty-current-param-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-current-param-3` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](1)[@@] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `empty-current-param-4` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[Int](1)[String](@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-current-inferred-1` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair(@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-current-inferred-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair(1)(@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-previous-1` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[](@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-previous-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[]()[@@] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `empty-previous-3` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[]()[](@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-previous-4` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[]()[](11@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-previous-5` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[](5@@1) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `empty-previous-6` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[String]()[@@] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `empty-previous-7` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[String]()[Int](@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `error-previous-1` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[String](52)[@@] + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^ + |""".stripMargin + ) + + @Test def `error-previous-2` = + check( + """ + |object Test: + | def pair[A](a: A)[B](b: B): (A, B) = (a, b) + | pair[String](52)[Int](""@@) + """.stripMargin, + """ + |pair[A](a: A)[B](b: B): (A, B) + | ^^^^ + |""".stripMargin + ) + + @Test def `complex-1` = + check( + """ + |object Test: + | def foo[A](using a: A)(b: List[A])[C <: a.type, D](cd: (C, D))[E]: Foo[A, B, C, D, E] + | foo[Int](using 1)(List(1, 2, 3))(@@) + """.stripMargin, + """ + |foo[A](using a: A)(b: List[A])[C <: a.type, D](cd: (C, D))[E]: Foo[A, B, C, D, E] + | ^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `complex-2` = + check( + """ + |object Test: + | def foo[A](using a: A)(b: List[A])[C <: a.type, D](cd: (C, D))[E]: Foo[A, B, C, D, E] + | foo[Int](using 1)(List(1, 2, 3))((1, 2))[@@] + """.stripMargin, + """ + |foo[A](using a: A)(b: List[A])[C <: a.type, D](cd: (C, D))[E]: Foo[A, B, C, D, E] + | ^ + |""".stripMargin + ) + + @Ignore("""Clause interleaving is still experimental. It lifts this tree into series of anonymous functions, which all have the same span. + It requires further investigation to determine whether this is a bug in the compiler.""") + @Test def `clause-interleaving-empty` = + check( + """|object M: + | def test[X](x: X)[Y](y: Y): (X, Y)= ??? + | test[@@] + |""".stripMargin, + """|test[X](x: X)[Y](y: Y): (X, Y) + | ^ + |""".stripMargin + ) + + @Ignore("""Clause interleaving is still experimental. It lifts this tree into series of anonymous functions, which all have the same span. + It requires further investigation to determine whether this is a bug in the compiler.""") + @Test def `more-interleaved-params-1` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[@@] + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^ + |""".stripMargin + ) + + @Test def `more-interleaved-params-2` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](@@) + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^^^^ + |""".stripMargin + ) + + @Ignore("""Clause interleaving is still experimental. It lifts this tree into series of anonymous functions, which all have the same span. + It requires further investigation to determine whether this is a bug in the compiler.""") + @Test def `more-interleaved-params-3` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)[@@] + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^ + |""".stripMargin + ) + + @Test def `more-interleaved-params-4` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)[String](@@) + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^^^^ + |""".stripMargin + ) + + @Ignore("""Clause interleaving is still experimental. It lifts this tree into series of anonymous functions, which all have the same span. + It requires further investigation to determine whether this is a bug in the compiler.""") + @Test def `more-interleaved-params-5` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)[String]("1")[@@] + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^ + |""".stripMargin + ) + + @Test def `more-interleaved-params-6` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)[String]("1")[Int](@@) + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^^^^ + |""".stripMargin + ) + + @Test def `more-interleaved-params-7` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)[String]("1")[Int](2)[@@] + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^ + |""".stripMargin + ) + + @Test def `more-interleaved-params-8` = + check( + """|object M: + | def test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)[String]("1")[Int](2)[String](@@) + |""".stripMargin, + """|test[A](a: A)[B](b: B)[C](c: C)[D](d: D): Int + | ^^^^ + |""".stripMargin + ) + + @Test def `interleaving-with-implicit` = + check( + """|object M: + | def test[A](a: A)(using Int)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)(using 5)[String]("1")[Int](@@) + |""".stripMargin, + """|test[A](a: A)(using Int)[B](b: B)[C](c: C)[D](d: D): Int + | ^^^^ + |""".stripMargin + ) + + @Test def `interleaving-with-implicit-recovery` = + check( + """|object M: + | def test[A](a: A)(using Int)[B](b: B)[C](c: C)[D](d: D): Int = ??? + | test[Int](1)(5)[String]("1")[Int](@@) + |""".stripMargin, + """|test[A](a: A)(using Int)[B](b: B)[C](c: C)[D](d: D): Int + | ^^^^ + |""".stripMargin + ) + diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpNamedArgsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpNamedArgsSuite.scala new file mode 100644 index 000000000000..1906e12a0254 --- /dev/null +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpNamedArgsSuite.scala @@ -0,0 +1,300 @@ +package dotty.tools.pc.tests.signaturehelp + +import dotty.tools.pc.base.BaseSignatureHelpSuite + +import org.junit.Test + +class SignatureHelpNamedArgsSuite extends BaseSignatureHelpSuite: + + + @Test def `new-named-param-style-1` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-double-space` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-before-equal` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, paramB @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-before-equal-something-after` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, paramB @@) + | def test: Unit = () + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-at-equal` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, paramB =@@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-after-equal` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, paramB = 1@@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-2` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 1, @@) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramC: Int], [paramD: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-3` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 1, paramC = 2, paramD = 3, @@) + |""".stripMargin, + """|method([paramB: Int], [paramC: Int], [paramD: Int], [paramA: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-4` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(1, 2, @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-5` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(1, paramB = 2, @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-6` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, 2, @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-7` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramA = 1, paramB = 2, @@) + |""".stripMargin, + """|method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-8` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 2, paramA = 1, @@) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramC: Int], [paramD: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-9` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramC = 3, paramA = 1, @@) + |""".stripMargin, + """|method([paramC: Int], [paramA: Int], [paramB: Int], [paramD: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-10` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramC = 3, @@ ,paramA = 1) + |""".stripMargin, + """|method([paramC: Int], [paramB: Int], [paramA: Int], [paramD: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `new-named-param-style-11` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramC = 3, paramB = 1, @@ ,paramA = 1) + |""".stripMargin, + """|method([paramC: Int], [paramB: Int], [paramD: Int], [paramA: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-param-before-first` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(@@paramC = 3) + |""".stripMargin, + """|method([paramC: Int], [paramA: Int], [paramB: Int], [paramD: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-param-inside-reordered-last-arg` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 3, paramA = 1, @@paramD = 3, paramC = 1) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramD: Int], [paramC: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-param-inside-reorderded-last-arg-1` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 3, paramA = 1, p@@aramD = 3, paramC = 1) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramD: Int], [paramC: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-param-before-reorderded-last-arg-1` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 3, paramA = 1,@@ paramD = 3, paramC = 1) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramD: Int], [paramC: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-param-properly-order-1` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(par@@amB = 3, paramA = 1, paramD = 3, paramC = 1) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramD: Int], [paramC: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-param-properly-order-2` = + check( + """|object O: + | def method(paramA: Int, paramB: Int, paramC: Int, paramD: Int): Unit = ??? + | method(paramB = 3, par@@amA = 1, paramD = 3, paramC = 1) + |""".stripMargin, + """|method([paramB: Int], [paramA: Int], [paramD: Int], [paramC: Int]): Unit + | ^^^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-with-type-args` = + check( + """|object Main: + | def test[T, F](aaa: Int, bbb: T, ccc: F): T = ??? + | val x = test(1, ccc = 2, b@@) + |""".stripMargin, + """|test[T, F](aaa: Int, [ccc: F], [bbb: T]): T + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-newline` = + check( + """|object Main: + | def test2(aaa: Int, bbb: Int, ccc: Int): Int = ??? + | val x = test2( + | 1, + | @@ + | ) + |""".stripMargin, + """|test2(aaa: Int, bbb: Int, ccc: Int): Int + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-before-comma` = + check( + """|object Main: + | def test2(aaa: Int, bbb: Int, ccc: Int): Int = ??? + | val x = test2(aaa = 2@@, ccc = 1) + |""".stripMargin, + """|test2(aaa: Int, [ccc: Int], [bbb: Int]): Int + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `named-on-whitespaces-between-args` = + check( + """|object Main: + | def test2(aaa: Int, bbb: Int, ccc: Int): Int = ??? + | val x = test2(aaa = 2, @@ ccc = 1, bbb = 3) + | + |""".stripMargin, + """|test2(aaa: Int, [ccc: Int], [bbb: Int]): Int + | ^^^^^^^^^^ + |""".stripMargin + ) + diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpPatternSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpPatternSuite.scala index f8a368a5ea3a..d01145510367 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpPatternSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpPatternSuite.scala @@ -202,23 +202,6 @@ class SignatureHelpPatternSuite extends BaseSignatureHelpSuite: |""".stripMargin ) - @Test def `pat4` = - check( - """ - |object & { - | def unapply[A](a: A): Some[(A, A)] = Some((a, a)) - |} - |object a { - | "" match { - | case "" & s@@ - | } - |} - """.stripMargin, - """|(String, String) - | ^^^^^^ - |""".stripMargin - ) - @Test def `pat5` = check( """ @@ -255,6 +238,24 @@ class SignatureHelpPatternSuite extends BaseSignatureHelpSuite: |""".stripMargin ) + @Test def `shortened` = + check( + """ + |object Test { + | def unapply(command: java.io.File): Option[java.io.File] = { + | Some(Some(1)) + | } + | + | "" match { + | case Test(@@) => + | } + |} + """.stripMargin, + """|(File) + | ^^^^ + |""".stripMargin + ) + @Test def `pat-negative` = check( """ diff --git a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala index 906a0bd9b72e..c1b51b127fd6 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/signaturehelp/SignatureHelpSuite.scala @@ -66,7 +66,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: """|Random() |Random(seed: Int) |Random(seed: Long) - |Random(self: java.util.Random) + |Random(self: Random) |""".stripMargin ) @@ -103,9 +103,9 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new File(@@) |} """.stripMargin, - """|File(x$0: java.net.URI) - | ^^^^^^^^^^^^^^^^^ - |File(x$0: java.io.File, x$1: String) + """|File(x$0: URI) + | ^^^^^^^^ + |File(x$0: File, x$1: String) |File(x$0: String, x$1: String) |File(x$0: String) |""".stripMargin @@ -118,9 +118,9 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new java.io.File(@@) |} """.stripMargin, - """|File(x$0: java.net.URI) - | ^^^^^^^^^^^^^^^^^ - |File(x$0: java.io.File, x$1: String) + """|File(x$0: URI) + | ^^^^^^^^ + |File(x$0: File, x$1: String) |File(x$0: String, x$1: String) |File(x$0: String) |""".stripMargin @@ -191,12 +191,12 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: |""".stripMargin ) - // https://github.com/lampepfl/dotty/issues/15244 + // https://github.com/scala/scala3/issues/15244 @Test def `vararg` = check( """ |object a { - | List(1, 2@@ + | List(1, 2@@) |} """.stripMargin, """|apply[A](elems: A*): List[A] @@ -323,9 +323,9 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | } yield k |} """.stripMargin, - """|to(end: Int): scala.collection.immutable.Range.Inclusive + """|to(end: Int): Inclusive | ^^^^^^^^ - |to(end: Int, step: Int): scala.collection.immutable.Range.Inclusive + |to(end: Int, step: Int): Inclusive |""".stripMargin, stableOrder = false ) @@ -388,7 +388,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | | """.stripMargin, - """|apply(viewId: String, nodeUri: String, label: String, command: String, icon: String, tooltip: String, collapseState: String): TreeViewNode + """|apply(viewId: String, nodeUri: String, label: String, [collapseState: String], [command: String], [icon: String], [tooltip: String]): TreeViewNode | ^^^^^^^^^^^^^^ |""".stripMargin ) @@ -424,7 +424,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | | """.stripMargin, - """|apply(viewId: String, nodeUri: String, label: String, command: String, collapseState: String): TreeViewNode + """|apply(viewId: String, nodeUri: String, label: String, [collapseState: String], [command: String]): TreeViewNode | ^^^^^^^^^^^^^^ |""".stripMargin ) @@ -437,8 +437,8 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | User(age = 1, @@) |} """.stripMargin, - """|apply(name: String, age: Int): User - | ^^^^^^^^ + """|apply([age: Int], [name: String]): User + | ^^^^^^^^^^^^^^ |""".stripMargin ) @@ -477,8 +477,8 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | def x = user(str@@eet = 42, name = "", age = 2) |} """.stripMargin, - """|user(name: String, age: Int, street: Int): Int - | ^^^^^^^^^^^ + """|user([street: Int], [name: String], [age: Int]): Int + | ^^^^^^^^^^^^^ |user(name: String, age: Int): Int |""".stripMargin ) @@ -502,9 +502,8 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new scala.util.control.Exception.Catch(@@) |} """.stripMargin, - // TODO short names are not supported yet - """|Catch[T](pf: scala.util.control.Exception.Catcher[T], fin: Option[scala.util.control.Exception.Finally], rethrow: Throwable => Boolean) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + """|Catch[T](pf: Catcher[T], fin: Option[Finally], rethrow: Throwable => Boolean) + | ^^^^^^^^^^^^^^ |""".stripMargin ) @@ -515,7 +514,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | new java.util.HashMap[String, Int]().computeIfAbsent(@@) |} """.stripMargin, - // TODO short names are not supported yet + // This is the correct result, as there is a conflict at Function: scala.Function and java.util.function.Function """|computeIfAbsent(x$0: String, x$1: java.util.function.Function[? >: String, ? <: Int]): Int | ^^^^^^^^^^^ |""".stripMargin @@ -650,9 +649,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | identity(42)@@ |} |""".stripMargin, - """|identity[A](x: A): A - | ^^^^ - |""".stripMargin + "" ) @Test def `off-by-one2` = @@ -675,7 +672,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: |} |""".stripMargin, """|fold[B](ifEmpty: => B)(f: Int => B): B - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^ |""".stripMargin ) @@ -763,24 +760,13 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: """|object O: | implicit class Test[T](xs: List[T]): | def test(x: T): List[T] = ??? - | List(1,2,3).test(@@""".stripMargin, + | List(1,2,3).test(s@@)""".stripMargin, """|test(x: Int): List[Int] | ^^^^^^ |""".stripMargin ) @Test def `instantiated-type-var-old-ext-2` = - check( - """|object O: - | implicit class Test[T](xs: List[T]): - | def test(x: T): List[T] = ??? - | List(1,2,3).test(s@@""".stripMargin, - """|test(x: Int): List[Int] - | ^^^^^^ - |""".stripMargin - ) - - @Test def `instantiated-type-var-old-ext-3` = check( """|object O: | implicit class Test[T](xs: List[T]): @@ -791,7 +777,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: |""".stripMargin ) - @Test def `instantiated-type-var-old-ext-4` = + @Test def `instantiated-type-var-old-ext-3` = check( """|object O: | implicit class Test[T](xs: List[T]): @@ -804,7 +790,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: |""".stripMargin ) - @Test def `instantiated-type-var-old-ext-5` = + @Test def `instantiated-type-var-old-ext-4` = check( """|object O: | implicit class Test[T](xs: List[T]): @@ -818,7 +804,7 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: |""".stripMargin ) - @Test def `instantiated-type-var-old-ext-6` = + @Test def `instantiated-type-var-old-ext-5` = check( """|object O: | implicit class Test[T](xs: List[T]): @@ -829,3 +815,687 @@ class SignatureHelpSuite extends BaseSignatureHelpSuite: | ^^^^^^ |""".stripMargin ) + + @Test def `multiline-before` = + check( + """|object Main { + | def deployment( + | fst: String, + | snd: Int = 1, + | ): Option[Int] = ??? + | val abc = deployment(@@ + | fst = "abc", + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment(fst: String, snd: Int): Option[Int] + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `multiline-after-first` = + check( + """|object Main { + | def deployment( + | fst: String, + | snd: Int = 1, + | ): Option[Int] = ??? + | val abc = deployment( + | fst = "abc", @@ + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment(fst: String, snd: Int): Option[Int] + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `multiline-between-first-and-second-a` = + check( + """|object Main { + | def deployment( + | fst: String, + | snd: Int = 1, + | ): Option[Int] = ??? + | val abc = deployment( + | fst = "abc" + | @@ + | + | ,snd = 1 + | ) + |} + |""".stripMargin, + """|deployment(fst: String, snd: Int): Option[Int] + | ^^^^^^^^^^^ + |""".stripMargin + ) + + @Test def `multiline-between-first-and-second-b` = + check( + """|object Main { + | def deployment( + | fst: String, + | snd: Int = 1, + | ): Option[Int] = ??? + | val abc = deployment( + | fst = "abc", + | @@ + | + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment(fst: String, snd: Int): Option[Int] + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `multiline-end` = + check( + """|object Main { + | def deployment( + | fst: String, + | snd: Int = 1, + | ): Option[Int] = ??? + | val abc = deployment( + | fst = "abc", + | snd = 1 + | @@) + |} + |""".stripMargin, + """|deployment(fst: String, snd: Int): Option[Int] + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `type-var-multiline-before` = + check( + """|object Main { + | def deployment[A, B]( + | fst: A, + | snd: B, + | ): Option[Int] = ??? + | val abc = deployment[@@ + Int, + | String, + | ]( + | fst = "abc", + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment[A, B](fst: A, snd: B): Option[Int] + | ^ + |""".stripMargin + ) + + @Test def `type-var-multiline-after` = + check( + """|object Main { + | def deployment[A, B]( + | fst: A, + | snd: B, + | ): Option[Int] = ??? + | val abc = deployment[ + | Int, @@ + | String, + | ]( + | fst = "abc", + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment[A, B](fst: A, snd: B): Option[Int] + | ^ + |""".stripMargin + ) + + @Test def `type-var-multiline-between-first-and-second-a` = + check( + """|object Main { + | def deployment[A, B]( + | fst: A, + | snd: B, + | ): Option[Int] = ??? + | val abc = deployment[ + | Int + | @@ + | + | ,String + | ]( + | fst = "abc", + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment[A, B](fst: A, snd: B): Option[Int] + | ^ + |""".stripMargin + ) + + @Test def `type-var-multiline-between-first-and-second-b` = + check( + """|object Main { + | def deployment[A, B]( + | fst: A, + | snd: B, + | ): Option[Int] = ??? + | val abc = deployment[ + | Int, + | @@ + | + | String, + | ]( + | fst = "abc", + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment[A, B](fst: A, snd: B): Option[Int] + | ^ + |""".stripMargin + ) + + @Test def `type-var-multiline-end` = + check( + """|object Main { + | def deployment[A, B]( + | fst: A, + | snd: B, + | ): Option[Int] = ??? + | val abc = deployment[ + | String, + | Int, + | @@]( + | fst = "abc", + | snd = 1 + | ) + |} + |""".stripMargin, + """|deployment[A, B](fst: A, snd: B): Option[Int] + | ^ + |""".stripMargin + ) + + @Test def `dont-show-directly-after-parenthesis` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, 2)@@ + |} + |""".stripMargin, + "" + ) + + @Test def `dont-show-directly-after-parenthesis-2` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, 2)@@ + |""".stripMargin, + "" + ) + + @Test def `dont-show-directly-when-unclosed` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, (2 + 1)@@ + |} + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-1` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, 2) @@ + |} + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-2` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, 2) @@ + |} + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-newline` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, 2) + |@@ + |} + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-newline-last-statement` = + check( + """|object Main: + | def test(a: Int, b: Int): Int = ??? + | test(1, 2) + | + |@@ + | + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-newline-last-statement-unclosed-1` = + check( + """|object Main: + | def test(a: Int, b: Int): Int = ??? + | test(1, 2 + | + |@@ + | + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-newline-last-statement-unclosed-2` = + check( + """|object Main: + | def test(a: Int, b: Int): Int = ??? + | test(1, (1 + 2) + | + |@@ + | + |""".stripMargin, + "" + ) + + @Test def `dont-show-after-parenthesis-unclosed-2` = + check( + """|object Main { + | def test(a: Int, b: Int): Int = ??? + | test(1, 2 + | + | @@ + |} + |""".stripMargin, + "" + ) + + @Test def `select-arg-detection` = + check( + """|object Main: + | object Foo: + | case class Test(x: Int) + | def test(a: Foo.Test, b: Foo.Test): Int = ??? + | test(Foo.Test(1), @@) + |""".stripMargin, + """|test(a: Test, b: Test): Int + | ^^^^^^^ + |""".stripMargin + ) + + @Test def `singature-help-works-in-select` = + check( + """|object Main: + | object Foo: + | class Test(x: Int, y: Int) + | new Foo.Test(1, @@) + |""".stripMargin, + """|Test(x: Int, y: Int) + | ^^^^^^ + |""".stripMargin + ) + + @Test def `curried-help-works-in-select` = + check( + """|object Main: + | def test(xxx: Int, yyy: Int)(zzz: Int): Int = ??? + | test(yyy = 5, xxx = 7)(@@) + |""".stripMargin, + """|test([yyy: Int], [xxx: Int])(zzz: Int): Int + | ^^^^^^^^ + |""".stripMargin + ) + + @Test def `no-signature-help-for-parameterless-method` = + check( + """|object Main: + | def test: Int = ??? + | test(@@) + |""".stripMargin, + "" + ) + + @Test def `show-methods-returning-tuples` = + check( + """|object Main: + | def test(): (Int, Int) = ??? + | test(@@) + |""".stripMargin, + "test(): (Int, Int)" + ) + + @Test def `show-methods-returning-tuples-2` = + check( + """|object Main: + | def test(x: Int): (Int, Int) = ??? + | test(@@) + |""".stripMargin, + """|test(x: Int): (Int, Int) + | ^^^^^^ + |""".stripMargin + ) + + @Test def `dont-show-tuples-application` = + check( + """|object Main: + | (1, @@) + |""".stripMargin, + "" + ) + + // Improvement would be to create synthetic signature help showing + // add(x: Int)(y: Int): Int + @Test def `dont-show-functionN` = + check( + """|object Main: + | val add = (x: Int) => (y: Int) => x + y + | add(@@) + |""".stripMargin, + "" + ) + + @Test def `dont-show-functionN-2` = + check( + """|object Main: + | val add = (x: Int) => (y: Int) => x + y + | add(1, @@) + |""".stripMargin, + "" + ) + + @Test def `type-param-start` = + check( + """|object Main: + | def test[A](x: A): A = ??? + | test[@@] + |""".stripMargin, + """|test[A](x: A): A + | ^ + |""".stripMargin + ) + + @Test def `error-recovery-1` = + check( + """|object Main: + | def test[A](x: A): Foo[A] = ??? + | test[@@] + |""".stripMargin, + """|test[A](x: A): Foo[A] + | ^ + |""".stripMargin + ) + + @Test def `error-recovery-2` = + check( + """|object Main: + | def test[A](x: A): Foo[A] = ??? + | test[Int](@@) + |""".stripMargin, + """|test[A](x: A): Foo[A] + | ^^^^ + |""".stripMargin + ) + + @Test def `type-param-shortening` = + check( + """|object M: + | def test[T <: java.io.File](x: Int): Int = ??? + | test(@@) + |""".stripMargin, + """|test[T <: File](x: Int): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `implicit-param` = + check( + """|object M: + | trait Context + | def test(x: Int)(using ctx: Context): Int = ??? + | test(@@) + |""".stripMargin, + """|test(x: Int)(using ctx: Context): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `context-param` = + check( + """|object M: + | def test(x: Int, y: Int = 7)(z: Int ?=> Int): Int = ??? + | test(@@) + |""".stripMargin, + """|test(x: Int, y: Int)(z: (Int) ?=> Int): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `empty-implicit-params` = + check( + """|object M: + | def test(x: Int)(using String): Int = ??? + | test(1)(@@) + |""".stripMargin, + """|test(x: Int)(using String): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `multiple-implicits-1` = + check( + """|object M: + | def a(using Int)(using String): Int = ??? + | a(@@) + |""".stripMargin, + """|a(using Int)(using String): Int + | ^^^ + |""".stripMargin + ) + + + @Test def `multiple-implicits-2` = + check( + """|object M: + | def a(using Int)(using String): Int = ??? + | a(using 5)(@@) + |""".stripMargin, + """|a(using Int)(using String): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `multiple-implicits-3` = + check( + """|object M: + | def a(using Int)(using String)(x: Int): Int = ??? + | a(@@) + |""".stripMargin, + """|a(using Int)(using String)(x: Int): Int + | ^^^ + |""".stripMargin + ) + + @Test def `multiple-implicits-4` = + check( + """|object M: + | def a(using Int)(using String)(x: Int): Int = ??? + | a(using 5)(@@) + |""".stripMargin, + """|a(using Int)(using String)(x: Int): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `multiple-implicits-error-1` = + check( + """|object M: + | def a(using Int)(using String)(x: Int): Int = ??? + | a(5)(@@) + |""".stripMargin, + """| + |a(using Int)(using String)(x: Int): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `multiple-implicits-error-2` = + check( + """|object M: + | def a(using Int)(using String)(x: Int): Int = ??? + | a(5)(@@) + |""".stripMargin, + """|a(using Int)(using String)(x: Int): Int + | ^^^^^^ + |""".stripMargin + ) + + @Test def `dont-crash-at-last-position` = + check( + """|object M: + | def test(x: Int): Int = ??? + | test(@@""".stripMargin, + "" + ) + + @Test def `type-var-position` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[A@@, C]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-1` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[@@A, C]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-2` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[A@@ + | , C]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-3` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[A, C@@]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-4` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[A,@@ C]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-5` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[A, @@C]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-6` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[ + | A@@, + | C + | ]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-7` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[ + | A, + | C@@ + | ]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-8` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[ + | A, + | @@C + | ]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-9` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[ + | A, + | C + | @@]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) + + @Test def `type-var-position-10` = + check( + """|trait Test[A, B]: + | def doThing[C](f: B => Test[@@ + | A, + | C + | ]) = ??? + |""".stripMargin, + """|Test[A, B]: Test + | ^ + |""".stripMargin + ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala index e18e37188141..fd90a8dfaca0 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala @@ -285,7 +285,7 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite: |}""".stripMargin ) - @Test def `predef1` = + @Test def `predef1` = check( """ |object <<Main>>/*class*/ { @@ -296,7 +296,7 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite: |""".stripMargin ) - @Test def `val-object` = + @Test def `val-object` = check( """ |case class <<X>>/*class*/(<<a>>/*variable,declaration,readonly*/: <<Int>>/*class,abstract*/) @@ -411,4 +411,24 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite: | } | val <<x>>/*variable,definition,readonly*/ = <<Abc>>/*class*/(123, 456) |}""".stripMargin + ) + + @Test def `i5977` = + check( + """ + |sealed trait <<ExtensionProvider>>/*interface,abstract*/ { + | extension [<<A>>/*typeParameter,definition,abstract*/] (<<self>>/*parameter,declaration,readonly*/: <<A>>/*typeParameter,abstract*/) { + | def <<typeArg>>/*method,declaration*/[<<B>>/*typeParameter,definition,abstract*/]: <<B>>/*typeParameter,abstract*/ + | def <<inferredTypeArg>>/*method,declaration*/[<<C>>/*typeParameter,definition,abstract*/](<<value>>/*parameter,declaration,readonly*/: <<C>>/*typeParameter,abstract*/): <<C>>/*typeParameter,abstract*/ + |} + | + |object <<Repro>>/*class*/ { + | def <<usage>>/*method,definition*/[<<A>>/*typeParameter,definition,abstract*/](<<f>>/*parameter,declaration,readonly*/: <<ExtensionProvider>>/*interface,abstract*/ ?=> <<A>>/*typeParameter,abstract*/ => <<Any>>/*class,abstract*/): <<Any>>/*class,abstract*/ = <<???>>/*method*/ + | + | <<usage>>/*method*/[<<Int>>/*class,abstract*/](<<_>>/*parameter,readonly*/.<<inferredTypeArg>>/*method*/("str")) + | <<usage>>/*method*/[<<Int>>/*class,abstract*/](<<_>>/*parameter,readonly*/.<<inferredTypeArg>>/*method*/[<<String>>/*type*/]("str")) + | <<usage>>/*method*/[<<Option>>/*class,abstract*/[<<Int>>/*class,abstract*/]](<<_>>/*parameter,readonly*/.<<typeArg>>/*method*/[<<Some>>/*class*/[<<Int>>/*class,abstract*/]].<<value>>/*variable,readonly*/.<<inferredTypeArg>>/*method*/("str")) + | <<usage>>/*method*/[<<Option>>/*class,abstract*/[<<Int>>/*class,abstract*/]](<<_>>/*parameter,readonly*/.<<typeArg>>/*method*/[<<Some>>/*class*/[<<Int>>/*class,abstract*/]].<<value>>/*variable,readonly*/.<<inferredTypeArg>>/*method*/[<<String>>/*type*/]("str")) + |} + |""".stripMargin ) \ No newline at end of file diff --git a/presentation-compiler/test/dotty/tools/pc/utils/MockEntries.scala b/presentation-compiler/test/dotty/tools/pc/utils/MockEntries.scala index 05cd2cb8c124..1c0c35c0c71e 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/MockEntries.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/MockEntries.scala @@ -28,6 +28,7 @@ abstract class MockEntries: def apply( symbol: String, displayName: String, + typeParams: List[MockParam] = Nil, params: List[MockParam] = Nil ): SymbolDocumentation = ScalaSymbolDocumentation( @@ -35,7 +36,14 @@ abstract class MockEntries: displayName, s"Found documentation for $symbol", "", - Nil.asJava, + typeParams + .map: param => + ScalaSymbolDocumentation( + param.name, + param.name, + s"Found documentation for type param ${param.name}\n", + ) + .asJava, params .map(param => ScalaSymbolDocumentation( @@ -43,8 +51,6 @@ abstract class MockEntries: param.name, s"Found documentation for param ${param.name}\n", param.defaultValue, - Nil.asJava, - Nil.asJava ) ) .asJava diff --git a/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala b/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala index b0be98850630..edd339a5e2ed 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala @@ -43,7 +43,7 @@ class MockSymbolSearch( ): SymbolSearch.Result = val query = WorkspaceSymbolQuery.exact(textQuery) workspace.search(query, visitor) - classpath.search(query, visitor) + classpath.search(query, visitor)._1 override def searchMethods( textQuery: String, diff --git a/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala b/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala index 5efb0feaeb9a..6dfc8acec66c 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala @@ -128,11 +128,11 @@ trait PcAssertions: val lines = diff.linesIterator.toList val sources = completionSources.padTo(lines.size, CompletionSource.Empty) val maxLength = lines.map(_.length).maxOption.getOrElse(0) - var redLineIndex = 0 + var completionIndex = 0 lines.map: line => - if line.startsWith(Console.BOLD + Console.RED) then - redLineIndex = redLineIndex + 1 - s"$line | [${sources(redLineIndex - 1)}]" + if line.startsWith(Console.BOLD + Console.RED) || line.startsWith(" ") then + completionIndex += 1 + s"$line | [${sources(completionIndex - 1)}]" else line .mkString("\n") diff --git a/project/Build.scala b/project/Build.scala index 1640bf0fac1b..b8bcbde97e7b 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -83,9 +83,9 @@ object DottyJSPlugin extends AutoPlugin { object Build { import ScaladocConfigs._ - val referenceVersion = "3.3.1" + val referenceVersion = "3.4.0" - val baseVersion = "3.4.0" + val baseVersion = "3.4.1" // Versions used by the vscode extension to create a new project // This should be the latest published releases. @@ -101,7 +101,10 @@ object Build { * set to 3.1.3. If it is going to be 3.1.0, it must be set to the latest * 3.0.x release. */ - val previousDottyVersion = "3.3.1" + val previousDottyVersion = "3.4.0" + + /** Version against which we check binary compatibility. */ + val ltsDottyVersion = "3.3.0" object CompatMode { final val BinaryCompatible = 0 @@ -137,8 +140,8 @@ object Build { val stdlibBootstrappedVersion = "2.13.12" val dottyOrganization = "org.scala-lang" - val dottyGithubUrl = "https://github.com/lampepfl/dotty" - val dottyGithubRawUserContentUrl = "https://raw.githubusercontent.com/lampepfl/dotty" + val dottyGithubUrl = "https://github.com/scala/scala3" + val dottyGithubRawUserContentUrl = "https://raw.githubusercontent.com/scala/scala3" val isRelease = sys.env.get("RELEASEBUILD") == Some("yes") @@ -173,11 +176,23 @@ object Build { // Run tests with filter through vulpix test suite val testCompilation = inputKey[Unit]("runs integration test with the supplied filter") + sealed trait Scala2Library + // Use Scala 2 compiled library JAR + object Scala2LibraryJar extends Scala2Library // Use the TASTy jar from `scala2-library-tasty` in the classpath // This only works with `scala3-bootstrapped/scalac` and tests in `scala3-bootstrapped` // - // Enable in SBT with: `set ThisBuild/Build.useScala2LibraryTasty := true` - val useScala2LibraryTasty = settingKey[Boolean]("Use the TASTy jar from `scala2-library-tasty` in the classpath") + object Scala2LibraryTasty extends Scala2Library + // Use the TASTy jar from `scala2-library-cc-tasty` in the classpath + // This only works with `scala3-bootstrapped/scalac` and tests in `scala3-bootstrapped` + // + object Scala2LibraryCCTasty extends Scala2Library + + // Set in SBT with: + // - `set ThisBuild/Build.scala2Library := Build.Scala2LibraryJar` (default) + // - `set ThisBuild/Build.scala2Library := Build.Scala2LibraryTasty` + // - `set ThisBuild/Build.scala2Library := Build.Scala2LibraryCCTasty` + val scala2Library = settingKey[Scala2Library]("Choose which version of the Scala 2 library should be used") // Used to compile files similar to ./bin/scalac script val scalac = inputKey[Unit]("run the compiler using the correct classpath, or the user supplied classpath") @@ -225,7 +240,7 @@ object Build { outputStrategy := Some(StdoutOutput), - useScala2LibraryTasty := false, + scala2Library := Scala2LibraryJar, // enable verbose exception messages for JUnit (Test / testOptions) += Tests.Argument(TestFrameworks.JUnit, "-a", "-v", "-s"), @@ -364,7 +379,7 @@ object Build { "-skip-by-regex:.+\\.impl($|\\..+)", "-project-logo", "docs/_assets/images/logo.svg", "-social-links:" + - "github::https://github.com/lampepfl/dotty," + + "github::https://github.com/scala/scala3," + "discord::https://discord.com/invite/scala," + "twitter::https://twitter.com/scala_lang", // contains special definitions which are "transplanted" elsewhere @@ -516,7 +531,9 @@ object Build { settings(commonMiMaSettings). settings( versionScheme := Some("semver-spec"), - mimaBinaryIssueFilters ++= MiMaFilters.Interfaces + mimaForwardIssueFilters := MiMaFilters.Interfaces.ForwardsBreakingChanges, + mimaBackwardIssueFilters := MiMaFilters.Interfaces.BackwardsBreakingChanges, + customMimaReportBinaryIssues("MiMaFilters.Interfaces"), ) /** Find an artifact with the given `name` in `classpath` */ @@ -645,12 +662,18 @@ object Build { val externalDeps = externalCompilerClasspathTask.value val jars = packageAll.value - val scala2LibraryTasty = jars.get("scala2-library-tasty") match { - case Some(scala2LibraryTastyJar) if useScala2LibraryTasty.value => - Seq("-Ddotty.tests.tasties.scalaLibrary=" + scala2LibraryTastyJar) - case _ => - if (useScala2LibraryTasty.value) log.warn("useScala2LibraryTasty is ignored on non-bootstrapped compiler") - Seq.empty + def libraryPathProperty(jarName: String): Seq[String] = + jars.get(jarName) match { + case Some(jar) => + Seq(s"-Ddotty.tests.tasties.scalaLibrary=$jar") + case None => + log.warn("Scala 2 library TASTy is ignored on non-bootstrapped compiler") + Seq.empty + } + val scala2LibraryTasty = scala2Library.value match { + case Scala2LibraryJar => Seq.empty + case Scala2LibraryTasty => libraryPathProperty("scala2-library-tasty") + case Scala2LibraryCCTasty => libraryPathProperty("scala2-library-cc-tasty") } scala2LibraryTasty ++ Seq( @@ -764,14 +787,21 @@ object Build { else if (debugFromTasty) "dotty.tools.dotc.fromtasty.Debug" else "dotty.tools.dotc.Main" - var extraClasspath = - scalaLibTastyOpt match { - case Some(scalaLibTasty) if useScala2LibraryTasty.value => - Seq(scalaLibTasty, scalaLib, dottyLib) - case _ => - if (useScala2LibraryTasty.value) log.warn("useScala2LibraryTasty is ignored on non-bootstrapped compiler") - Seq(scalaLib, dottyLib) - } + var extraClasspath = Seq(scalaLib, dottyLib) + + scala2Library.value match { + case Scala2LibraryJar => + case Scala2LibraryTasty => + jars.get("scala2-library-tasty") match { + case Some(jar) => extraClasspath :+= jar + case None => log.warn("Scala2LibraryTasty is ignored on non-bootstrapped compiler") + }; + case Scala2LibraryCCTasty => + jars.get("scala2-library-cc-tasty") match { + case Some(jar) => extraClasspath :+= jar + case None => log.warn("Scala2LibraryCCTasty is ignored on non-bootstrapped compiler") + } + } if (decompile && !args.contains("-classpath")) extraClasspath ++= Seq(".") @@ -882,6 +912,7 @@ object Build { "scala3-tasty-inspector" -> (LocalProject("scala3-tasty-inspector") / Compile / packageBin).value.getAbsolutePath, "tasty-core" -> (LocalProject("tasty-core-bootstrapped") / Compile / packageBin).value.getAbsolutePath, "scala2-library-tasty" -> (LocalProject("scala2-library-tasty") / Compile / packageBin).value.getAbsolutePath, + "scala2-library-cc-tasty" -> (LocalProject("scala2-library-cc-tasty") / Compile / packageBin).value.getAbsolutePath, ) }, @@ -1010,14 +1041,31 @@ object Build { withCommonSettings(Bootstrapped). dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test"). settings(commonBootstrappedSettings). + settings(scala2LibraryBootstrappedSettings). + settings(moduleName := "scala2-library") + + /** Scala 2 library compiled by dotty using the latest published sources of the library. + * + * This version of the library is not (yet) TASTy/binary compatible with the Scala 2 compiled library. + */ + lazy val `scala2-library-cc` = project.in(file("scala2-library-cc")). + withCommonSettings(Bootstrapped). + dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test"). + settings(commonBootstrappedSettings). + settings(scala2LibraryBootstrappedSettings). settings( - moduleName := "scala2-library", + moduleName := "scala2-library-cc", + scalacOptions += "-Ycheck:all", + ) + + lazy val scala2LibraryBootstrappedSettings = Seq( javaOptions := (`scala3-compiler-bootstrapped` / javaOptions).value, Compile / scalacOptions ++= { Seq("-sourcepath", ((Compile/sourceManaged).value / "scala-library-src").toString) }, Compile / doc / scalacOptions += "-Ydocument-synthetic-types", scalacOptions += "-Ycompile-scala2-library", + scalacOptions += "-Yscala2Unpickler:never", scalacOptions -= "-Xfatal-warnings", Compile / compile / logLevel := Level.Error, ivyConfigurations += SourceDeps.hide, @@ -1069,8 +1117,9 @@ object Build { _.filterNot(file => file.data.getName == s"scala-library-$stdlibBootstrappedVersion.jar") }, mimaCheckDirection := "both", - mimaBackwardIssueFilters := MiMaFilters.StdlibBootstrappedBackwards, - mimaForwardIssueFilters := MiMaFilters.StdlibBootstrappedForward, + mimaBackwardIssueFilters := Scala2LibraryBootstrappedMiMaFilters.BackwardsBreakingChanges, + mimaForwardIssueFilters := Scala2LibraryBootstrappedMiMaFilters.ForwardsBreakingChanges, + customMimaReportBinaryIssues("Scala2LibraryBootstrappedMiMaFilters"), mimaPreviousArtifacts += "org.scala-lang" % "scala-library" % stdlibBootstrappedVersion, mimaExcludeAnnotations ++= Seq( "scala.annotation.experimental", @@ -1096,13 +1145,13 @@ object Build { | - final val MinorVersion = $minorVersion | - final val ExperimentalVersion = 0 | * Clean everything to generate a compiler with those new TASTy versions - | * Run scala2-library-bootstrapped/tastyMiMaReportIssues + | * Run ${name.value}/tastyMiMaReportIssues |""".stripMargin) }).value, Compile / exportJars := true, artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) => - "scala2-library-" + dottyVersion + "." + artifact.extension + moduleName.value + "-" + dottyVersion + "." + artifact.extension }, run := { val log = streams.value.log @@ -1174,7 +1223,7 @@ object Build { |""".stripMargin) } } - ) + ) /** Packages the TASTy files of `scala2-library-bootstrapped` in a jar */ lazy val `scala2-library-tasty` = project.in(file("scala2-library-tasty")). @@ -1187,6 +1236,17 @@ object Build { }, ) + /** Packages the TASTy files of `scala2-library-cc` in a jar */ + lazy val `scala2-library-cc-tasty` = project.in(file("scala2-library-cc-tasty")). + withCommonSettings(Bootstrapped). + settings( + exportJars := true, + Compile / packageBin / mappings := { + (`scala2-library-cc` / Compile / packageBin / mappings).value + .filter(_._2.endsWith(".tasty")) + }, + ) + /** Test the tasty generated by `scala2-library-bootstrapped` * * The sources in src are compiled using TASTy from scala2-library-tasty but then run @@ -1211,13 +1271,6 @@ object Build { Compile / compile / fullClasspath ~= { _.filterNot(file => file.data.getName == s"scala-library-$stdlibBootstrappedVersion.jar") }, - Compile / compile / dependencyClasspath := { - // make sure that the scala2-library (tasty of `scala2-library-tasty`) is listed before the scala-library (classfiles) - val (bootstrappedLib, otherLibs) = - (Compile / compile / dependencyClasspath).value - .partition(_.data.getName == s"scala2-library-${dottyVersion}.jar") - bootstrappedLib ++ otherLibs - }, ) lazy val `scala3-sbt-bridge` = project.in(file("sbt-bridge/src")). @@ -1285,7 +1338,7 @@ object Build { BuildInfoPlugin.buildInfoDefaultSettings lazy val presentationCompilerSettings = { - val mtagsVersion = "1.1.0+79-325e7ef0-SNAPSHOT" + val mtagsVersion = "1.2.0+67-30f8ab53-SNAPSHOT" Seq( resolvers ++= Resolver.sonatypeOssRepos("snapshots"), @@ -1804,7 +1857,7 @@ object Build { .add(ProjectVersion(baseVersion)) .remove[VersionsDictionaryUrl] .add(SourceLinks(List( - s"${temp.getAbsolutePath}=github://lampepfl/dotty/language-reference-stable" + s"${temp.getAbsolutePath}=github://scala/scala3/language-reference-stable" ))) .withTargets(List("___fake___.scala")) } @@ -1864,6 +1917,7 @@ object Build { (`scala3-interfaces` / publishLocalBin), (`scala3-compiler-bootstrapped` / publishLocalBin), (`scala3-library-bootstrapped` / publishLocalBin), + (`scala2-library-tasty` / publishLocal), (`scala3-library-bootstrappedJS` / publishLocalBin), (`tasty-core-bootstrapped` / publishLocalBin), (`scala3-staging` / publishLocalBin), @@ -1971,7 +2025,7 @@ object Build { scmInfo := Some( ScmInfo( url(dottyGithubUrl), - "scm:git:git@github.com:lampepfl/dotty.git" + "scm:git:git@github.com:scala/scala3.git" ) ), developers := List( @@ -2051,6 +2105,15 @@ object Build { packResourceDir += (baseDirectory.value / "bin" -> "bin"), ) + private def customMimaReportBinaryIssues(issueFilterLocation: String) = mimaReportBinaryIssues := { + mimaReportBinaryIssues.result.value match { + case Inc(inc: Incomplete) => + streams.value.log.error(s"\nFilters in $issueFilterLocation are used in this check.\n ") + throw inc + case Value(v) => v + } + } + implicit class ProjectDefinitions(val project: Project) extends AnyVal { // FIXME: we do not aggregate `bin` because its tests delete jars, thus breaking other tests @@ -2061,10 +2124,13 @@ object Build { dependsOn(tastyCore). dependsOn(dottyCompiler). dependsOn(dottyLibrary). + bootstrappedSettings( + addCommandAlias("clean", ";scala3-bootstrapped/clean;scala2-library-bootstrapped/clean;scala2-library-cc/clean"), + ). nonBootstrappedSettings( addCommandAlias("run", "scala3-compiler/run"), // Clean everything by default - addCommandAlias("clean", ";scala3/clean;scala3-bootstrapped/clean"), + addCommandAlias("clean", ";scala3/clean;scala3-bootstrapped/clean;scala2-library-bootstrapped/clean;scala2-library-cc/clean"), // `publishLocal` on the non-bootstrapped compiler does not produce a // working distribution (it can't in general, since there's no guarantee // that the non-bootstrapped library is compatible with the @@ -2104,7 +2170,17 @@ object Build { (Compile/doc/target).value }, commonMiMaSettings, - mimaBinaryIssueFilters ++= MiMaFilters.Library + mimaPreviousArtifacts += { + val thisProjectID = projectID.value + val crossedName = thisProjectID.crossVersion match { + case cv: Disabled => thisProjectID.name + case cv: Binary => s"${thisProjectID.name}_${cv.prefix}3${cv.suffix}" + } + (thisProjectID.organization % crossedName % ltsDottyVersion) + }, + mimaForwardIssueFilters := MiMaFilters.Scala3Library.ForwardsBreakingChanges, + mimaBackwardIssueFilters := MiMaFilters.Scala3Library.BackwardsBreakingChanges, + customMimaReportBinaryIssues("MiMaFilters.Scala3Library"), ) } else base } @@ -2118,7 +2194,9 @@ object Build { versionScheme := Some("semver-spec"), if (mode == Bootstrapped) Def.settings( commonMiMaSettings, - mimaBinaryIssueFilters ++= MiMaFilters.TastyCore, + mimaForwardIssueFilters := MiMaFilters.TastyCore.ForwardsBreakingChanges, + mimaBackwardIssueFilters := MiMaFilters.TastyCore.BackwardsBreakingChanges, + customMimaReportBinaryIssues("MiMaFilters.TastyCore"), ) else { Nil } @@ -2172,7 +2250,7 @@ object ScaladocConfigs { sys.env.get("GITHUB_SHA") match { case Some(sha) => s"${sourcesPrefix}github://${sys.env("GITHUB_REPOSITORY")}/$sha$outputPrefix" - case None => s"${sourcesPrefix}github://lampepfl/dotty/$v$outputPrefix" + case None => s"${sourcesPrefix}github://scala/scala3/$v$outputPrefix" } def defaultSourceLinks(version: String = dottyNonBootstrappedVersion, refVersion: String = dottyVersion) = Def.task { @@ -2183,7 +2261,7 @@ object ScaladocConfigs { scalaSrcLink(stdLibVersion, srcManaged(version, "scala") + "="), dottySrcLink(refVersion, "library/src=", "#library/src"), dottySrcLink(refVersion), - "docs=github://lampepfl/dotty/main#docs" + "docs=github://scala/scala3/main#docs" ) ) } @@ -2191,7 +2269,7 @@ object ScaladocConfigs { lazy val DefaultGenerationSettings = Def.task { def projectVersion = version.value def socialLinks = SocialLinks(List( - "github::https://github.com/lampepfl/dotty", + "github::https://github.com/scala/scala3", "discord::https://discord.com/invite/scala", "twitter::https://twitter.com/scala_lang", )) @@ -2299,7 +2377,10 @@ object ScaladocConfigs { .add(VersionsDictionaryUrl("https://scala-lang.org/api/versions.json")) .add(DocumentSyntheticTypes(true)) .add(SnippetCompiler(List( - s"${dottyLibRoot}/scala=compile", + s"$dottyLibRoot/src/scala=compile", + s"$dottyLibRoot/src/scala/compiletime=compile", + s"$dottyLibRoot/src/scala/util=compile", + s"$dottyLibRoot/src/scala/util/control=compile" ))) .add(SiteRoot("docs")) .add(ApiSubdirectory(true)) @@ -2315,7 +2396,9 @@ object ScaladocConfigs { .add(SnippetCompiler( List( s"$dottyLibrarySrc/scala/quoted=compile", - s"$dottyLibrarySrc/scala/compiletime=compile" + s"$dottyLibrarySrc/scala/compiletime=compile", + s"$dottyLibrarySrc/scala/util=compile", + s"$dottyLibrarySrc/scala/util/control=compile" ) )) .add(CommentSyntax(List( diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a1fe972c4c34..88a97721ee3c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -28,5 +28,5 @@ object Dependencies { "com.vladsch.flexmark" % "flexmark-ext-yaml-front-matter" % flexmarkVersion, ) - val compilerInterface = "org.scala-sbt" % "compiler-interface" % "1.9.3" + val compilerInterface = "org.scala-sbt" % "compiler-interface" % "1.9.6" } diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index 8a1ea7d1141f..7565d23b2c1b 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -2,251 +2,103 @@ import com.typesafe.tools.mima.core._ object MiMaFilters { - val Library: Seq[ProblemFilter] = Seq( - // New API in 3.4.X - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#FlagsModule.AbsOverride"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefTypeTest"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefMethods"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#defnModule.FunctionClass"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#defnModule.PolyFunctionClass"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeReprMethods.dealiasKeepOpaques"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.paramVariance"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeLambdaMethods.paramVariances"), - ) - val TastyCore: Seq[ProblemFilter] = Seq( - ProblemFilters.exclude[DirectMissingMethodProblem]("dotty.tools.tasty.TastyFormat.EXPLICITtpt"), - ) - val Interfaces: Seq[ProblemFilter] = Seq( - ) - val StdlibBootstrappedBackwards: Map[String, Seq[ProblemFilter]] = Map( - Build.stdlibBootstrappedVersion -> { - Seq( - // Files that are not compiled in the bootstrapped library - ProblemFilters.exclude[MissingClassProblem]("scala.AnyVal"), + object Scala3Library { + + val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + // Additions that require a new minor version of the library + Build.previousDottyVersion -> Seq( + ), + + // Additions since last LTS + Build.ltsDottyVersion -> Seq( + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefMethods"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefTypeTest"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#defnModule.FunctionClass"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#defnModule.PolyFunctionClass"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#FlagsModule.AbsOverride"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.paramVariance"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeLambdaMethods.paramVariances"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeReprMethods.dealiasKeepOpaques"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuples.reverse"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.AssignedNonLocally"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.CaptureChecked"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.reachCapability"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.unchecked.uncheckedCaptures"), + ProblemFilters.exclude[MissingClassProblem]("scala.quoted.Quotes$reflectModule$ValOrDefDefMethods"), + ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$3$u002E4$"), + ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$3$u002E4$minusmigration$"), + ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$3$u002E5$"), + ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$3$u002E5$minusmigration$"), + ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$experimental$clauseInterleaving$"), + ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$experimental$relaxedExtensionImports$"), + ProblemFilters.exclude[MissingClassProblem]("scala.scalajs.runtime.AnonFunctionXXL"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language.3.4-migration"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language.3.4"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language.3.5-migration"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language.3.5"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language#experimental.clauseInterleaving"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language#experimental.relaxedExtensionImports"), + ), + ) + + val BackwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + // In general we should never have backwards incompatible changes in the library. + // Only exceptional cases should be added here. + + // Breaking changes since last reference version + Build.previousDottyVersion -> Seq.empty, // We should never break backwards compatibility + + // Breaking changes since last LTS + Build.ltsDottyVersion -> Seq( + // Quotes is assumed to only be implemented by the compiler and on the same version of the library. + // It is exceptionally OK to break this compatibility. In these cases, there add new abstract methods that would + // potentially not be implemented by others. If some other library decides to implement these, + // they need to recompile and republish on each minor release. + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefMethods"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefTypeTest"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#defnModule.FunctionClass"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#defnModule.PolyFunctionClass"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#FlagsModule.AbsOverride"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.paramVariance"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeLambdaMethods.paramVariances"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeReprMethods.dealiasKeepOpaques"), + ), + ) + } + + object TastyCore { + val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + // Additions that require a new minor version of tasty core + Build.previousDottyVersion -> Seq( + ), + + // Additions since last LTS + Build.ltsDottyVersion -> Seq( + ) + ) + + val BackwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + // Breaking changes since last LTS + Build.ltsDottyVersion -> Seq.empty // We should never break backwards compatibility + ) + } + + object Interfaces { + val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + // Additions that require a new minor version of interfaces + Build.previousDottyVersion -> Seq( + ), + + // Additions since last LTS + Build.ltsDottyVersion -> Seq( + ) + ) + + val BackwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + // Breaking changes since last LTS + Build.ltsDottyVersion -> Seq.empty // We should never break backwards compatibility + ) + } - // Scala language features - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language.<clinit>"), - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language#experimental.<clinit>"), - ProblemFilters.exclude[FinalClassProblem]("scala.language$experimental$"), - ProblemFilters.exclude[FinalClassProblem]("scala.languageFeature$*$"), - - // trait $init$ - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*.$init$"), - - // Value class extension methods - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$extension"), - - // Companion module class - ProblemFilters.exclude[FinalClassProblem]("scala.*$"), - - // Scala 2 intrinsic macros - ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"), - - // Specialization? - ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple1._1"), // field _1 in class scala.Tuple1 does not have a correspondent in current version - ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._1"), // field _1 in class scala.Tuple2 does not have a correspondent in current version - ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._2"), // field _2 in class scala.Tuple2 does not have a correspondent in current version - - // Scala 2 specialization - ProblemFilters.exclude[MissingClassProblem]("scala.*$sp"), - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$sp"), - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*#*#sp.$init$"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.DoubleStepper"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.DoubleVectorStepper"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.IntVectorStepper"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.LongVectorStepper"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.IntStepper"), - ProblemFilters.exclude[MissingTypesProblem]("scala.collection.LongStepper"), - ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.DoubleAccumulator"), - ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.FunctionWrappers$*"), - ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.IntAccumulator"), - ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.LongAccumulator"), - ProblemFilters.exclude[FinalClassProblem]("scala.collection.ArrayOps$ReverseIterator"), - ProblemFilters.exclude[FinalClassProblem]("scala.Tuple1"), - ProblemFilters.exclude[FinalClassProblem]("scala.Tuple2"), - - // other - ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueOrdering"), - ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueSet"), - ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.NoPositioner"), - ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPosition"), - ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPositioner"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.SortedMapOps.coll"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.empty"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.fromSpecific"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.ArrayBuilder#ofUnit.addAll"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.empty"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.fromSpecific"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NothingManifest.newArray"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NullManifest.newArray"), - ProblemFilters.exclude[MissingFieldProblem]("scala.collection.ArrayOps#ReverseIterator.xs"), - ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.NonLocalReturnControl.value"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.immutable.SortedMapOps.coll"), - ) ++ - Seq( // DirectMissingMethodProblem - "scala.collection.LinearSeqIterator#LazyCell.this", - "scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this", - "scala.concurrent.BatchingExecutor#AbstractBatch.this", - "scala.concurrent.Channel#LinkedList.this", - "scala.Enumeration#ValueOrdering.this", - "scala.io.Source#RelaxedPosition.this", - "scala.collection.IterableOnceOps#Maximized.this", // New in 2.13.11: private inner class - "scala.util.Properties.<clinit>", - "scala.util.Sorting.scala$util$Sorting$$mergeSort$default$5", - // New in 2.13.12 -- can be removed once scala/scala#10549 lands in 2.13.13 - // and we take the upgrade here - "scala.collection.immutable.MapNodeRemoveAllSetNodeIterator.next", - ).map(ProblemFilters.exclude[DirectMissingMethodProblem]) - } - ) - - val StdlibBootstrappedForward: Map[String, Seq[ProblemFilter]] = Map( - Build.stdlibBootstrappedVersion -> { - Seq( - // Scala language features - ProblemFilters.exclude[FinalClassProblem]("scala.languageFeature$*$"), - ProblemFilters.exclude[MissingFieldProblem]("scala.language.experimental"), - ProblemFilters.exclude[MissingFieldProblem]("scala.languageFeature*"), - - // https://github.com/scala/scala/blob/v2.13.10/src/library/scala/collection/immutable/Range.scala#LL155C1-L156C1 - // Issue #17519: we do not set final on the default methods of final copy method. - ProblemFilters.exclude[FinalMethodProblem]("scala.collection.immutable.Range.copy$default$*"), - - // Value class extension methods - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$extension"), - - // Companion module class: Missing type java.io.Serializable - ProblemFilters.exclude[MissingTypesProblem]("scala.*$"), - - // Non-categorized - ProblemFilters.exclude[IncompatibleMethTypeProblem]("scala.collection.mutable.ArrayBuilder#ofUnit.addAll"), - - // Non-categorized - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.SortedMapOps.coll"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NothingManifest.newArray"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NullManifest.newArray"), - - // the type hierarchy of class scala.Array is different in other version. Missing types {java.io.Serializable,java.lang.Cloneable} - ProblemFilters.exclude[MissingTypesProblem]("scala.Array"), - - // abstract method coll()scala.collection.immutable.SortedMapOps in interface scala.collection.immutable.SortedMapOps is present only in other version - ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.immutable.SortedMapOps.coll"), - ) ++ - Seq( // DirectMissingMethodProblem - "scala.<:<.antisymm", "scala.<:<.refl", - "scala.collection.BitSet.ordMsg", "scala.collection.BitSet.zipOrdMsg", - "scala.collection.BitSetOps.computeWordForFilter", "scala.collection.BitSetOps.LogWL", "scala.collection.BitSetOps.MaxSize", "scala.collection.BitSetOps.updateArray", "scala.collection.BitSetOps.WordLength", - "scala.collection.convert.StreamExtensions#AccumulatorFactoryInfo.*AccumulatorFactoryInfo", "scala.collection.convert.StreamExtensions#StreamShape.*StreamShape", "scala.collection.convert.StreamExtensions#StreamUnboxer.*StreamUnboxer", - "scala.collection.immutable.List.partialNotApplied", - "scala.collection.immutable.ListSet.emptyInstance", - "scala.collection.immutable.Nil.andThen", "scala.collection.immutable.Nil.collectionClassName", "scala.collection.immutable.Nil.empty", "scala.collection.immutable.Nil.view", - "scala.collection.immutable.NumericRange.defaultOrdering", - "scala.collection.immutable.Set.emptyInstance", - "scala.collection.immutable.Stream.collectedTail", "scala.collection.immutable.Stream.filteredTail", - "scala.collection.immutable.TreeSeqMap#Ordering#Bin.apply", "scala.collection.immutable.TreeSeqMap#Ordering#Bin.unapply", "scala.collection.immutable.TreeSeqMap#Ordering#Iterator.empty", "scala.collection.immutable.TreeSeqMap#Ordering#Iterator.Empty", "scala.collection.immutable.TreeSeqMap#Ordering#Tip.apply", "scala.collection.immutable.TreeSeqMap#Ordering#Tip.unapply", - "scala.collection.immutable.Vector.fillSparse", - "scala.collection.IterableOnce.checkArraySizeWithinVMLimit", - "scala.collection.IterableOnce.copyElemsToArray", "scala.collection.IterableOnce.copyElemsToArray$default$3", "scala.collection.IterableOnce.copyElemsToArray$default$4", - "scala.collection.IterableOnce.elemsToCopyToArray", - "scala.collection.LinearSeqIterator#LazyCell.this", - "scala.collection.mutable.ArrayDeque.alloc", "scala.collection.mutable.ArrayDeque.end_=", "scala.collection.mutable.ArrayDeque.end", "scala.collection.mutable.ArrayDeque.StableSize", "scala.collection.mutable.ArrayDeque.start_=", "scala.collection.mutable.ArrayDeque.start", - "scala.collection.mutable.CollisionProofHashMap.ordMsg", - "scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this", - "scala.collection.mutable.RedBlackTree#Node.apply", "scala.collection.mutable.RedBlackTree#Node.leaf", "scala.collection.mutable.RedBlackTree#Node.unapply", "scala.collection.mutable.RedBlackTree#Tree.empty", - "scala.collection.mutable.UnrolledBuffer.unrolledlength", "scala.collection.mutable.UnrolledBuffer#Unrolled.<init>$default$4", - "scala.collection.Searching#Found.apply", "scala.collection.Searching#Found.unapply", - "scala.collection.Searching#Found.andThen", "scala.collection.Searching#Found.compose", - "scala.collection.Searching#InsertionPoint.andThen", "scala.collection.Searching#InsertionPoint.compose", - "scala.collection.Searching#InsertionPoint.apply", "scala.collection.Searching#InsertionPoint.unapply", - "scala.collection.SortedMapFactoryDefaults.empty", "scala.collection.SortedMapFactoryDefaults.fromSpecific", - "scala.collection.SortedMapOps.ordMsg", "scala.collection.SortedSetOps.ordMsg", - "scala.collection.SortedSetOps.zipOrdMsg", - "scala.collection.Stepper.throwNSEE", - "scala.collection.View.dropRightIterator", "scala.collection.View.takeRightIterator", - "scala.collection.View#Filter.apply", - "scala.concurrent.BatchingExecutor#AbstractBatch.this", - "scala.concurrent.Channel#LinkedList.this", - "scala.concurrent.ExecutionContext.opportunistic", - "scala.concurrent.Future.addToBuilderFun", "scala.concurrent.Future.collectFailed", "scala.concurrent.Future.failedFailureFuture", "scala.concurrent.Future.failedFun", "scala.concurrent.Future.filterFailure", "scala.concurrent.Future.id", "scala.concurrent.Future.recoverWithFailed", "scala.concurrent.Future.recoverWithFailedMarker", "scala.concurrent.Future.toBoxed", "scala.concurrent.Future.zipWithTuple2Fun", - "scala.Enumeration#ValueOrdering.this", - "scala.io.Source#RelaxedPosition.this", - "scala.jdk.Accumulator#AccumulatorFactoryShape.anyAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.doubleAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.intAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.jDoubleAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.jIntegerAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.jLongAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.longAccumulatorFactoryShape", - "scala.jdk.FunctionWrappers#*", - "scala.PartialFunction.unlifted", - "scala.sys.process.BasicIO.connectNoOp", "scala.sys.process.BasicIO.connectToStdIn", - "scala.sys.process.Process.Future", - "scala.sys.process.Process.Spawn", - "scala.util.control.Exception#Catch.<init>$default$2", "scala.util.control.Exception#Catch.<init>$default$3", - "scala.util.control.TailCalls#Call.apply", "scala.util.control.TailCalls#Call.unapply", "scala.util.control.TailCalls#Cont.apply", "scala.util.control.TailCalls#Cont.unapply", "scala.util.control.TailCalls#Done.apply", "scala.util.control.TailCalls#Done.unapply", - "scala.util.Either#LeftProjection.apply", "scala.util.Either#LeftProjection.unapply", "scala.util.Either#RightProjection.apply", "scala.util.Either#RightProjection.unapply", - "scala.util.matching.Regex#Match.unapply", - "scala.util.Properties.coloredOutputEnabled", - "scala.util.Properties.isAvian", - "scala.util.Properties.versionFor", - // New problem in 2.13.11 - "scala.collection.IterableOnceOps#Maximized.this", // private inner class - "scala.collection.mutable.LinkedHashMap.defaultLoadFactor", // private[collection] final def - "scala.collection.mutable.LinkedHashMap.defaultinitialSize", // private[collection] final def - "scala.collection.mutable.LinkedHashSet.defaultLoadFactor", // private[collection] final def - "scala.collection.mutable.LinkedHashSet.defaultinitialSize", // private[collection] final def - "scala.collection.mutable.OpenHashMap.nextPositivePowerOfTwo", // private[mutable] def - ).map(ProblemFilters.exclude[DirectMissingMethodProblem]) ++ - Seq( // MissingFieldProblem: static field ... in object ... does not have a correspondent in other version - "scala.Array.UnapplySeqWrapper", - "scala.collection.concurrent.TrieMap.RemovalPolicy", - "scala.collection.convert.StreamExtensions.AccumulatorFactoryInfo", "scala.collection.convert.StreamExtensions.StreamShape", "scala.collection.convert.StreamExtensions.StreamUnboxer", - "scala.collection.immutable.IntMap.Bin", "scala.collection.immutable.IntMap.Nil", "scala.collection.immutable.IntMap.Tip", - "scala.collection.immutable.LazyList.#::", "scala.collection.immutable.LazyList.cons", "scala.collection.immutable.LazyList.Deferrer", "scala.collection.immutable.LazyList#State.Empty", - "scala.collection.immutable.LongMap.Bin", "scala.collection.immutable.LongMap.Nil", "scala.collection.immutable.LongMap.Tip", - "scala.collection.immutable.Range.BigDecimal", "scala.collection.immutable.Range.BigInt", "scala.collection.immutable.Range.Int", "scala.collection.immutable.Range.Long", "scala.collection.immutable.Range.Partial", - "scala.collection.immutable.Stream.#::", "scala.collection.immutable.Stream.cons", "scala.collection.immutable.Stream.Deferrer", "scala.collection.immutable.Stream.Empty", - "scala.collection.immutable.TreeSeqMap.OrderBy", "scala.collection.immutable.TreeSeqMap.Ordering", "scala.collection.immutable.TreeSeqMap#OrderBy.Insertion", "scala.collection.immutable.TreeSeqMap#OrderBy.Modification", - "scala.collection.immutable.VectorMap.Tombstone", - "scala.collection.immutable.WrappedString.UnwrapOp", - "scala.collection.IterableOps.SizeCompareOps", - "scala.collection.mutable.UnrolledBuffer.Unrolled", - "scala.collection.package.:+", "scala.collection.package.+:", - "scala.collection.Searching.Found", "scala.collection.Searching.InsertionPoint", "scala.collection.Searching.SearchImpl", - "scala.collection.SeqFactory.UnapplySeqWrapper", - "scala.collection.StepperShape.Shape", - "scala.collection.View.Empty", "scala.collection.View.Filter", - "scala.concurrent.duration.Deadline.DeadlineIsOrdered", "scala.concurrent.duration.Duration.DurationIsOrdered", - "scala.concurrent.duration.DurationConversions.fromNowConvert", "scala.concurrent.duration.DurationConversions.spanConvert", - "scala.concurrent.duration.FiniteDuration.FiniteDurationIsOrdered", - "scala.concurrent.duration.package.DoubleMult", "scala.concurrent.duration.package.DurationDouble", "scala.concurrent.duration.package.DurationInt", "scala.concurrent.duration.package.DurationLong", "scala.concurrent.duration.package.fromNow", "scala.concurrent.duration.package.IntMult", "scala.concurrent.duration.package.LongMult", "scala.concurrent.duration.package.span", - "scala.concurrent.ExecutionContext.Implicits", "scala.concurrent.ExecutionContext.parasitic", - "scala.concurrent.Future.never", - "scala.Function1.UnliftOps", - "scala.jdk.Accumulator.AccumulatorFactoryShape", - "scala.jdk.DurationConverters.JavaDurationOps", "scala.jdk.DurationConverters.ScalaDurationOps", - "scala.jdk.FunctionWrappers.*", - "scala.jdk.FutureConverters.CompletionStageOps", "scala.jdk.FutureConverters.FutureOps", - "scala.jdk.OptionConverters.RichOption", "scala.jdk.OptionConverters.RichOptional", "scala.jdk.OptionConverters.RichOptionalDouble", "scala.jdk.OptionConverters.RichOptionalInt", "scala.jdk.OptionConverters.RichOptionalLong", - "scala.math.BigDecimal.RoundingMode", - "scala.math.Equiv.BigDecimal", "scala.math.Equiv.BigInt", "scala.math.Equiv.Boolean", "scala.math.Equiv.Byte", "scala.math.Equiv.Char", "scala.math.Equiv.DeprecatedDoubleEquiv", "scala.math.Equiv.DeprecatedFloatEquiv", "scala.math.Equiv.Double", "scala.math.Equiv.Float", "scala.math.Equiv.Implicits", "scala.math.Equiv.Int", "scala.math.Equiv.Long", "scala.math.Equiv.Short", "scala.math.Equiv.String", "scala.math.Equiv.Symbol", "scala.math.Equiv.Unit", - "scala.math.Equiv#Double.IeeeEquiv", "scala.math.Equiv#Double.StrictEquiv", "scala.math.Equiv#Float.IeeeEquiv", "scala.math.Equiv#Float.StrictEquiv", - "scala.math.Fractional.Implicits", - "scala.math.Integral.Implicits", - "scala.math.Numeric.BigDecimalAsIfIntegral", "scala.math.Numeric.BigDecimalIsFractional", "scala.math.Numeric.BigIntIsIntegral", "scala.math.Numeric.ByteIsIntegral", "scala.math.Numeric.CharIsIntegral", "scala.math.Numeric.DoubleIsFractional", "scala.math.Numeric.FloatIsFractional", "scala.math.Numeric.Implicits", "scala.math.Numeric.IntIsIntegral", "scala.math.Numeric.LongIsIntegral", "scala.math.Numeric.ShortIsIntegral", - "scala.math.Ordering.BigDecimal", - "scala.math.Ordering.BigInt", "scala.math.Ordering.Boolean", "scala.math.Ordering.Byte", "scala.math.Ordering.Char", "scala.math.Ordering.DeprecatedDoubleOrdering", "scala.math.Ordering.DeprecatedFloatOrdering", "scala.math.Ordering.Double", "scala.math.Ordering.Float", "scala.math.Ordering.Implicits", "scala.math.Ordering.Int", "scala.math.Ordering.Long", "scala.math.Ordering.Short", "scala.math.Ordering.String", "scala.math.Ordering.Symbol", "scala.math.Ordering.Unit", - "scala.math.Ordering#Double.IeeeOrdering", "scala.math.Ordering#Double.TotalOrdering", - "scala.math.Ordering#Float.IeeeOrdering", "scala.math.Ordering#Float.TotalOrdering", - "scala.package.#::", - "scala.PartialFunction.ElementWiseExtractor", - "scala.Predef.any2stringadd", - "scala.Predef.ArrowAssoc", "scala.Predef.Ensuring", "scala.Predef.StringFormat", - "scala.runtime.Tuple2Zipped.Ops", "scala.runtime.Tuple3Zipped.Ops", - "scala.sys.process.BasicIO.LazilyListed", "scala.sys.process.BasicIO.Streamed", "scala.sys.process.BasicIO.Uncloseable", - "scala.sys.Prop.DoubleProp", "scala.sys.Prop.FileProp", "scala.sys.Prop.IntProp", "scala.sys.Prop.StringProp", - "scala.util.control.Exception.Catch", - "scala.util.control.TailCalls.Call", "scala.util.control.TailCalls.Cont", "scala.util.control.TailCalls.Done", - "scala.util.Either.LeftProjection", "scala.util.Either.MergeableEither", "scala.util.Either.RightProjection", - "scala.util.matching.Regex.Groups", "scala.util.matching.Regex.Match", - "scala.util.package.chaining", - "scala.util.Using.Manager", "scala.util.Using.Releasable", "scala.util.Using#Releasable.AutoCloseableIsReleasable", - ).map(ProblemFilters.exclude[MissingFieldProblem]) - } - ) } diff --git a/project/Scala2LibraryBootstrappedMiMaFilters.scala b/project/Scala2LibraryBootstrappedMiMaFilters.scala new file mode 100644 index 000000000000..bd149d5a910b --- /dev/null +++ b/project/Scala2LibraryBootstrappedMiMaFilters.scala @@ -0,0 +1,236 @@ + +import com.typesafe.tools.mima.core._ + +object Scala2LibraryBootstrappedMiMaFilters { + + val BackwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + Build.stdlibBootstrappedVersion -> { + Seq( + // Files that are not compiled in the bootstrapped library + ProblemFilters.exclude[MissingClassProblem]("scala.AnyVal"), + + // Scala language features + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language.<clinit>"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language#experimental.<clinit>"), + ProblemFilters.exclude[FinalClassProblem]("scala.language$experimental$"), + ProblemFilters.exclude[FinalClassProblem]("scala.languageFeature$*$"), + + // trait $init$ + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*.$init$"), + + // Value class extension methods + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$extension"), + + // Companion module class + ProblemFilters.exclude[FinalClassProblem]("scala.*$"), + + // Scala 2 intrinsic macros + ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"), + + // Specialization? + ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple1._1"), // field _1 in class scala.Tuple1 does not have a correspondent in current version + ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._1"), // field _1 in class scala.Tuple2 does not have a correspondent in current version + ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._2"), // field _2 in class scala.Tuple2 does not have a correspondent in current version + + // Scala 2 specialization + ProblemFilters.exclude[MissingClassProblem]("scala.*$sp"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$sp"), + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*#*#sp.$init$"), + ProblemFilters.exclude[MissingTypesProblem]("scala.collection.DoubleStepper"), + ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.DoubleVectorStepper"), + ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.IntVectorStepper"), + ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.LongVectorStepper"), + ProblemFilters.exclude[MissingTypesProblem]("scala.collection.IntStepper"), + ProblemFilters.exclude[MissingTypesProblem]("scala.collection.LongStepper"), + ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.DoubleAccumulator"), + ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.FunctionWrappers$*"), + ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.IntAccumulator"), + ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.LongAccumulator"), + ProblemFilters.exclude[FinalClassProblem]("scala.collection.ArrayOps$ReverseIterator"), + ProblemFilters.exclude[FinalClassProblem]("scala.Tuple1"), + ProblemFilters.exclude[FinalClassProblem]("scala.Tuple2"), + + // other + ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueOrdering"), + ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueSet"), + ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.NoPositioner"), + ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPosition"), + ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPositioner"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.SortedMapOps.coll"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.empty"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.fromSpecific"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.ArrayBuilder#ofUnit.addAll"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.empty"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.fromSpecific"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NothingManifest.newArray"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NullManifest.newArray"), + ProblemFilters.exclude[MissingFieldProblem]("scala.collection.ArrayOps#ReverseIterator.xs"), + ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.NonLocalReturnControl.value"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.immutable.SortedMapOps.coll"), + ) ++ + Seq( // DirectMissingMethodProblem + "scala.collection.LinearSeqIterator#LazyCell.this", + "scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this", + "scala.concurrent.BatchingExecutor#AbstractBatch.this", + "scala.concurrent.Channel#LinkedList.this", + "scala.Enumeration#ValueOrdering.this", + "scala.io.Source#RelaxedPosition.this", + "scala.collection.IterableOnceOps#Maximized.this", // New in 2.13.11: private inner class + "scala.util.Properties.<clinit>", + "scala.util.Sorting.scala$util$Sorting$$mergeSort$default$5", + // New in 2.13.12 -- can be removed once scala/scala#10549 lands in 2.13.13 + // and we take the upgrade here + "scala.collection.immutable.MapNodeRemoveAllSetNodeIterator.next", + ).map(ProblemFilters.exclude[DirectMissingMethodProblem]) + } + ) + + val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map( + Build.stdlibBootstrappedVersion -> { + Seq( + // Scala language features + ProblemFilters.exclude[FinalClassProblem]("scala.languageFeature$*$"), + ProblemFilters.exclude[MissingFieldProblem]("scala.language.experimental"), + ProblemFilters.exclude[MissingFieldProblem]("scala.languageFeature*"), + + // https://github.com/scala/scala/blob/v2.13.10/src/library/scala/collection/immutable/Range.scala#LL155C1-L156C1 + // Issue #17519: we do not set final on the default methods of final copy method. + ProblemFilters.exclude[FinalMethodProblem]("scala.collection.immutable.Range.copy$default$*"), + + // Value class extension methods + ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$extension"), + + // Companion module class: Missing type java.io.Serializable + ProblemFilters.exclude[MissingTypesProblem]("scala.*$"), + + // Non-categorized + ProblemFilters.exclude[IncompatibleMethTypeProblem]("scala.collection.mutable.ArrayBuilder#ofUnit.addAll"), + + // Non-categorized + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.SortedMapOps.coll"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NothingManifest.newArray"), + ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NullManifest.newArray"), + + // the type hierarchy of class scala.Array is different in other version. Missing types {java.io.Serializable,java.lang.Cloneable} + ProblemFilters.exclude[MissingTypesProblem]("scala.Array"), + + // abstract method coll()scala.collection.immutable.SortedMapOps in interface scala.collection.immutable.SortedMapOps is present only in other version + ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.immutable.SortedMapOps.coll"), + ) ++ + Seq( // DirectMissingMethodProblem + "scala.<:<.antisymm", "scala.<:<.refl", + "scala.collection.BitSet.ordMsg", "scala.collection.BitSet.zipOrdMsg", + "scala.collection.BitSetOps.computeWordForFilter", "scala.collection.BitSetOps.LogWL", "scala.collection.BitSetOps.MaxSize", "scala.collection.BitSetOps.updateArray", "scala.collection.BitSetOps.WordLength", + "scala.collection.convert.StreamExtensions#AccumulatorFactoryInfo.*AccumulatorFactoryInfo", "scala.collection.convert.StreamExtensions#StreamShape.*StreamShape", "scala.collection.convert.StreamExtensions#StreamUnboxer.*StreamUnboxer", + "scala.collection.immutable.List.partialNotApplied", + "scala.collection.immutable.ListSet.emptyInstance", + "scala.collection.immutable.Nil.andThen", "scala.collection.immutable.Nil.collectionClassName", "scala.collection.immutable.Nil.empty", "scala.collection.immutable.Nil.view", + "scala.collection.immutable.NumericRange.defaultOrdering", + "scala.collection.immutable.Set.emptyInstance", + "scala.collection.immutable.Stream.collectedTail", "scala.collection.immutable.Stream.filteredTail", + "scala.collection.immutable.TreeSeqMap#Ordering#Bin.apply", "scala.collection.immutable.TreeSeqMap#Ordering#Bin.unapply", "scala.collection.immutable.TreeSeqMap#Ordering#Iterator.empty", "scala.collection.immutable.TreeSeqMap#Ordering#Iterator.Empty", "scala.collection.immutable.TreeSeqMap#Ordering#Tip.apply", "scala.collection.immutable.TreeSeqMap#Ordering#Tip.unapply", + "scala.collection.immutable.Vector.fillSparse", + "scala.collection.IterableOnce.checkArraySizeWithinVMLimit", + "scala.collection.IterableOnce.copyElemsToArray", "scala.collection.IterableOnce.copyElemsToArray$default$3", "scala.collection.IterableOnce.copyElemsToArray$default$4", + "scala.collection.IterableOnce.elemsToCopyToArray", + "scala.collection.LinearSeqIterator#LazyCell.this", + "scala.collection.mutable.ArrayDeque.alloc", "scala.collection.mutable.ArrayDeque.end_=", "scala.collection.mutable.ArrayDeque.end", "scala.collection.mutable.ArrayDeque.StableSize", "scala.collection.mutable.ArrayDeque.start_=", "scala.collection.mutable.ArrayDeque.start", + "scala.collection.mutable.CollisionProofHashMap.ordMsg", + "scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this", + "scala.collection.mutable.RedBlackTree#Node.apply", "scala.collection.mutable.RedBlackTree#Node.leaf", "scala.collection.mutable.RedBlackTree#Node.unapply", "scala.collection.mutable.RedBlackTree#Tree.empty", + "scala.collection.mutable.UnrolledBuffer.unrolledlength", "scala.collection.mutable.UnrolledBuffer#Unrolled.<init>$default$4", + "scala.collection.Searching#Found.apply", "scala.collection.Searching#Found.unapply", + "scala.collection.Searching#Found.andThen", "scala.collection.Searching#Found.compose", + "scala.collection.Searching#InsertionPoint.andThen", "scala.collection.Searching#InsertionPoint.compose", + "scala.collection.Searching#InsertionPoint.apply", "scala.collection.Searching#InsertionPoint.unapply", + "scala.collection.SortedMapFactoryDefaults.empty", "scala.collection.SortedMapFactoryDefaults.fromSpecific", + "scala.collection.SortedMapOps.ordMsg", "scala.collection.SortedSetOps.ordMsg", + "scala.collection.SortedSetOps.zipOrdMsg", + "scala.collection.Stepper.throwNSEE", + "scala.collection.View.dropRightIterator", "scala.collection.View.takeRightIterator", + "scala.collection.View#Filter.apply", + "scala.concurrent.BatchingExecutor#AbstractBatch.this", + "scala.concurrent.Channel#LinkedList.this", + "scala.concurrent.ExecutionContext.opportunistic", + "scala.concurrent.Future.addToBuilderFun", "scala.concurrent.Future.collectFailed", "scala.concurrent.Future.failedFailureFuture", "scala.concurrent.Future.failedFun", "scala.concurrent.Future.filterFailure", "scala.concurrent.Future.id", "scala.concurrent.Future.recoverWithFailed", "scala.concurrent.Future.recoverWithFailedMarker", "scala.concurrent.Future.toBoxed", "scala.concurrent.Future.zipWithTuple2Fun", + "scala.Enumeration#ValueOrdering.this", + "scala.io.Source#RelaxedPosition.this", + "scala.jdk.Accumulator#AccumulatorFactoryShape.anyAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.doubleAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.intAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.jDoubleAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.jIntegerAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.jLongAccumulatorFactoryShape", "scala.jdk.Accumulator#AccumulatorFactoryShape.longAccumulatorFactoryShape", + "scala.jdk.FunctionWrappers#*", + "scala.PartialFunction.unlifted", + "scala.sys.process.BasicIO.connectNoOp", "scala.sys.process.BasicIO.connectToStdIn", + "scala.sys.process.Process.Future", + "scala.sys.process.Process.Spawn", + "scala.util.control.Exception#Catch.<init>$default$2", "scala.util.control.Exception#Catch.<init>$default$3", + "scala.util.control.TailCalls#Call.apply", "scala.util.control.TailCalls#Call.unapply", "scala.util.control.TailCalls#Cont.apply", "scala.util.control.TailCalls#Cont.unapply", "scala.util.control.TailCalls#Done.apply", "scala.util.control.TailCalls#Done.unapply", + "scala.util.Either#LeftProjection.apply", "scala.util.Either#LeftProjection.unapply", "scala.util.Either#RightProjection.apply", "scala.util.Either#RightProjection.unapply", + "scala.util.matching.Regex#Match.unapply", + "scala.util.Properties.coloredOutputEnabled", + "scala.util.Properties.isAvian", + "scala.util.Properties.versionFor", + // New problem in 2.13.11 + "scala.collection.IterableOnceOps#Maximized.this", // private inner class + "scala.collection.mutable.LinkedHashMap.defaultLoadFactor", // private[collection] final def + "scala.collection.mutable.LinkedHashMap.defaultinitialSize", // private[collection] final def + "scala.collection.mutable.LinkedHashSet.defaultLoadFactor", // private[collection] final def + "scala.collection.mutable.LinkedHashSet.defaultinitialSize", // private[collection] final def + "scala.collection.mutable.OpenHashMap.nextPositivePowerOfTwo", // private[mutable] def + ).map(ProblemFilters.exclude[DirectMissingMethodProblem]) ++ + Seq( // MissingFieldProblem: static field ... in object ... does not have a correspondent in other version + "scala.Array.UnapplySeqWrapper", + "scala.collection.concurrent.TrieMap.RemovalPolicy", + "scala.collection.convert.StreamExtensions.AccumulatorFactoryInfo", "scala.collection.convert.StreamExtensions.StreamShape", "scala.collection.convert.StreamExtensions.StreamUnboxer", + "scala.collection.immutable.IntMap.Bin", "scala.collection.immutable.IntMap.Nil", "scala.collection.immutable.IntMap.Tip", + "scala.collection.immutable.LazyList.#::", "scala.collection.immutable.LazyList.cons", "scala.collection.immutable.LazyList.Deferrer", "scala.collection.immutable.LazyList#State.Empty", + "scala.collection.immutable.LongMap.Bin", "scala.collection.immutable.LongMap.Nil", "scala.collection.immutable.LongMap.Tip", + "scala.collection.immutable.Range.BigDecimal", "scala.collection.immutable.Range.BigInt", "scala.collection.immutable.Range.Int", "scala.collection.immutable.Range.Long", "scala.collection.immutable.Range.Partial", + "scala.collection.immutable.Stream.#::", "scala.collection.immutable.Stream.cons", "scala.collection.immutable.Stream.Deferrer", "scala.collection.immutable.Stream.Empty", + "scala.collection.immutable.TreeSeqMap.OrderBy", "scala.collection.immutable.TreeSeqMap.Ordering", "scala.collection.immutable.TreeSeqMap#OrderBy.Insertion", "scala.collection.immutable.TreeSeqMap#OrderBy.Modification", + "scala.collection.immutable.VectorMap.Tombstone", + "scala.collection.immutable.WrappedString.UnwrapOp", + "scala.collection.IterableOps.SizeCompareOps", + "scala.collection.mutable.UnrolledBuffer.Unrolled", + "scala.collection.package.:+", "scala.collection.package.+:", + "scala.collection.Searching.Found", "scala.collection.Searching.InsertionPoint", "scala.collection.Searching.SearchImpl", + "scala.collection.SeqFactory.UnapplySeqWrapper", + "scala.collection.StepperShape.Shape", + "scala.collection.View.Empty", "scala.collection.View.Filter", + "scala.concurrent.duration.Deadline.DeadlineIsOrdered", "scala.concurrent.duration.Duration.DurationIsOrdered", + "scala.concurrent.duration.DurationConversions.fromNowConvert", "scala.concurrent.duration.DurationConversions.spanConvert", + "scala.concurrent.duration.FiniteDuration.FiniteDurationIsOrdered", + "scala.concurrent.duration.package.DoubleMult", "scala.concurrent.duration.package.DurationDouble", "scala.concurrent.duration.package.DurationInt", "scala.concurrent.duration.package.DurationLong", "scala.concurrent.duration.package.fromNow", "scala.concurrent.duration.package.IntMult", "scala.concurrent.duration.package.LongMult", "scala.concurrent.duration.package.span", + "scala.concurrent.ExecutionContext.Implicits", "scala.concurrent.ExecutionContext.parasitic", + "scala.concurrent.Future.never", + "scala.Function1.UnliftOps", + "scala.jdk.Accumulator.AccumulatorFactoryShape", + "scala.jdk.DurationConverters.JavaDurationOps", "scala.jdk.DurationConverters.ScalaDurationOps", + "scala.jdk.FunctionWrappers.*", + "scala.jdk.FutureConverters.CompletionStageOps", "scala.jdk.FutureConverters.FutureOps", + "scala.jdk.OptionConverters.RichOption", "scala.jdk.OptionConverters.RichOptional", "scala.jdk.OptionConverters.RichOptionalDouble", "scala.jdk.OptionConverters.RichOptionalInt", "scala.jdk.OptionConverters.RichOptionalLong", + "scala.math.BigDecimal.RoundingMode", + "scala.math.Equiv.BigDecimal", "scala.math.Equiv.BigInt", "scala.math.Equiv.Boolean", "scala.math.Equiv.Byte", "scala.math.Equiv.Char", "scala.math.Equiv.DeprecatedDoubleEquiv", "scala.math.Equiv.DeprecatedFloatEquiv", "scala.math.Equiv.Double", "scala.math.Equiv.Float", "scala.math.Equiv.Implicits", "scala.math.Equiv.Int", "scala.math.Equiv.Long", "scala.math.Equiv.Short", "scala.math.Equiv.String", "scala.math.Equiv.Symbol", "scala.math.Equiv.Unit", + "scala.math.Equiv#Double.IeeeEquiv", "scala.math.Equiv#Double.StrictEquiv", "scala.math.Equiv#Float.IeeeEquiv", "scala.math.Equiv#Float.StrictEquiv", + "scala.math.Fractional.Implicits", + "scala.math.Integral.Implicits", + "scala.math.Numeric.BigDecimalAsIfIntegral", "scala.math.Numeric.BigDecimalIsFractional", "scala.math.Numeric.BigIntIsIntegral", "scala.math.Numeric.ByteIsIntegral", "scala.math.Numeric.CharIsIntegral", "scala.math.Numeric.DoubleIsFractional", "scala.math.Numeric.FloatIsFractional", "scala.math.Numeric.Implicits", "scala.math.Numeric.IntIsIntegral", "scala.math.Numeric.LongIsIntegral", "scala.math.Numeric.ShortIsIntegral", + "scala.math.Ordering.BigDecimal", + "scala.math.Ordering.BigInt", "scala.math.Ordering.Boolean", "scala.math.Ordering.Byte", "scala.math.Ordering.Char", "scala.math.Ordering.DeprecatedDoubleOrdering", "scala.math.Ordering.DeprecatedFloatOrdering", "scala.math.Ordering.Double", "scala.math.Ordering.Float", "scala.math.Ordering.Implicits", "scala.math.Ordering.Int", "scala.math.Ordering.Long", "scala.math.Ordering.Short", "scala.math.Ordering.String", "scala.math.Ordering.Symbol", "scala.math.Ordering.Unit", + "scala.math.Ordering#Double.IeeeOrdering", "scala.math.Ordering#Double.TotalOrdering", + "scala.math.Ordering#Float.IeeeOrdering", "scala.math.Ordering#Float.TotalOrdering", + "scala.package.#::", + "scala.PartialFunction.ElementWiseExtractor", + "scala.Predef.any2stringadd", + "scala.Predef.ArrowAssoc", "scala.Predef.Ensuring", "scala.Predef.StringFormat", + "scala.runtime.Tuple2Zipped.Ops", "scala.runtime.Tuple3Zipped.Ops", + "scala.sys.process.BasicIO.LazilyListed", "scala.sys.process.BasicIO.Streamed", "scala.sys.process.BasicIO.Uncloseable", + "scala.sys.Prop.DoubleProp", "scala.sys.Prop.FileProp", "scala.sys.Prop.IntProp", "scala.sys.Prop.StringProp", + "scala.util.control.Exception.Catch", + "scala.util.control.TailCalls.Call", "scala.util.control.TailCalls.Cont", "scala.util.control.TailCalls.Done", + "scala.util.Either.LeftProjection", "scala.util.Either.MergeableEither", "scala.util.Either.RightProjection", + "scala.util.matching.Regex.Groups", "scala.util.matching.Regex.Match", + "scala.util.package.chaining", + "scala.util.Using.Manager", "scala.util.Using.Releasable", "scala.util.Using#Releasable.AutoCloseableIsReleasable", + ).map(ProblemFilters.exclude[MissingFieldProblem]) + } + ) +} diff --git a/project/ScaladocGeneration.scala b/project/ScaladocGeneration.scala index ade9b65d5445..aac9f187a888 100644 --- a/project/ScaladocGeneration.scala +++ b/project/ScaladocGeneration.scala @@ -137,6 +137,10 @@ object ScaladocGeneration { def key: String = "-quick-links" } + case class DynamicSideMenu(value: Boolean) extends Arg[Boolean] { + def key: String = "-dynamic-side-menu" + } + import _root_.scala.reflect._ trait GenerationConfig { diff --git a/project/TastyMiMaFilters.scala b/project/TastyMiMaFilters.scala index 0d2ed387da33..85a9b98b7d87 100644 --- a/project/TastyMiMaFilters.scala +++ b/project/TastyMiMaFilters.scala @@ -20,11 +20,10 @@ object TastyMiMaFilters { ProblemMatcher.make(ProblemKind.MissingTermMember, "scala.math.Big*.underlying"), ProblemMatcher.make(ProblemKind.NewAbstractMember, "scala.math.ScalaNumericConversions.underlying"), - // Problem: super accessors + // Probably OK: super accessors // In Scala 3 these accessors are added in the `postyper` phase. // In Scala 2 these accessors are added in the `superaccessors` phase after typer. - // Are these accessors in the Scala 2 pickles? If so, it implies that TASTy Query/MiMa is ignoring them in Scala 2 but not Scala 3. - // Otherwise, if these are not in the Scala 2 pickles, we might need to remove them when compiling with -Ycompile-scala2-library + // Handle as a special case in `ExtensionMethods`. ProblemMatcher.make(ProblemKind.NewAbstractMember, "scala.collection.immutable.IndexedSeqOps.superscala$collection$immutable$IndexedSeqOps$$slice"), ProblemMatcher.make(ProblemKind.NewAbstractMember, "scala.collection.immutable.StrictOptimizedSeqOps.superscala$collection$immutable$StrictOptimizedSeqOps$$sorted"), ProblemMatcher.make(ProblemKind.NewAbstractMember, "scala.collection.immutable.IndexedSeq.superscala$collection$immutable$IndexedSeq$$*"/* sameElements, canEqual */), @@ -38,7 +37,7 @@ object TastyMiMaFilters { ProblemMatcher.make(ProblemKind.NewAbstractMember, "scala.util.control.NoStackTrace.superscala$util$control$NoStackTrace$$fillInStackTrace"), // TASTy-MiMa bug (probably OK): `private[scala] var` in case class - // This is probably because we can only access the next field from the scala library. + // This member should not have been loaded by TASTy-MiMa. ProblemMatcher.make(ProblemKind.MissingTermMember, "scala.collection.immutable.::.next$access$1"), // Probably OK: Problem Missing setter for `protected var` @@ -60,15 +59,16 @@ object TastyMiMaFilters { ProblemMatcher.make(ProblemKind.MissingTermMember, "scala.Predef.ne"), // The member scala.Predef.ne with signature (java.lang.Object,java.lang.Object):scala.Boolean does not have a correspondant in current version ProblemMatcher.make(ProblemKind.MissingTermMember, "scala.Predef.eq"), // The member scala.Predef.eq with signature (java.lang.Object,java.lang.Object):scala.Boolean does not have a correspondant in current version - // Problem: protected lazy val (processThread, (futureThread, futureValue), destroyer) = { ... } + // Probably OK: protected lazy val (processThread, (futureThread, futureValue), destroyer) = { ... } + // None of these can be accessed from user code. // https://github.com/scala/scala/blob/cff8a9af4da67658d8e1e32f929e1aff03ffa384/src/library/scala/sys/process/ProcessImpl.scala#L99C5-L99C83 ProblemMatcher.make(ProblemKind.IncompatibleKindChange, "scala.sys.process.ProcessImpl.CompoundProcess.destroyer"), // before: lazy val; after: def ProblemMatcher.make(ProblemKind.IncompatibleKindChange, "scala.sys.process.ProcessImpl.CompoundProcess.futureThread"), // before: lazy val; after: def ProblemMatcher.make(ProblemKind.IncompatibleKindChange, "scala.sys.process.ProcessImpl.CompoundProcess.processThread"), // before: lazy val; after: def ProblemMatcher.make(ProblemKind.IncompatibleKindChange, "scala.sys.process.ProcessImpl.CompoundProcess.futureValue"), // before: lazy val; after: def - // Problem? - // https://github.com/scala/scala/blob/2.13.x/src/library/scala/collection/convert/JavaCollectionWrappers.scala#L66-L71 + // Probably Ok: defined within a `private[collection]` object + // https://github.com/scala/scala/blob/2.13.x/src/library/scala/collection/convert/JavaCollectionWrappers.scala#L66-L71 ProblemMatcher.make(ProblemKind.MissingTermMember, "scala.collection.convert.JavaCollectionWrappers.IterableWrapperTrait.iterator"), // The member scala.collection.convert.JavaCollectionWrappers.IterableWrapperTrait.iterator with signature ():scala.collection.convert.JavaCollectionWrappers.IteratorWrapper does not have a correspondant in current version // Problem? diff --git a/project/build.properties b/project/build.properties index 52413ab79a18..e8a1e246e8ad 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.3 +sbt.version=1.9.7 diff --git a/project/scripts/bisect.scala b/project/scripts/bisect.scala index dbb14f2c4587..e97fbb3fafd7 100755 --- a/project/scripts/bisect.scala +++ b/project/scripts/bisect.scala @@ -35,9 +35,9 @@ val usageMessage = """ |* --releases <releases-range> | Bisect only releases from the given range (defaults to all releases). | The range format is <first>...<last>, where both <first> and <last> are optional, e.g. - | * 3.1.0-RC1-bin-20210827-427d313-NIGHTLY..3.2.1-RC1-bin-20220716-bb9c8ff-NIGHTLY - | * 3.2.1-RC1-bin-20220620-de3a82c-NIGHTLY.. - | * ..3.3.0-RC1-bin-20221124-e25362d-NIGHTLY + | * 3.1.0-RC1-bin-20210827-427d313-NIGHTLY...3.2.1-RC1-bin-20220716-bb9c8ff-NIGHTLY + | * 3.2.1-RC1-bin-20220620-de3a82c-NIGHTLY... + | * ...3.3.0-RC1-bin-20221124-e25362d-NIGHTLY | The ranges are treated as inclusive. | |* --bootstrapped @@ -169,9 +169,13 @@ class Releases(val releases: Vector[Release]) object Releases: lazy val allReleases: Vector[Release] = - val re = raw"""(?<=title=")(.+-bin-\d{8}-\w{7}-NIGHTLY)(?=/")""".r - val html = Source.fromURL("https://repo1.maven.org/maven2/org/scala-lang/scala3-compiler_3/") - re.findAllIn(html.mkString).map(Release.apply).toVector + val re = raw"<version>(.+-bin-\d{8}-\w{7}-NIGHTLY)</version>".r + val xml = io.Source.fromURL( + "https://repo1.maven.org/maven2/org/scala-lang/scala3-compiler_3/maven-metadata.xml" + ) + re.findAllMatchIn(xml.mkString) + .flatMap{ m => Option(m.group(1)).map(Release.apply) } + .toVector def fromRange(range: ReleasesRange): Vector[Release] = range.filter(allReleases) @@ -237,7 +241,7 @@ class CommitBisect(validationScript: File, shouldFail: Boolean, bootstrapped: Bo val validationCommandStatusModifier = if shouldFail then "! " else "" // invert the process status if failure was expected val bisectRunScript = raw""" |scalaVersion=$$(sbt "print ${scala3CompilerProject}/version" | tail -n1) - |rm -r out + |rm -rf out |sbt "clean; set every doc := new File(\"unused\"); set scaladoc/Compile/resourceGenerators := (\`${scala3Project}\`/Compile/resourceGenerators).value; ${scala3Project}/publishLocal" |${validationCommandStatusModifier}${validationScript.getAbsolutePath} "$$scalaVersion" """.stripMargin diff --git a/project/scripts/bootstrappedOnlyCmdTests b/project/scripts/bootstrappedOnlyCmdTests index 8a0f5cf78f2f..4e18e3a1d4a4 100755 --- a/project/scripts/bootstrappedOnlyCmdTests +++ b/project/scripts/bootstrappedOnlyCmdTests @@ -113,7 +113,7 @@ scala_version=${versionProps[2]} echo "testing -sourcepath with incremental compile: inlining changed inline def into a def" # Here we will test that a changed inline method symbol loaded from the sourcepath (-sourcepath compiler option) # will have its `defTree` correctly set when its method body is required for inlining. -# So far I have not found a way to replicate issue https://github.com/lampepfl/dotty/issues/13994 +# So far I have not found a way to replicate issue https://github.com/scala/scala3/issues/13994 # with sbt scripted tests, if a way is found, move this test there. cwd=$(pwd) sbt_test_command="++${scala_version}!;clean;prepareSources;compile;copyChanges;compile" @@ -126,7 +126,7 @@ echo "testing -sourcepath with incremental compile: hashing reference to changed # Here we will test that a changed inline method symbol loaded from the sourcepath (-sourcepath compiler option) # will have its `defTree` correctly set when its method body is hashed by extractAPI, when referenced from another # inline method. -# So far I have not found a way to replicate https://github.com/lampepfl/dotty/pull/12931#discussion_r753212124 +# So far I have not found a way to replicate https://github.com/scala/scala3/pull/12931#discussion_r753212124 # with sbt scripted tests, if a way is found, move this test there. cwd=$(pwd) sbt_test_dir="$cwd/tests/cmdTest-sbt-tests/sourcepath-with-inline-api-hash" diff --git a/project/scripts/cmdScaladocTests b/project/scripts/cmdScaladocTests index e9403d988b98..06353af693f1 100755 --- a/project/scripts/cmdScaladocTests +++ b/project/scripts/cmdScaladocTests @@ -16,7 +16,7 @@ DOTTY_NONBOOTSTRAPPED_VERSION=$(eval $DOTTY_NONBOOTSTRAPPED_VERSION_COMMAND | ta DOTTY_BOOTSTRAPPED_VERSION_COMMAND="$SBT \"eval println(Build.dottyVersion)\"" DOTTY_BOOTSTRAPPED_VERSION=$(eval $DOTTY_BOOTSTRAPPED_VERSION_COMMAND | tail -n 2 | head -n 1) -SOURCE_LINKS_REPOSITORY="lampepfl/dotty" +SOURCE_LINKS_REPOSITORY="scala/scala3" SOURCE_LINKS_VERSION="${GITHUB_SHA:-$DOTTY_BOOTSTRAPPED_VERSION}" "$SBT" "scaladoc/generateTestcasesDocumentation" > "$tmp" 2>&1 || echo "generated testcases project with sbt" @@ -30,7 +30,7 @@ dist/target/pack/bin/scaladoc \ "-skip-by-regex:.+\.internal($|\..+)" \ "-skip-by-regex:.+\.impl($|\..+)" \ -project-logo docs/_assets/images/logo.svg \ - -social-links:github::https://github.com/lampepfl/dotty,discord::https://discord.com/invite/scala,twitter::https://twitter.com/scala_lang \ + -social-links:github::https://github.com/scala/scala3,discord::https://discord.com/invite/scala,twitter::https://twitter.com/scala_lang \ -Ygenerate-inkuire \ "-skip-by-id:scala.runtime.stdLibPatches" \ "-skip-by-id:scala.runtime.MatchCase" \ @@ -42,4 +42,4 @@ dist/target/pack/bin/scaladoc \ -author -groups -revision main -project-version "${DOTTY_BOOTSTRAPPED_VERSION}" \ "-quick-links:Learn::https://docs.scala-lang.org/,Install::https://www.scala-lang.org/download/,Playground::https://scastie.scala-lang.org,Find A Library::https://index.scala-lang.org,Community::https://www.scala-lang.org/community/,Blog::https://www.scala-lang.org/blog/," \ out/bootstrap/scaladoc-testcases/scala-"${DOTTY_NONBOOTSTRAPPED_VERSION}"/classes > "$tmp" 2>&1 || echo "generated testcases project with scripts" -diff -rq "$OUT1" "scaladoc/output/testcases" +diff -r "$OUT1" "scaladoc/output/testcases" diff --git a/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java b/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java index 2d54d4e83404..20256d9e17cc 100644 --- a/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java +++ b/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java @@ -79,7 +79,7 @@ private static void reportMissingFile(DelegatingReporter reporter, SourceFile so underline + "\n" + " Falling back to placeholder for the given source file (of class " + sourceFile.getClass().getName() + ")\n" + " This is likely a bug in incremental compilation for the Scala 3 compiler.\n" + - " Please report it to the Scala 3 maintainers at https://github.com/lampepfl/dotty/issues."; + " Please report it to the Scala 3 maintainers at https://github.com/scala/scala3/issues."; reporter.reportBasicWarning(message); } diff --git a/sbt-bridge/src/xsbt/CachedCompilerImpl.java b/sbt-bridge/src/xsbt/CachedCompilerImpl.java index 8b7779f9c9cb..c9d4c50485ed 100644 --- a/sbt-bridge/src/xsbt/CachedCompilerImpl.java +++ b/sbt-bridge/src/xsbt/CachedCompilerImpl.java @@ -18,7 +18,7 @@ import dotty.tools.dotc.sbt.interfaces.IncrementalCallback; // deprecation warnings are suppressed because scala3-sbt-bridge must stay compatible with Zinc 1.3 -// see https://github.com/lampepfl/dotty/issues/10816 +// see https://github.com/scala/scala3/issues/10816 @SuppressWarnings("deprecation") public class CachedCompilerImpl implements CachedCompiler { private final String[] args; diff --git a/sbt-test/sbt-bridge/zinc-13-compat/test b/sbt-test/sbt-bridge/zinc-13-compat/test index f7b3295e155c..aecadb2f539d 100644 --- a/sbt-test/sbt-bridge/zinc-13-compat/test +++ b/sbt-test/sbt-bridge/zinc-13-compat/test @@ -1,3 +1,3 @@ # this little app test that scala3-sbt-bridge is compatible with Zinc 1.3 -# this is necessary to maintain the compatibility with Bloop (see https://github.com/lampepfl/dotty/issues/10816) +# this is necessary to maintain the compatibility with Bloop (see https://github.com/scala/scala3/issues/10816) > run diff --git a/sbt-test/sbt-dotty/scala2-library-tasty/build.sbt b/sbt-test/sbt-dotty/scala2-library-tasty/build.sbt new file mode 100644 index 000000000000..ce95be79470f --- /dev/null +++ b/sbt-test/sbt-dotty/scala2-library-tasty/build.sbt @@ -0,0 +1,4 @@ +scalaVersion := sys.props("plugin.scalaVersion") + +libraryDependencies += "org.scala-lang" %% "scala2-library-tasty" % scalaVersion.value +scalacOptions += "-Yscala2-unpickler:never" // check that we do not load symbol from the Scala 2 library classfiles (use TASTy) diff --git a/sbt-test/sbt-dotty/scala2-library-tasty/src/main/scala/hello/Hello.scala b/sbt-test/sbt-dotty/scala2-library-tasty/src/main/scala/hello/Hello.scala new file mode 100644 index 000000000000..87277631f69b --- /dev/null +++ b/sbt-test/sbt-dotty/scala2-library-tasty/src/main/scala/hello/Hello.scala @@ -0,0 +1,4 @@ +package hello + +@main def hello: Unit = + println(Some("Hello world!")) // load Some form the Scala 2 library TASTy diff --git a/sbt-test/sbt-dotty/scala2-library-tasty/test b/sbt-test/sbt-dotty/scala2-library-tasty/test new file mode 100644 index 000000000000..62ea636c177f --- /dev/null +++ b/sbt-test/sbt-dotty/scala2-library-tasty/test @@ -0,0 +1 @@ +> run diff --git a/sbt-test/sbt-dotty/scaladoc/src/main/scala/AutoParamTupling.scala b/sbt-test/sbt-dotty/scaladoc/src/main/scala/AutoParamTupling.scala index 3636fd218ca3..7010a43a5107 100644 --- a/sbt-test/sbt-dotty/scaladoc/src/main/scala/AutoParamTupling.scala +++ b/sbt-test/sbt-dotty/scaladoc/src/main/scala/AutoParamTupling.scala @@ -11,7 +11,7 @@ object AutoParamTupling { * In order to get thread safety, you need to put @volatile before lazy vals. * https://dotty.epfl.ch/docs/reference/changed-features/lazy-vals.html */ - @volatile lazy val xs: List[String] = List("d", "o", "t", "t", "y") + lazy val xs: List[String] = List("d", "o", "t", "t", "y") /** * Current behaviour in Scala 2.12.2 : diff --git a/sbt-test/sbt-dotty/scaladoc/src/main/scala/MultiversalEquality.scala b/sbt-test/sbt-dotty/scaladoc/src/main/scala/MultiversalEquality.scala index a4089e75de19..b8ebaf5565df 100644 --- a/sbt-test/sbt-dotty/scaladoc/src/main/scala/MultiversalEquality.scala +++ b/sbt-test/sbt-dotty/scaladoc/src/main/scala/MultiversalEquality.scala @@ -4,7 +4,7 @@ import scala.language.strictEquality /** * Multiversal Equality: https://dotty.epfl.ch/docs/reference/contextual/multiversal-equality.html - * scala.Eq definition: https://github.com/lampepfl/dotty/blob/master/library/src/scala/CanEqual.scala + * scala.Eq definition: https://github.com/scala/scala3/blob/master/library/src/scala/CanEqual.scala */ object MultiversalEquality { diff --git a/sbt-test/sbt-dotty/tasty-inspector-cache/inspector/src/main/scala/main.scala b/sbt-test/sbt-dotty/tasty-inspector-cache/inspector/src/main/scala/main.scala index 8335a016578f..b17747aa3ccf 100644 --- a/sbt-test/sbt-dotty/tasty-inspector-cache/inspector/src/main/scala/main.scala +++ b/sbt-test/sbt-dotty/tasty-inspector-cache/inspector/src/main/scala/main.scala @@ -2,7 +2,7 @@ import scala.quoted.Quotes import scala.quoted.quotes import scala.tasty.inspector as ins -// Test for https://github.com/lampepfl/dotty/issues/13919 +// Test for https://github.com/scala/scala3/issues/13919 class MyInspector extends ins.Inspector: def inspect(using Quotes)(tastys: List[ins.Tasty[quotes.type]]): Unit = import quotes.reflect._ diff --git a/sbt-test/source-dependencies/malformed-class-name-with-dollar/test b/sbt-test/source-dependencies/malformed-class-name-with-dollar/test index cf2dc1898f3e..bc71a440925e 100644 --- a/sbt-test/source-dependencies/malformed-class-name-with-dollar/test +++ b/sbt-test/source-dependencies/malformed-class-name-with-dollar/test @@ -1,5 +1,5 @@ > compile $ copy-file changes/A.scala A.scala -# It seems that https://github.com/lampepfl/dotty/pull/10784 break incremental compilation here +# It seems that https://github.com/scala/scala3/pull/10784 break incremental compilation here > clean > compile diff --git a/scala2-library-cc/src/scala/Function1.scala b/scala2-library-cc/src/scala/Function1.scala new file mode 100644 index 000000000000..96ca493739ed --- /dev/null +++ b/scala2-library-cc/src/scala/Function1.scala @@ -0,0 +1,90 @@ +/* + * 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. + */ + +// GENERATED CODE: DO NOT EDIT. See scala.Function0 for timestamp. + +package scala + + +object Function1 { + + implicit final class UnliftOps[A, B] private[Function1](private val f: A => Option[B]) extends AnyVal { + /** Converts an optional function to a partial function. + * + * @example Unlike [[Function.unlift]], this [[UnliftOps.unlift]] method can be used in extractors. + * {{{ + * val of: Int => Option[String] = { i => + * if (i == 2) { + * Some("matched by an optional function") + * } else { + * None + * } + * } + * + * util.Random.nextInt(4) match { + * case of.unlift(m) => // Convert an optional function to a pattern + * println(m) + * case _ => + * println("Not matched") + * } + * }}} + */ + def unlift: PartialFunction[A, B] = Function.unlift(f) + } + +} + +/** A function of 1 parameter. + * + * In the following example, the definition of `succ` is + * shorthand, conceptually, for the anonymous class definition + * `anonfun1`, although the implementation details of how the + * function value is constructed may differ: + * + * {{{ + * object Main extends App { + * val succ = (x: Int) => x + 1 + * val anonfun1 = new Function1[Int, Int] { + * def apply(x: Int): Int = x + 1 + * } + * assert(succ(0) == anonfun1(0)) + * } + * }}} + * + * Note that the difference between `Function1` and [[scala.PartialFunction]] + * is that the latter can specify inputs which it will not handle. + */ +@annotation.implicitNotFound(msg = "No implicit view available from ${T1} => ${R}.") +trait Function1[@specialized(Specializable.Arg) -T1, @specialized(Specializable.Return) +R] extends AnyRef { // FIXME: self => + /** Apply the body of this function to the argument. + * @return the result of function application. + */ + def apply(v1: T1): R + + /** Composes two instances of Function1 in a new Function1, with this function applied last. + * + * @tparam A the type to which function `g` can be applied + * @param g a function A => T1 + * @return a new function `f` such that `f(x) == apply(g(x))` + */ + @annotation.unspecialized def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + + /** Composes two instances of Function1 in a new Function1, with this function applied first. + * + * @tparam A the result type of function `g` + * @param g a function R => A + * @return a new function `f` such that `f(x) == g(apply(x))` + */ + @annotation.unspecialized def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + + override def toString(): String = "<function1>" +} diff --git a/scala2-library-cc/src/scala/PartialFunction.scala b/scala2-library-cc/src/scala/PartialFunction.scala new file mode 100644 index 000000000000..671d58be33e5 --- /dev/null +++ b/scala2-library-cc/src/scala/PartialFunction.scala @@ -0,0 +1,403 @@ +/* + * 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 + +import scala.annotation.nowarn + +/** A partial function of type `PartialFunction[A, B]` is a unary function + * where the domain does not necessarily include all values of type `A`. + * The function [[isDefinedAt]] allows to test dynamically if a value is in + * the domain of the function. + * + * Even if `isDefinedAt` returns true for an `a: A`, calling `apply(a)` may + * still throw an exception, so the following code is legal: + * + * {{{ + * val f: PartialFunction[Int, Any] = { case x => x / 0 } // ArithmeticException: / by zero + * }}} + * + * It is the responsibility of the caller to call `isDefinedAt` before + * calling `apply`, because if `isDefinedAt` is false, it is not guaranteed + * `apply` will throw an exception to indicate an error condition. If an + * exception is not thrown, evaluation may result in an arbitrary value. + * + * The usual way to respect this contract is to call [[applyOrElse]], + * 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: + * + * {{{ + * 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" + * // because it uses a PartialFunction to select elements + * // to which the function is applied. + * val evenNumbers = sample.collect(eveningNews) + * + * 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) + * + * // same as + * 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) + * + * // Providing "default" values. + * val oddsAndEnds = sample.map(n => oddByHalf.applyOrElse(n, (i: Int) => s"[\$i]")) + * }}} + * + * @note Optional [[Function]]s, [[PartialFunction]]s and extractor objects + * can be converted to each other as shown in the following table. + * + * | How to convert ... | to a [[PartialFunction]] | to an optional [[Function]] | to an extractor | + * | :---: | --- | --- | --- | + * | 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]] | + * + * + * @define applyOrElseOrElse Note that calling [[isDefinedAt]] on the resulting partial function + * may apply the first partial function and execute its side effect. + * For efficiency, it is recommended to call [[applyOrElse]] instead of [[isDefinedAt]] or [[apply]]. + */ +trait PartialFunction[-A, +B] extends (A => B) { // FIXME: self => + import PartialFunction._ + + /** Tries to extract a `B` from an `A` in a pattern matching expression. */ + def unapply(a: A): Option[B] = lift(a) + + /** Returns an extractor object with a `unapplySeq` method, which extracts each element of a sequence data. + * + * @example {{{ + * val firstChar: String => Option[Char] = _.headOption + * + * Seq("foo", "bar", "baz") match { + * case firstChar.unlift.elementWise(c0, c1, c2) => + * println(s"\$c0, \$c1, \$c2") // Output: f, b, b + * } + * }}} + */ + def elementWise: ElementWiseExtractor[A, B] = new ElementWiseExtractor[A, B](this) + + /** Checks if a value is contained in the function's domain. + * + * @param x the value to test + * @return `'''true'''`, iff `x` is in the domain of this function, `'''false'''` otherwise. + */ + def isDefinedAt(x: A): Boolean + + /** Composes this partial function with a fallback partial function which + * gets applied where this partial function is not defined. + * + * @param that the fallback function + * @tparam A1 the argument type of the fallback function + * @tparam B1 the result type of the fallback function + * @return a partial function which has as domain the union of the domains + * of this partial function and `that`. The resulting partial function + * takes `x` to `this(x)` where `this` is defined, and to `that(x)` where it is not. + */ + def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = + new OrElse[A1, B1] (this, that) + //TODO: why not overload it with orElse(that: F1): F1? + + /** Composes this partial function with a transformation function that + * gets applied to results of this partial function. + * + * If the runtime type of the function is a `PartialFunction` then the + * other `andThen` method is used (note its cautions). + * + * @param k the transformation function + * @tparam C the result type of the transformation function. + * @return a partial function with the domain of this partial function, + * possibly narrowed by the specified function, which maps + * arguments `x` to `k(this(x))`. + */ + override def andThen[C](k: B => C): PartialFunction[A, C] = k match { + case pf: PartialFunction[B, C] => andThen(pf) + case _ => new AndThen[A, B, C](this, k) + } + + /** + * Composes this partial function with another partial function that + * gets applied to results of this partial function. + * + * $applyOrElseOrElse + * + * @param k the transformation function + * @tparam C the result type of the transformation function. + * @return a partial function with the domain of this partial function narrowed by + * other partial function, which maps arguments `x` to `k(this(x))`. + */ + def andThen[C](k: PartialFunction[B, C]): PartialFunction[A, C] = + new Combined[A, B, C](this, k) + + /** + * Composes another partial function `k` with this partial function so that this + * partial function gets applied to results of `k`. + * + * $applyOrElseOrElse + * + * @param k the transformation function + * @tparam R the parameter type of the transformation function. + * @return a partial function with the domain of other partial function narrowed by + * this partial function, which maps arguments `x` to `this(k(x))`. + */ + def compose[R](k: PartialFunction[R, A]): PartialFunction[R, B] = + new Combined[R, A, B](k, this) + + /** Turns this partial function into a plain function returning an `Option` result. + * @see Function.unlift + * @return a function that takes an argument `x` to `Some(this(x))` if `this` + * is defined for `x`, and to `None` otherwise. + */ + def lift: A => Option[B] = new Lifted(this) + + /** Applies this partial function to the given argument when it is contained in the function domain. + * Applies fallback function where this partial function is not defined. + * + * Note that expression `pf.applyOrElse(x, default)` is equivalent to + * {{{ if(pf isDefinedAt x) pf(x) else default(x) }}} + * except that `applyOrElse` method can be implemented more efficiently. + * For all partial function literals the compiler generates an `applyOrElse` implementation which + * avoids double evaluation of pattern matchers and guards. + * This makes `applyOrElse` the basis for the efficient implementation for many operations and scenarios, such as: + * + * - combining partial functions into `orElse`/`andThen` chains does not lead to + * excessive `apply`/`isDefinedAt` evaluation + * - `lift` and `unlift` do not evaluate source functions twice on each invocation + * - `runWith` allows efficient imperative-style combining of partial functions + * with conditionally applied actions + * + * For non-literal partial function classes with nontrivial `isDefinedAt` method + * it is recommended to override `applyOrElse` with custom implementation that avoids + * double `isDefinedAt` evaluation. This may result in better performance + * and more predictable behavior w.r.t. side effects. + * + * @param x the function argument + * @param default the fallback function + * @return the result of this function or fallback function application. + */ + def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = + if (isDefinedAt(x)) apply(x) else default(x) + + /** Composes this partial function with an action function which + * gets applied to results of this partial function. + * The action function is invoked only for its side effects; its result is ignored. + * + * Note that expression `pf.runWith(action)(x)` is equivalent to + * {{{ if(pf isDefinedAt x) { action(pf(x)); true } else false }}} + * except that `runWith` is implemented via `applyOrElse` and thus potentially more efficient. + * Using `runWith` avoids double evaluation of pattern matchers and guards for partial function literals. + * @see `applyOrElse`. + * + * @param action the action function + * @return a function which maps arguments `x` to `isDefinedAt(x)`. The resulting function + * runs `action(this(x))` where `this` is defined. + */ + def runWith[U](action: B => U): A => Boolean = { x => + val z = applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(z)) { action(z); true } else false + } +} + +/** A few handy operations which leverage the extra bit of information + * available in partial functions. Examples: + * {{{ + * import PartialFunction._ + * + * def strangeConditional(other: Any): Boolean = cond(other) { + * case x: String if x == "abc" || x == "def" => true + * case x: Int => true + * } + * def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x } + * }}} + */ +object PartialFunction { + + final class ElementWiseExtractor[-A, +B] private[PartialFunction] (private val pf: PartialFunction[A, B]) extends AnyVal { + @nowarn("cat=lint-nonlocal-return") + def unapplySeq(seq: Seq[A]): Option[Seq[B]] = { + Some(seq.map { + case pf(b) => b + case _ => return None + }) + } + } + + /** Composite function produced by `PartialFunction#orElse` method + */ + private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) + extends scala.runtime.AbstractPartialFunction[A, B] with Serializable { + def isDefinedAt(x: A) = f1.isDefinedAt(x) || f2.isDefinedAt(x) + + override def apply(x: A): B = f1.applyOrElse(x, f2) + + override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = { + val z = f1.applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(z)) z else f2.applyOrElse(x, default) + } + + override def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): OrElse[A1, B1] = + new OrElse[A1, B1] (f1, f2 orElse that) + + override def andThen[C](k: B => C): OrElse[A, C] = + new OrElse[A, C] (f1 andThen k, f2 andThen k) + } + + /** Composite function produced by `PartialFunction#andThen` method + */ + private class AndThen[-A, B, +C] (pf: PartialFunction[A, B], k: B => C) extends PartialFunction[A, C] with Serializable { + def isDefinedAt(x: A) = pf.isDefinedAt(x) + + def apply(x: A): C = k(pf(x)) + + override def applyOrElse[A1 <: A, C1 >: C](x: A1, default: A1 => C1): C1 = { + val z = pf.applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(z)) k(z) else default(x) + } + } + + /** Composite function produced by `PartialFunction#andThen` method + */ + private class Combined[-A, B, +C] (pf: PartialFunction[A, B], k: PartialFunction[B, C]) extends PartialFunction[A, C] with Serializable { + def isDefinedAt(x: A): Boolean = { + val b: B = pf.applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(b)) k.isDefinedAt(b) else false + } + + def apply(x: A): C = k(pf(x)) + + override def applyOrElse[A1 <: A, C1 >: C](x: A1, default: A1 => C1): C1 = { + val pfv = pf.applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(pfv)) k.applyOrElse(pfv, (_: B) => default(x)) else default(x) + } + } + + /** To implement patterns like {{{ if(pf isDefinedAt x) f1(pf(x)) else f2(x) }}} efficiently + * the following trick is used: + * + * To avoid double evaluation of pattern matchers & guards `applyOrElse` method is used here + * instead of `isDefinedAt`/`apply` pair. + * + * After call to `applyOrElse` we need both the function result it returned and + * the fact if the function's argument was contained in its domain. The only degree of freedom we have here + * to achieve this goal is tweaking with the continuation argument (`default`) of `applyOrElse` method. + * The obvious way is to throw an exception from `default` function and to catch it after + * calling `applyOrElse` but I consider this somewhat inefficient. + * + * I know only one way how you can do this task efficiently: `default` function should return unique marker object + * which never may be returned by any other (regular/partial) function. This way after calling `applyOrElse` you need + * just one reference comparison to distinguish if `pf isDefined x` or not. + * + * This correctly interacts with specialization as return type of `applyOrElse` + * (which is parameterized upper bound) can never be specialized. + * + * Here `fallback_fn` is used as both unique marker object and special fallback function that returns it. + */ + private[this] val fallback_fn: Any => Any = _ => fallback_fn + private def checkFallback[B] = fallback_fn.asInstanceOf[Any => B] + private def fallbackOccurred[B](x: B) = fallback_fn eq x.asInstanceOf[AnyRef] + + private class Lifted[-A, +B] (val pf: PartialFunction[A, B]) + extends scala.runtime.AbstractFunction1[A, Option[B]] with Serializable { + + def apply(x: A): Option[B] = { + val z = pf.applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(z)) Some(z) else None + } + } + + private class Unlifted[A, B] (f: A => Option[B]) extends scala.runtime.AbstractPartialFunction[A, B] with Serializable { + def isDefinedAt(x: A): Boolean = f(x).isDefined + + override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = { + f(x).getOrElse(default(x)) + } + + override def lift = f + } + + private[scala] def unlifted[A, B](f: A => Option[B]): PartialFunction[A, B] = f match { + case lf: Lifted[A, B] => lf.pf + case ff => new Unlifted(ff) + } + + /** Converts an ordinary function to a partial function. Note that calling `isDefinedAt(x)` on + * this partial function will return `true` for every `x`. + * @param f an ordinary function + * @return a partial function which delegates to the ordinary function `f` + */ + def fromFunction[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) } + + private[this] val constFalse: Any => Boolean = { _ => false} + + private[this] val empty_pf: PartialFunction[Any, Nothing] = new PartialFunction[Any, Nothing] with Serializable { + def isDefinedAt(x: Any) = false + def apply(x: Any) = throw new MatchError(x) + override def orElse[A1, B1](that: PartialFunction[A1, B1]) = that + override def andThen[C](k: Nothing => C): PartialFunction[Any, Nothing] = this + override val lift: Any => None.type = (x: Any) => None + override def runWith[U](action: Nothing => U) = constFalse + } + + /** The partial function with empty domain. + * Any attempt to invoke empty partial function leads to throwing [[scala.MatchError]] exception. + */ + def empty[A, B] : PartialFunction[A, B] = empty_pf + + /** A Boolean test that is the result of the given function where defined, + * and false otherwise. + * + * It behaves like a `case _ => false` were added to the partial function. + * + * @param x the value to test + * @param pf the partial function + * @return true, iff `x` is in the domain of `pf` and `pf(x) == true`. + */ + def cond[A](x: A)(pf: PartialFunction[A, Boolean]): Boolean = pf.applyOrElse(x, constFalse) + + /** Apply the function to the given value if defined, and return the result + * in a `Some`; otherwise, return `None`. + * + * @param x the value to test + * @param pf the PartialFunction[T, U] + * @return `Some(pf(x))` if `pf isDefinedAt x`, `None` otherwise. + */ + def condOpt[A, B](x: A)(pf: PartialFunction[A, B]): Option[B] = { + val z = pf.applyOrElse(x, checkFallback[B]) + if (!fallbackOccurred(z)) Some(z) else None + } +} diff --git a/scala2-library-cc/src/scala/TODO b/scala2-library-cc/src/scala/TODO new file mode 100644 index 000000000000..241779ab8dd9 --- /dev/null +++ b/scala2-library-cc/src/scala/TODO @@ -0,0 +1 @@ +- Delete or re-clone Function1 and PartialFunction. These where edited to remove the self type. diff --git a/tests/pos-special/stdlib/collection/ArrayOps.scala b/scala2-library-cc/src/scala/collection/ArrayOps.scala similarity index 98% rename from tests/pos-special/stdlib/collection/ArrayOps.scala rename to scala2-library-cc/src/scala/collection/ArrayOps.scala index bb6174f59598..e8548c12751f 100644 --- a/tests/pos-special/stdlib/collection/ArrayOps.scala +++ b/scala2-library-cc/src/scala/collection/ArrayOps.scala @@ -113,7 +113,7 @@ object ArrayOps { b.result() } - def flatMap[BS, B](f: A => BS)(implicit asIterable: BS => Iterable[B], m: ClassTag[B]): Array[B] = + def flatMap[BS, B](f: A => BS)(implicit asIterable: BS => Iterable[B], m: ClassTag[B]): Array[B] = flatMap[B](x => asIterable(f(x))) /** Creates a new non-strict filter which combines this filter with the given predicate. */ @@ -505,7 +505,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * * @return a pair of arrays: the first one made of those values returned by `f` that were wrapped in [[scala.util.Left]], * and the second one made of those wrapped in [[scala.util.Right]]. */ - def partitionMap[A1: ClassTag, A2: ClassTag](f: A => Either[A1, A2]): (Array[A1], Array[A2]) = { + def partitionMap[A1: ClassTag, A2: ClassTag](f: A => Either[A1, A2]): (Array[A1], Array[A2]) = { val res1 = ArrayBuilder.make[A1] val res2 = ArrayBuilder.make[A2] var i = 0 @@ -816,7 +816,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * }}} * */ - def scanLeft[B : ClassTag](z: B)(op: (B, A) => B): Array[B] = { + def scanLeft[ B : ClassTag ](z: B)(op: (B, A) => B): Array[B] = { var v = z var i = 0 val res = new Array[B](xs.length + 1) @@ -855,7 +855,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * }}} * */ - def scanRight[B : ClassTag](z: B)(op: (A, B) => B): Array[B] = { + def scanRight[ B : ClassTag ](z: B)(op: (A, B) => B): Array[B] = { var v = z var i = xs.length - 1 val res = new Array[B](xs.length + 1) @@ -973,7 +973,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { b.result() } - def flatMap[BS, B](f: A => BS)(implicit asIterable: BS => Iterable[B], m: ClassTag[B]): Array[B] = + def flatMap[BS, B](f: A => BS)(implicit asIterable: BS => Iterable[B], m: ClassTag[B]): Array[B] = flatMap[B](x => asIterable(f(x))) /** Flattens a two-dimensional array by concatenating all its rows @@ -1095,7 +1095,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * If this array is shorter than `that`, `thisElem` values are used to pad the result. * If `that` is shorter than this array, `thatElem` values are used to pad the result. */ - def zipAll[A1 >: A, B](that: Iterable[B], thisElem: A1, thatElem: B): Array[(A1, B)] = { + def zipAll[A1 >: A, B](that: Iterable[B], thisElem: A1, thatElem: B): Array[(A1, B)] = { val b = new ArrayBuilder.ofRef[(A1, B)]() val k = that.knownSize b.sizeHint(max(k, xs.length)) @@ -1244,7 +1244,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * @return a pair of Arrays, containing, respectively, the first and second half * of each element pair of this Array. */ - def unzip[A1, A2](implicit asPair: A => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (Array[A1], Array[A2]) = { + def unzip[A1, A2](implicit asPair: A => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (Array[A1], Array[A2]) = { val a1 = new Array[A1](xs.length) val a2 = new Array[A2](xs.length) var i = 0 @@ -1273,7 +1273,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * @return a triple of Arrays, containing, respectively, the first, second, and third * elements from each element triple of this Array. */ - def unzip3[A1, A2, A3](implicit asTriple: A => (A1, A2, A3), ct1: ClassTag[A1], ct2: ClassTag[A2], + def unzip3[A1, A2, A3](implicit asTriple: A => (A1, A2, A3), ct1: ClassTag[A1], ct2: ClassTag[A2], ct3: ClassTag[A3]): (Array[A1], Array[A2], Array[A3]) = { val a1 = new Array[A1](xs.length) val a2 = new Array[A2](xs.length) @@ -1418,7 +1418,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { * @tparam K the type of keys returned by the discriminator function * @tparam B the type of values returned by the transformation function */ - def groupMap[K, B : ClassTag](key: A => K)(f: A => B): immutable.Map[K, Array[B]] = { + def groupMap[K, B : ClassTag](key: A => K)(f: A => B): immutable.Map[K, Array[B]] = { val m = mutable.Map.empty[K, ArrayBuilder[B]] val len = xs.length var i = 0 @@ -1479,7 +1479,8 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal { /** Create a copy of this array with the specified element type. */ def toArray[B >: A: ClassTag]: Array[B] = { val destination = new Array[B](xs.length) - copyToArray(destination, 0) + @annotation.unused val copied = copyToArray(destination, 0) + //assert(copied == xs.length) destination } diff --git a/tests/pos-special/stdlib/collection/BitSet.scala b/scala2-library-cc/src/scala/collection/BitSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/BitSet.scala rename to scala2-library-cc/src/scala/collection/BitSet.scala diff --git a/tests/pos-special/stdlib/collection/BufferedIterator.scala b/scala2-library-cc/src/scala/collection/BufferedIterator.scala similarity index 100% rename from tests/pos-special/stdlib/collection/BufferedIterator.scala rename to scala2-library-cc/src/scala/collection/BufferedIterator.scala diff --git a/tests/pos-special/stdlib/collection/BuildFrom.scala b/scala2-library-cc/src/scala/collection/BuildFrom.scala similarity index 99% rename from tests/pos-special/stdlib/collection/BuildFrom.scala rename to scala2-library-cc/src/scala/collection/BuildFrom.scala index 05df32856d82..d82e90777d3e 100644 --- a/tests/pos-special/stdlib/collection/BuildFrom.scala +++ b/scala2-library-cc/src/scala/collection/BuildFrom.scala @@ -87,7 +87,7 @@ object BuildFrom extends BuildFromLowPriority1 { def newBuilder(from: Array[_]): Builder[A, Array[A]] = Factory.arrayFactory[A].newBuilder } - implicit def buildFromView[A, B]: BuildFrom[View[A], B, View[B]] = + implicit def buildFromView[A, B]: BuildFrom[View[A], B, View[B]] = new BuildFrom[View[A], B, View[B]] { def fromSpecific(from: View[A])(it: IterableOnce[B]^): View[B] = View.from(it).unsafeAssumePure def newBuilder(from: View[A]): Builder[B, View[B]] = View.newBuilder diff --git a/tests/pos-special/stdlib/collection/DefaultMap.scala b/scala2-library-cc/src/scala/collection/DefaultMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/DefaultMap.scala rename to scala2-library-cc/src/scala/collection/DefaultMap.scala diff --git a/tests/pos-special/stdlib/collection/Factory.scala b/scala2-library-cc/src/scala/collection/Factory.scala similarity index 96% rename from tests/pos-special/stdlib/collection/Factory.scala rename to scala2-library-cc/src/scala/collection/Factory.scala index c50fa395a0fb..5392d7e2c642 100644 --- a/tests/pos-special/stdlib/collection/Factory.scala +++ b/scala2-library-cc/src/scala/collection/Factory.scala @@ -160,8 +160,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @param elem the element computation * @return A $coll that contains the results of `n1 x n2` evaluations of `elem`. */ - def fill[A](n1: Int, n2: Int)(elem: => A): CC[CC[A] @uncheckedVariance]^{elem} = // !!! problem with checking rhs under cc - ??? // fill(n1)(fill(n2)(elem)) + def fill[A](n1: Int, n2: Int)(elem: => A): CC[(CC[A]^{elem}) @uncheckedVariance]^{elem} = + fill(n1)(fill(n2)(elem)) /** Produces a three-dimensional $coll containing the results of some element computation a number of times. * @param n1 the number of elements in the 1st dimension @@ -170,8 +170,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @param elem the element computation * @return A $coll that contains the results of `n1 x n2 x n3` evaluations of `elem`. */ - def fill[A](n1: Int, n2: Int, n3: Int)(elem: => A): CC[CC[CC[A]] @uncheckedVariance]^{elem} = // !!! problem with checking rhs under cc - ??? // fill(n1)(fill(n2, n3)(elem)).unsafeAssumePure + def fill[A](n1: Int, n2: Int, n3: Int)(elem: => A): CC[(CC[CC[A]^{elem}]^{elem}) @uncheckedVariance]^{elem} = + fill(n1)(fill(n2, n3)(elem)) /** Produces a four-dimensional $coll containing the results of some element computation a number of times. * @param n1 the number of elements in the 1st dimension @@ -181,8 +181,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @param elem the element computation * @return A $coll that contains the results of `n1 x n2 x n3 x n4` evaluations of `elem`. */ - def fill[A](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): CC[CC[CC[CC[A]]] @uncheckedVariance]^{elem} = // !!! problem with checking rhs under cc - ??? // fill(n1)(fill(n2, n3, n4)(elem)) + def fill[A](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): CC[(CC[CC[CC[A]^{elem}]^{elem}]^{elem}) @uncheckedVariance]^{elem} = + fill(n1)(fill(n2, n3, n4)(elem)) /** Produces a five-dimensional $coll containing the results of some element computation a number of times. * @param n1 the number of elements in the 1st dimension @@ -193,8 +193,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @param elem the element computation * @return A $coll that contains the results of `n1 x n2 x n3 x n4 x n5` evaluations of `elem`. */ - def fill[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): CC[CC[CC[CC[CC[A]]]] @uncheckedVariance]^{elem} = // !!! problem with checking rhs under cc - ??? // fill(n1)(fill(n2, n3, n4, n5)(elem)) + def fill[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): CC[(CC[CC[CC[CC[A]^{elem}]^{elem}]^{elem}]^{elem}) @uncheckedVariance]^{elem} = + fill(n1)(fill(n2, n3, n4, n5)(elem)) /** Produces a $coll containing values of a given function over a range of integer values starting from 0. * @param n The number of elements in the $coll @@ -210,8 +210,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @return A $coll consisting of elements `f(i1, i2)` * for `0 <= i1 < n1` and `0 <= i2 < n2`. */ - def tabulate[A](n1: Int, n2: Int)(f: (Int, Int) => A): CC[CC[A] @uncheckedVariance]^{f} = // !!! problem with checking rhs under cc - ??? // tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) + def tabulate[A](n1: Int, n2: Int)(f: (Int, Int) => A): CC[(CC[A]^{f}) @uncheckedVariance]^{f} = + tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) /** Produces a three-dimensional $coll containing values of a given function over ranges of integer values starting from 0. * @param n1 the number of elements in the 1st dimension @@ -221,8 +221,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @return A $coll consisting of elements `f(i1, i2, i3)` * for `0 <= i1 < n1`, `0 <= i2 < n2`, and `0 <= i3 < n3`. */ - def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[CC[CC[A]] @uncheckedVariance]^{f} = // !!! problem with checking rhs under cc - ??? // tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) + def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[(CC[CC[A]^{f}]^{f}) @uncheckedVariance]^{f} = + tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) /** Produces a four-dimensional $coll containing values of a given function over ranges of integer values starting from 0. * @param n1 the number of elements in the 1st dimension @@ -233,8 +233,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @return A $coll consisting of elements `f(i1, i2, i3, i4)` * for `0 <= i1 < n1`, `0 <= i2 < n2`, `0 <= i3 < n3`, and `0 <= i4 < n4`. */ - def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): CC[CC[CC[CC[A]]] @uncheckedVariance]^{f} = // !!! problem with checking rhs under cc - ??? // tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) + def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): CC[(CC[CC[CC[A]^{f}]^{f}]^{f}) @uncheckedVariance]^{f} = + tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) /** Produces a five-dimensional $coll containing values of a given function over ranges of integer values starting from 0. * @param n1 the number of elements in the 1st dimension @@ -246,8 +246,8 @@ trait IterableFactory[+CC[_]] extends Serializable, Pure { * @return A $coll consisting of elements `f(i1, i2, i3, i4, i5)` * for `0 <= i1 < n1`, `0 <= i2 < n2`, `0 <= i3 < n3`, `0 <= i4 < n4`, and `0 <= i5 < n5`. */ - def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): CC[CC[CC[CC[CC[A]]]] @uncheckedVariance]^{f} = // !!! problem with checking rhs under cc - ??? // tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) + def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): CC[(CC[CC[CC[CC[A]^{f}]^{f}]^{f}]^{f}) @uncheckedVariance]^{f} = + tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) /** Concatenates all argument collections into a single $coll. * diff --git a/tests/pos-special/stdlib/collection/Hashing.scala b/scala2-library-cc/src/scala/collection/Hashing.scala similarity index 100% rename from tests/pos-special/stdlib/collection/Hashing.scala rename to scala2-library-cc/src/scala/collection/Hashing.scala diff --git a/tests/pos-special/stdlib/collection/IndexedSeq.scala b/scala2-library-cc/src/scala/collection/IndexedSeq.scala similarity index 91% rename from tests/pos-special/stdlib/collection/IndexedSeq.scala rename to scala2-library-cc/src/scala/collection/IndexedSeq.scala index a2d4cc942231..998d1a5a635f 100644 --- a/tests/pos-special/stdlib/collection/IndexedSeq.scala +++ b/scala2-library-cc/src/scala/collection/IndexedSeq.scala @@ -94,11 +94,25 @@ trait IndexedSeqOps[+A, +CC[_], +C] extends Any with IndexedSeqViewOps[A, CC, C] override def slice(from: Int, until: Int): C = fromSpecific(new IndexedSeqView.Slice(this, from, until)) - override def head: A = apply(0) + override def head: A = + if (!isEmpty) apply(0) + else throw new NoSuchElementException(s"head of empty ${ + self match { + case self: IndexedSeq[_] => self.collectionClassName + case _ => toString + } + }") override def headOption: Option[A] = if (isEmpty) None else Some(head) - override def last: A = apply(length - 1) + override def last: A = + if (!isEmpty) apply(length - 1) + else throw new NoSuchElementException(s"last of empty ${ + self match { + case self: IndexedSeq[_] => self.collectionClassName + case _ => toString + } + }") // We already inherit an efficient `lastOption = if (isEmpty) None else Some(last)` diff --git a/tests/pos-special/stdlib/collection/IndexedSeqView.scala b/scala2-library-cc/src/scala/collection/IndexedSeqView.scala similarity index 98% rename from tests/pos-special/stdlib/collection/IndexedSeqView.scala rename to scala2-library-cc/src/scala/collection/IndexedSeqView.scala index a16e06fa707d..0b6f1bc8e64e 100644 --- a/tests/pos-special/stdlib/collection/IndexedSeqView.scala +++ b/scala2-library-cc/src/scala/collection/IndexedSeqView.scala @@ -55,7 +55,6 @@ object IndexedSeqView { @SerialVersionUID(3L) private[collection] class IndexedSeqViewIterator[A](self: IndexedSeqView[A]^) extends AbstractIterator[A] with Serializable { - this: IndexedSeqViewIterator[A]^ => private[this] var current = 0 private[this] var remainder = self.length override def knownSize: Int = remainder @@ -90,7 +89,6 @@ object IndexedSeqView { } @SerialVersionUID(3L) private[collection] class IndexedSeqViewReverseIterator[A](self: IndexedSeqView[A]^) extends AbstractIterator[A] with Serializable { - this: IndexedSeqViewReverseIterator[A]^ => private[this] var remainder = self.length private[this] var pos = remainder - 1 @inline private[this] def _hasNext: Boolean = remainder > 0 diff --git a/tests/pos-special/stdlib/collection/Iterable.scala b/scala2-library-cc/src/scala/collection/Iterable.scala similarity index 99% rename from tests/pos-special/stdlib/collection/Iterable.scala rename to scala2-library-cc/src/scala/collection/Iterable.scala index bca80d7be108..5afc14f4ceef 100644 --- a/tests/pos-special/stdlib/collection/Iterable.scala +++ b/scala2-library-cc/src/scala/collection/Iterable.scala @@ -9,7 +9,6 @@ * See the NOTICE file distributed with this work for * additional information regarding copyright ownership. */ - package scala package collection @@ -29,7 +28,6 @@ import language.experimental.captureChecking trait Iterable[+A] extends IterableOnce[A] with IterableOps[A, Iterable, Iterable[A]] with IterableFactoryDefaults[A, Iterable] { - this: Iterable[A]^ => // The collection itself @deprecated("toIterable 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.7") @@ -134,7 +132,6 @@ trait Iterable[+A] extends IterableOnce[A] * and may be nondeterministic. */ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with IterableOnceOps[A, CC, C] { - this: IterableOps[A, CC, C]^ => /** * @return This collection as an `Iterable[A]`. No new collection will be built if `this` is already an `Iterable[A]`. @@ -400,7 +397,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable if (i != headSize) fail } - iterableFactory.from(bs.map(_.result())).asInstanceOf // !!! needed for cc + iterableFactory.from(bs.map(_.result())) } def filter(pred: A => Boolean): C^{this, pred} = fromSpecific(new View.Filter(this, pred, isFlipped = false)) diff --git a/tests/pos-special/stdlib/collection/IterableOnce.scala b/scala2-library-cc/src/scala/collection/IterableOnce.scala similarity index 99% rename from tests/pos-special/stdlib/collection/IterableOnce.scala rename to scala2-library-cc/src/scala/collection/IterableOnce.scala index a0b184410428..7e8555421c53 100644 --- a/tests/pos-special/stdlib/collection/IterableOnce.scala +++ b/scala2-library-cc/src/scala/collection/IterableOnce.scala @@ -19,7 +19,7 @@ import scala.collection.mutable.StringBuilder import scala.language.implicitConversions import scala.math.{Numeric, Ordering} import scala.reflect.ClassTag -import scala.runtime.AbstractFunction2 +import scala.runtime.{AbstractFunction1, AbstractFunction2} import language.experimental.captureChecking /** @@ -43,7 +43,6 @@ import language.experimental.captureChecking * @define coll collection */ trait IterableOnce[+A] extends Any { - this: IterableOnce[A]^ => /** Iterator can be used only once */ def iterator: Iterator[A]^{this} @@ -272,7 +271,7 @@ object IterableOnce { math.max(math.min(math.min(len, srcLen), destLen - start), 0) /** Calls `copyToArray` on the given collection, regardless of whether or not it is an `Iterable`. */ - @inline private[collection] def copyElemsToArray[A, B >: A]( + @inline private[collection] def copyElemsToArray[A, B >: A]( elems: IterableOnce[A]^, xs: Array[B], start: Int = 0, @@ -322,8 +321,6 @@ object IterableOnce { trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ => /////////////////////////////////////////////////////////////// Abstract methods that must be implemented - import IterableOnceOps.Maximized - /** Produces a $coll containing cumulative results of applying the * operator going left to right, including the initial value. * @@ -1053,6 +1050,29 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ => case _ => foldLeft(new Maximized[A, B]("maxBy")(f)(ord.gt))((m, a) => m(m, a)).result } + private class Maximized[X, B](descriptor: String)(f: X -> B)(cmp: (B, B) -> Boolean) extends AbstractFunction2[Maximized[X, B], X, Maximized[X, B]] { + var maxElem: X = null.asInstanceOf[X] + var maxF: B = null.asInstanceOf[B] + var nonEmpty = false + def toOption: Option[X] = if (nonEmpty) Some(maxElem) else None + def result: X = if (nonEmpty) maxElem else throw new UnsupportedOperationException(s"empty.$descriptor") + def apply(m: Maximized[X, B], a: X): Maximized[X, B] = + if (m.nonEmpty) { + val fa = f(a) + if (cmp(fa, maxF)) { + maxF = fa + maxElem = a + } + m + } + else { + m.nonEmpty = true + m.maxElem = a + m.maxF = f(a) + m + } + } + /** Finds the first element which yields the largest value measured by function f. * * $willNotTerminateInf @@ -1117,8 +1137,8 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ => 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 // (Tested to be lower-overhead than runWith. Would be better yet to not need to (formally) allocate it) - val sentinel: scala.Function1[A, Any] = new scala.runtime.AbstractFunction1[A, Any] { - def apply(a: A) = this + val sentinel: scala.Function1[A, Any] = new AbstractFunction1[A, Any] { + def apply(a: A): AbstractFunction1[A, Any] = this } val it = iterator while (it.hasNext) { @@ -1322,7 +1342,8 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ => def toArray[B >: A: ClassTag]: Array[B] = if (knownSize >= 0) { val destination = new Array[B](knownSize) - copyToArray(destination, 0) + @annotation.unused val copied = copyToArray(destination, 0) + //assert(copied == destination.length) destination } else mutable.ArrayBuilder.make[B].addAll(this).result() @@ -1335,31 +1356,3 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ => xs } } - -object IterableOnceOps: - - // Moved out of trait IterableOnceOps to here, since universal traits cannot - // have nested classes in Scala 3 - private class Maximized[X, B](descriptor: String)(f: X -> B)(cmp: (B, B) -> Boolean) extends AbstractFunction2[Maximized[X, B], X, Maximized[X, B]] { - var maxElem: X = null.asInstanceOf[X] - var maxF: B = null.asInstanceOf[B] - var nonEmpty = false - def toOption: Option[X] = if (nonEmpty) Some(maxElem) else None - def result: X = if (nonEmpty) maxElem else throw new UnsupportedOperationException(s"empty.$descriptor") - def apply(m: Maximized[X, B], a: X): Maximized[X, B] = - if (m.nonEmpty) { - val fa = f(a) - if (cmp(fa, maxF)) { - maxF = fa - maxElem = a - } - m - } - else { - m.nonEmpty = true - m.maxElem = a - m.maxF = f(a) - m - } - } -end IterableOnceOps \ No newline at end of file diff --git a/tests/pos-special/stdlib/collection/Iterator.scala b/scala2-library-cc/src/scala/collection/Iterator.scala similarity index 99% rename from tests/pos-special/stdlib/collection/Iterator.scala rename to scala2-library-cc/src/scala/collection/Iterator.scala index 57a12767320a..58ef4beb930d 100644 --- a/tests/pos-special/stdlib/collection/Iterator.scala +++ b/scala2-library-cc/src/scala/collection/Iterator.scala @@ -1302,5 +1302,4 @@ object Iterator extends IterableFactory[Iterator] { } /** Explicit instantiation of the `Iterator` trait to reduce class file size in subclasses. */ -abstract class AbstractIterator[+A] extends Iterator[A]: - this: Iterator[A]^ => +abstract class AbstractIterator[+A] extends Iterator[A] diff --git a/tests/pos-special/stdlib/collection/JavaConverters.scala b/scala2-library-cc/src/scala/collection/JavaConverters.scala similarity index 100% rename from tests/pos-special/stdlib/collection/JavaConverters.scala rename to scala2-library-cc/src/scala/collection/JavaConverters.scala diff --git a/tests/pos-special/stdlib/collection/LazyZipOps.scala b/scala2-library-cc/src/scala/collection/LazyZipOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/LazyZipOps.scala rename to scala2-library-cc/src/scala/collection/LazyZipOps.scala diff --git a/tests/pos-special/stdlib/collection/LinearSeq.scala b/scala2-library-cc/src/scala/collection/LinearSeq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/LinearSeq.scala rename to scala2-library-cc/src/scala/collection/LinearSeq.scala diff --git a/tests/pos-special/stdlib/collection/Map.scala b/scala2-library-cc/src/scala/collection/Map.scala similarity index 99% rename from tests/pos-special/stdlib/collection/Map.scala rename to scala2-library-cc/src/scala/collection/Map.scala index 8ab25a3c13e0..7ba393ecd242 100644 --- a/tests/pos-special/stdlib/collection/Map.scala +++ b/scala2-library-cc/src/scala/collection/Map.scala @@ -104,7 +104,6 @@ trait Map[K, +V] trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C] extends IterableOps[(K, V), Iterable, C] with PartialFunction[K, V] { - this: MapOps[K, V, CC, C]^ => override def view: MapView[K, V]^{this} = new MapView.Id(this) diff --git a/tests/pos-special/stdlib/collection/MapView.scala b/scala2-library-cc/src/scala/collection/MapView.scala similarity index 96% rename from tests/pos-special/stdlib/collection/MapView.scala rename to scala2-library-cc/src/scala/collection/MapView.scala index 595fe20538d3..e6c5c91e1dd5 100644 --- a/tests/pos-special/stdlib/collection/MapView.scala +++ b/scala2-library-cc/src/scala/collection/MapView.scala @@ -21,7 +21,6 @@ import caps.unsafe.unsafeAssumePure trait MapView[K, +V] extends MapOps[K, V, ({ type l[X, Y] = View[(X, Y)] })#l, View[(K, V)]] with View[(K, V)] { - this: MapView[K, V]^ => override def view: MapView[K, V]^{this} = this @@ -82,7 +81,7 @@ object MapView extends MapViewFactory { @SerialVersionUID(3L) object EmptyMapView extends AbstractMapView[Any, Nothing] { - // !!! cc problem: crash when we replace the line with + // !!! cc problem? type mismatch when we replace the line with // private val EmptyMapView: MapView[Any, Nothing] = new AbstractMapView[Any, Nothing] { override def get(key: Any): Option[Nothing] = None override def iterator: Iterator[Nothing] = Iterator.empty[Nothing] @@ -161,7 +160,7 @@ object MapView extends MapViewFactory { override def isEmpty: Boolean = underlying.isEmpty } - override def newBuilder[X, Y]: Builder[(X, Y), MapView[X, Y]] = mutable.HashMap.newBuilder[X, Y].mapResult(_.view) + override def newBuilder[X, Y]: Builder[(X, Y), MapView[X, Y]] = mutable.HashMap.newBuilder[X, Y].mapResult(_.view) override def empty[K, V]: MapView[K, V] = EmptyMapView.asInstanceOf[MapView[K, V]] @@ -191,6 +190,5 @@ trait MapViewFactory extends collection.MapFactory[({ type l[X, Y] = View[(X, Y) /** Explicit instantiation of the `MapView` trait to reduce class file size in subclasses. */ @SerialVersionUID(3L) -abstract class AbstractMapView[K, +V] extends AbstractView[(K, V)] with MapView[K, V]: - this: AbstractMapView[K, V]^ => +abstract class AbstractMapView[K, +V] extends AbstractView[(K, V)] with MapView[K, V] diff --git a/tests/pos-special/stdlib/collection/Searching.scala b/scala2-library-cc/src/scala/collection/Searching.scala similarity index 100% rename from tests/pos-special/stdlib/collection/Searching.scala rename to scala2-library-cc/src/scala/collection/Searching.scala diff --git a/tests/pos-special/stdlib/collection/Seq.scala b/scala2-library-cc/src/scala/collection/Seq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/Seq.scala rename to scala2-library-cc/src/scala/collection/Seq.scala diff --git a/tests/pos-special/stdlib/collection/SeqMap.scala b/scala2-library-cc/src/scala/collection/SeqMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/SeqMap.scala rename to scala2-library-cc/src/scala/collection/SeqMap.scala diff --git a/tests/pos-special/stdlib/collection/SeqView.scala b/scala2-library-cc/src/scala/collection/SeqView.scala similarity index 100% rename from tests/pos-special/stdlib/collection/SeqView.scala rename to scala2-library-cc/src/scala/collection/SeqView.scala diff --git a/tests/pos-special/stdlib/collection/Set.scala b/scala2-library-cc/src/scala/collection/Set.scala similarity index 100% rename from tests/pos-special/stdlib/collection/Set.scala rename to scala2-library-cc/src/scala/collection/Set.scala diff --git a/tests/pos-special/stdlib/collection/SortedMap.scala b/scala2-library-cc/src/scala/collection/SortedMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/SortedMap.scala rename to scala2-library-cc/src/scala/collection/SortedMap.scala diff --git a/tests/pos-special/stdlib/collection/SortedOps.scala b/scala2-library-cc/src/scala/collection/SortedOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/SortedOps.scala rename to scala2-library-cc/src/scala/collection/SortedOps.scala diff --git a/tests/pos-special/stdlib/collection/SortedSet.scala b/scala2-library-cc/src/scala/collection/SortedSet.scala similarity index 99% rename from tests/pos-special/stdlib/collection/SortedSet.scala rename to scala2-library-cc/src/scala/collection/SortedSet.scala index fb2f879edcd2..639dc9ddead0 100644 --- a/tests/pos-special/stdlib/collection/SortedSet.scala +++ b/scala2-library-cc/src/scala/collection/SortedSet.scala @@ -69,7 +69,6 @@ trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]] * @param start The lower-bound (inclusive) of the iterator */ def iteratorFrom(start: A): Iterator[A] - @deprecated("Use `iteratorFrom` instead.", "2.13.0") @`inline` def keysIteratorFrom(start: A): Iterator[A] = iteratorFrom(start) diff --git a/tests/pos-special/stdlib/collection/Stepper.scala b/scala2-library-cc/src/scala/collection/Stepper.scala similarity index 99% rename from tests/pos-special/stdlib/collection/Stepper.scala rename to scala2-library-cc/src/scala/collection/Stepper.scala index 0a0ac0075990..2f8abee4cffb 100644 --- a/tests/pos-special/stdlib/collection/Stepper.scala +++ b/scala2-library-cc/src/scala/collection/Stepper.scala @@ -39,7 +39,6 @@ import scala.collection.Stepper.EfficientSplit * @tparam A the element type of the Stepper */ trait Stepper[@specialized(Double, Int, Long) +A] { - this: Stepper[A]^ => /** Check if there's an element available. */ def hasStep: Boolean @@ -186,7 +185,6 @@ object Stepper { /** A Stepper for arbitrary element types. See [[Stepper]]. */ trait AnyStepper[+A] extends Stepper[A] { - this: AnyStepper[A]^ => def trySplit(): AnyStepper[A] @@ -258,7 +256,6 @@ object AnyStepper { /** A Stepper for Ints. See [[Stepper]]. */ trait IntStepper extends Stepper[Int] { - this: IntStepper^ => def trySplit(): IntStepper @@ -298,7 +295,6 @@ object IntStepper { /** A Stepper for Doubles. See [[Stepper]]. */ trait DoubleStepper extends Stepper[Double] { - this: DoubleStepper^ => def trySplit(): DoubleStepper def spliterator[B >: Double]: Spliterator.OfDouble^{this} = new DoubleStepper.DoubleStepperSpliterator(this) @@ -338,7 +334,6 @@ object DoubleStepper { /** A Stepper for Longs. See [[Stepper]]. */ trait LongStepper extends Stepper[Long] { - this: LongStepper^ => def trySplit(): LongStepper^{this} diff --git a/tests/pos-special/stdlib/collection/StepperShape.scala b/scala2-library-cc/src/scala/collection/StepperShape.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StepperShape.scala rename to scala2-library-cc/src/scala/collection/StepperShape.scala diff --git a/tests/pos-special/stdlib/collection/StrictOptimizedIterableOps.scala b/scala2-library-cc/src/scala/collection/StrictOptimizedIterableOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StrictOptimizedIterableOps.scala rename to scala2-library-cc/src/scala/collection/StrictOptimizedIterableOps.scala diff --git a/tests/pos-special/stdlib/collection/StrictOptimizedMapOps.scala b/scala2-library-cc/src/scala/collection/StrictOptimizedMapOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StrictOptimizedMapOps.scala rename to scala2-library-cc/src/scala/collection/StrictOptimizedMapOps.scala diff --git a/tests/pos-special/stdlib/collection/StrictOptimizedSeqOps.scala b/scala2-library-cc/src/scala/collection/StrictOptimizedSeqOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StrictOptimizedSeqOps.scala rename to scala2-library-cc/src/scala/collection/StrictOptimizedSeqOps.scala diff --git a/tests/pos-special/stdlib/collection/StrictOptimizedSetOps.scala b/scala2-library-cc/src/scala/collection/StrictOptimizedSetOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StrictOptimizedSetOps.scala rename to scala2-library-cc/src/scala/collection/StrictOptimizedSetOps.scala diff --git a/tests/pos-special/stdlib/collection/StrictOptimizedSortedMapOps.scala b/scala2-library-cc/src/scala/collection/StrictOptimizedSortedMapOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StrictOptimizedSortedMapOps.scala rename to scala2-library-cc/src/scala/collection/StrictOptimizedSortedMapOps.scala diff --git a/tests/pos-special/stdlib/collection/StrictOptimizedSortedSetOps.scala b/scala2-library-cc/src/scala/collection/StrictOptimizedSortedSetOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StrictOptimizedSortedSetOps.scala rename to scala2-library-cc/src/scala/collection/StrictOptimizedSortedSetOps.scala diff --git a/tests/pos-special/stdlib/collection/StringOps.scala b/scala2-library-cc/src/scala/collection/StringOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/StringOps.scala rename to scala2-library-cc/src/scala/collection/StringOps.scala diff --git a/tests/pos-special/stdlib/collection/StringParsers.scala b/scala2-library-cc/src/scala/collection/StringParsers.scala similarity index 99% rename from tests/pos-special/stdlib/collection/StringParsers.scala rename to scala2-library-cc/src/scala/collection/StringParsers.scala index 47281815da71..75dedab7183c 100644 --- a/tests/pos-special/stdlib/collection/StringParsers.scala +++ b/scala2-library-cc/src/scala/collection/StringParsers.scala @@ -167,7 +167,6 @@ private[scala] object StringParsers { else None } } - //floating point final def checkFloatFormat(format: String): Boolean = { //indices are tracked with a start index which points *at* the first index @@ -194,7 +193,6 @@ private[scala] object StringParsers { rec(from) } - def isHexFloatLiteral(startIndex: Int, endIndex: Int): Boolean = { def isHexDigit(ch: Char) = ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || @@ -232,7 +230,6 @@ private[scala] object StringParsers { val pIndex = format.indexWhere(ch => ch == 'p' || ch == 'P', startIndex) (pIndex <= endIndex) && prefixOK(startIndex, pIndex) && postfixOK(pIndex + 1, endIndex) } - def isDecFloatLiteral(startIndex: Int, endIndex: Int): Boolean = { //invariant: endIndex > startIndex @@ -279,7 +276,6 @@ private[scala] object StringParsers { //count 0x00 to 0x20 as "whitespace", and nothing else val unspacedStart = format.indexWhere(ch => ch.toInt > 0x20) val unspacedEnd = format.lastIndexWhere(ch => ch.toInt > 0x20) + 1 - if (unspacedStart == -1 || unspacedStart >= unspacedEnd || unspacedEnd <= 0) false else { //all formats can have a sign @@ -306,7 +302,6 @@ private[scala] object StringParsers { } } } - @inline def parseFloat(from: String): Option[Float] = if (checkFloatFormat(from)) Some(java.lang.Float.parseFloat(from)) diff --git a/tests/pos-special/stdlib/collection/View.scala b/scala2-library-cc/src/scala/collection/View.scala similarity index 99% rename from tests/pos-special/stdlib/collection/View.scala rename to scala2-library-cc/src/scala/collection/View.scala index 8e2ee3ad9e32..31c544a46beb 100644 --- a/tests/pos-special/stdlib/collection/View.scala +++ b/scala2-library-cc/src/scala/collection/View.scala @@ -24,7 +24,6 @@ import language.experimental.captureChecking * @define Coll `View` */ trait View[+A] extends Iterable[A] with IterableOps[A, View, View[A]] with IterableFactoryDefaults[A, View] with Serializable { - this: View[A]^ => override def view: View[A]^{this} = this diff --git a/tests/pos-special/stdlib/collection/WithFilter.scala b/scala2-library-cc/src/scala/collection/WithFilter.scala similarity index 98% rename from tests/pos-special/stdlib/collection/WithFilter.scala rename to scala2-library-cc/src/scala/collection/WithFilter.scala index 0f3830e9fe25..a2255a8cc0c5 100644 --- a/tests/pos-special/stdlib/collection/WithFilter.scala +++ b/scala2-library-cc/src/scala/collection/WithFilter.scala @@ -23,7 +23,6 @@ import language.experimental.captureChecking */ @SerialVersionUID(3L) abstract class WithFilter[+A, +CC[_]] extends Serializable { - this: WithFilter[A, CC]^ => /** Builds a new collection by applying a function to all elements of the * `filtered` outer $coll. diff --git a/tests/pos-special/stdlib/collection/concurrent/Map.scala b/scala2-library-cc/src/scala/collection/concurrent/Map.scala similarity index 100% rename from tests/pos-special/stdlib/collection/concurrent/Map.scala rename to scala2-library-cc/src/scala/collection/concurrent/Map.scala diff --git a/tests/pos-special/stdlib/collection/concurrent/TrieMap.scala b/scala2-library-cc/src/scala/collection/concurrent/TrieMap.scala similarity index 99% rename from tests/pos-special/stdlib/collection/concurrent/TrieMap.scala rename to scala2-library-cc/src/scala/collection/concurrent/TrieMap.scala index 8a34eddf0bdb..3bcbc60c8744 100644 --- a/tests/pos-special/stdlib/collection/concurrent/TrieMap.scala +++ b/scala2-library-cc/src/scala/collection/concurrent/TrieMap.scala @@ -1183,10 +1183,7 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: stack(d) = arr1 stackpos(d) = -1 val it = newIterator(level + 1, ct, _mustInit = false) - val xss: Array[Array[BasicNode]] = it.stack.asInstanceOf - // !!! cc split into separate xss and asInstanceOf needed because cc gets confused with - // two-dimensinal invariant arrays - xss(0) = arr2 + it.stack(0) = arr2 it.stackpos(0) = -1 it.depth = 0 it.advance() // <-- fix it diff --git a/tests/pos-special/stdlib/collection/convert/AsJavaConverters.scala b/scala2-library-cc/src/scala/collection/convert/AsJavaConverters.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/AsJavaConverters.scala rename to scala2-library-cc/src/scala/collection/convert/AsJavaConverters.scala diff --git a/tests/pos-special/stdlib/collection/convert/AsJavaExtensions.scala b/scala2-library-cc/src/scala/collection/convert/AsJavaExtensions.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/AsJavaExtensions.scala rename to scala2-library-cc/src/scala/collection/convert/AsJavaExtensions.scala diff --git a/tests/pos-special/stdlib/collection/convert/AsScalaConverters.scala b/scala2-library-cc/src/scala/collection/convert/AsScalaConverters.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/AsScalaConverters.scala rename to scala2-library-cc/src/scala/collection/convert/AsScalaConverters.scala diff --git a/tests/pos-special/stdlib/collection/convert/AsScalaExtensions.scala b/scala2-library-cc/src/scala/collection/convert/AsScalaExtensions.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/AsScalaExtensions.scala rename to scala2-library-cc/src/scala/collection/convert/AsScalaExtensions.scala diff --git a/tests/pos-special/stdlib/collection/convert/ImplicitConversions.scala b/scala2-library-cc/src/scala/collection/convert/ImplicitConversions.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/ImplicitConversions.scala rename to scala2-library-cc/src/scala/collection/convert/ImplicitConversions.scala diff --git a/tests/pos-special/stdlib/collection/convert/JavaCollectionWrappers.scala b/scala2-library-cc/src/scala/collection/convert/JavaCollectionWrappers.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/JavaCollectionWrappers.scala rename to scala2-library-cc/src/scala/collection/convert/JavaCollectionWrappers.scala diff --git a/tests/pos-special/stdlib/collection/convert/StreamExtensions.scala b/scala2-library-cc/src/scala/collection/convert/StreamExtensions.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/StreamExtensions.scala rename to scala2-library-cc/src/scala/collection/convert/StreamExtensions.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/ArrayStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/ArrayStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/ArrayStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/ArrayStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/BinaryTreeStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/BinaryTreeStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/BinaryTreeStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/BinaryTreeStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/BitSetStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/BitSetStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/BitSetStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/BitSetStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/ChampStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/ChampStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/ChampStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/ChampStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/InOrderStepperBase.scala b/scala2-library-cc/src/scala/collection/convert/impl/InOrderStepperBase.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/InOrderStepperBase.scala rename to scala2-library-cc/src/scala/collection/convert/impl/InOrderStepperBase.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/IndexedSeqStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/IndexedSeqStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/IndexedSeqStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/IndexedSeqStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/IndexedStepperBase.scala b/scala2-library-cc/src/scala/collection/convert/impl/IndexedStepperBase.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/IndexedStepperBase.scala rename to scala2-library-cc/src/scala/collection/convert/impl/IndexedStepperBase.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/IteratorStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/IteratorStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/IteratorStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/IteratorStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/NumericRangeStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/NumericRangeStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/NumericRangeStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/NumericRangeStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/RangeStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/RangeStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/RangeStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/RangeStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/StringStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/StringStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/StringStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/StringStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/TableStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/TableStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/TableStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/TableStepper.scala diff --git a/tests/pos-special/stdlib/collection/convert/impl/VectorStepper.scala b/scala2-library-cc/src/scala/collection/convert/impl/VectorStepper.scala similarity index 100% rename from tests/pos-special/stdlib/collection/convert/impl/VectorStepper.scala rename to scala2-library-cc/src/scala/collection/convert/impl/VectorStepper.scala diff --git a/tests/pos-special/stdlib/collection/generic/BitOperations.scala b/scala2-library-cc/src/scala/collection/generic/BitOperations.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/BitOperations.scala rename to scala2-library-cc/src/scala/collection/generic/BitOperations.scala diff --git a/tests/pos-special/stdlib/collection/generic/DefaultSerializationProxy.scala b/scala2-library-cc/src/scala/collection/generic/DefaultSerializationProxy.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/DefaultSerializationProxy.scala rename to scala2-library-cc/src/scala/collection/generic/DefaultSerializationProxy.scala diff --git a/tests/pos-special/stdlib/collection/generic/IsIterable.scala b/scala2-library-cc/src/scala/collection/generic/IsIterable.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/IsIterable.scala rename to scala2-library-cc/src/scala/collection/generic/IsIterable.scala diff --git a/tests/pos-special/stdlib/collection/generic/IsIterableOnce.scala b/scala2-library-cc/src/scala/collection/generic/IsIterableOnce.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/IsIterableOnce.scala rename to scala2-library-cc/src/scala/collection/generic/IsIterableOnce.scala diff --git a/tests/pos-special/stdlib/collection/generic/IsMap.scala b/scala2-library-cc/src/scala/collection/generic/IsMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/IsMap.scala rename to scala2-library-cc/src/scala/collection/generic/IsMap.scala diff --git a/tests/pos-special/stdlib/collection/generic/IsSeq.scala b/scala2-library-cc/src/scala/collection/generic/IsSeq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/IsSeq.scala rename to scala2-library-cc/src/scala/collection/generic/IsSeq.scala diff --git a/tests/pos-special/stdlib/collection/generic/Subtractable.scala b/scala2-library-cc/src/scala/collection/generic/Subtractable.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/Subtractable.scala rename to scala2-library-cc/src/scala/collection/generic/Subtractable.scala diff --git a/tests/pos-special/stdlib/collection/generic/package.scala b/scala2-library-cc/src/scala/collection/generic/package.scala similarity index 100% rename from tests/pos-special/stdlib/collection/generic/package.scala rename to scala2-library-cc/src/scala/collection/generic/package.scala diff --git a/tests/pos-special/stdlib/collection/immutable/ArraySeq.scala b/scala2-library-cc/src/scala/collection/immutable/ArraySeq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/ArraySeq.scala rename to scala2-library-cc/src/scala/collection/immutable/ArraySeq.scala diff --git a/tests/pos-special/stdlib/collection/immutable/BitSet.scala b/scala2-library-cc/src/scala/collection/immutable/BitSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/BitSet.scala rename to scala2-library-cc/src/scala/collection/immutable/BitSet.scala diff --git a/tests/pos-special/stdlib/collection/immutable/ChampCommon.scala b/scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala similarity index 99% rename from tests/pos-special/stdlib/collection/immutable/ChampCommon.scala rename to scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala index fc9bcb022874..3da269dccbd8 100644 --- a/tests/pos-special/stdlib/collection/immutable/ChampCommon.scala +++ b/scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala @@ -113,7 +113,6 @@ private[immutable] abstract class ChampBaseIterator[T <: Node[T]] { // ChampBaseReverseIterator and in convert.impl.ChampStepperBase. // If you change this code, check those also in case they also // need to be modified. - protected var currentValueCursor: Int = 0 protected var currentValueLength: Int = 0 protected var currentValueNode: T = _ diff --git a/tests/pos-special/stdlib/collection/immutable/HashMap.scala b/scala2-library-cc/src/scala/collection/immutable/HashMap.scala similarity index 99% rename from tests/pos-special/stdlib/collection/immutable/HashMap.scala rename to scala2-library-cc/src/scala/collection/immutable/HashMap.scala index 8faa37625d51..2d1179ef0ee6 100644 --- a/tests/pos-special/stdlib/collection/immutable/HashMap.scala +++ b/scala2-library-cc/src/scala/collection/immutable/HashMap.scala @@ -2384,7 +2384,7 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K, ) currentValueCursor += 1 } - }.asInstanceOf // !!! cc gets confused with representation of capture sets in invariant position + } case hm: collection.mutable.HashMap[K, V] => val iter = hm.nodeIterator while (iter.hasNext) { diff --git a/tests/pos-special/stdlib/collection/immutable/HashSet.scala b/scala2-library-cc/src/scala/collection/immutable/HashSet.scala similarity index 99% rename from tests/pos-special/stdlib/collection/immutable/HashSet.scala rename to scala2-library-cc/src/scala/collection/immutable/HashSet.scala index 9a3676705201..b4b8f9fdf27c 100644 --- a/tests/pos-special/stdlib/collection/immutable/HashSet.scala +++ b/scala2-library-cc/src/scala/collection/immutable/HashSet.scala @@ -2101,7 +2101,7 @@ private[collection] final class HashSetBuilder[A] extends ReusableBuilder[A, Has ) currentValueCursor += 1 } - }.asInstanceOf // !!! cc gets confused with representation of capture sets in invariant position + } case other => val it = other.iterator while(it.hasNext) addOne(it.next()) diff --git a/tests/pos-special/stdlib/collection/immutable/IntMap.scala b/scala2-library-cc/src/scala/collection/immutable/IntMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/IntMap.scala rename to scala2-library-cc/src/scala/collection/immutable/IntMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Iterable.scala b/scala2-library-cc/src/scala/collection/immutable/Iterable.scala similarity index 97% rename from tests/pos-special/stdlib/collection/immutable/Iterable.scala rename to scala2-library-cc/src/scala/collection/immutable/Iterable.scala index c4f9900eea8b..e40f5ada595e 100644 --- a/tests/pos-special/stdlib/collection/immutable/Iterable.scala +++ b/scala2-library-cc/src/scala/collection/immutable/Iterable.scala @@ -25,8 +25,6 @@ import language.experimental.captureChecking trait Iterable[+A] extends collection.Iterable[A] with collection.IterableOps[A, Iterable, Iterable[A]] with IterableFactoryDefaults[A, Iterable] { - this: Iterable[A]^ => - override def iterableFactory: IterableFactory[Iterable] = Iterable } diff --git a/tests/pos-special/stdlib/collection/immutable/LazyListIterable.scala b/scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala similarity index 99% rename from tests/pos-special/stdlib/collection/immutable/LazyListIterable.scala rename to scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala index 959dfbe36679..ac24995e6892 100644 --- a/tests/pos-special/stdlib/collection/immutable/LazyListIterable.scala +++ b/scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala @@ -251,7 +251,6 @@ final class LazyListIterable[+A] private(private[this] var lazyState: () => Lazy with IterableOps[A, LazyListIterable, LazyListIterable[A]] with IterableFactoryDefaults[A, LazyListIterable] with Serializable { - this: LazyListIterable[A]^ => import LazyListIterable._ @volatile private[this] var stateEvaluated: Boolean = false @@ -964,7 +963,6 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { private[this] val _empty = newLL(State.Empty).force private sealed trait State[+A] extends Serializable { - this: State[A]^ => def head: A def tail: LazyListIterable[A]^ } @@ -1252,7 +1250,6 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { private class SlidingIterator[A](private[this] var lazyList: LazyListIterable[A]^, size: Int, step: Int) extends AbstractIterator[LazyListIterable[A]] { - this: SlidingIterator[A]^ => private val minLen = size - step max 0 private var first = true @@ -1273,7 +1270,6 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { private final class WithFilter[A] private[LazyListIterable](lazyList: LazyListIterable[A]^, p: A => Boolean) extends collection.WithFilter[A, LazyListIterable] { - this: WithFilter[A]^ => private[this] val filtered = lazyList.filter(p) def map[B](f: A => B): LazyListIterable[B]^{this, f} = filtered.map(f) def flatMap[B](f: A => IterableOnce[B]^): LazyListIterable[B]^{this, f} = filtered.flatMap(f) @@ -1320,7 +1316,6 @@ object LazyListIterable extends IterableFactory[LazyListIterable] { private object LazyBuilder { final class DeferredState[A] { - this: DeferredState[A]^ => private[this] var _state: (() => State[A]^) @uncheckedCaptures = _ def eval(): State[A]^ = { diff --git a/tests/pos-special/stdlib/collection/immutable/List.scala b/scala2-library-cc/src/scala/collection/immutable/List.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/List.scala rename to scala2-library-cc/src/scala/collection/immutable/List.scala diff --git a/tests/pos-special/stdlib/collection/immutable/ListMap.scala b/scala2-library-cc/src/scala/collection/immutable/ListMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/ListMap.scala rename to scala2-library-cc/src/scala/collection/immutable/ListMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/ListSet.scala b/scala2-library-cc/src/scala/collection/immutable/ListSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/ListSet.scala rename to scala2-library-cc/src/scala/collection/immutable/ListSet.scala diff --git a/tests/pos-special/stdlib/collection/immutable/LongMap.scala b/scala2-library-cc/src/scala/collection/immutable/LongMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/LongMap.scala rename to scala2-library-cc/src/scala/collection/immutable/LongMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Map.scala b/scala2-library-cc/src/scala/collection/immutable/Map.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/Map.scala rename to scala2-library-cc/src/scala/collection/immutable/Map.scala diff --git a/tests/pos-special/stdlib/collection/immutable/NumericRange.scala b/scala2-library-cc/src/scala/collection/immutable/NumericRange.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/NumericRange.scala rename to scala2-library-cc/src/scala/collection/immutable/NumericRange.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Queue.scala b/scala2-library-cc/src/scala/collection/immutable/Queue.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/Queue.scala rename to scala2-library-cc/src/scala/collection/immutable/Queue.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Range.scala b/scala2-library-cc/src/scala/collection/immutable/Range.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/Range.scala rename to scala2-library-cc/src/scala/collection/immutable/Range.scala diff --git a/tests/pos-special/stdlib/collection/immutable/RedBlackTree.scala b/scala2-library-cc/src/scala/collection/immutable/RedBlackTree.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/RedBlackTree.scala rename to scala2-library-cc/src/scala/collection/immutable/RedBlackTree.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Seq.scala b/scala2-library-cc/src/scala/collection/immutable/Seq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/Seq.scala rename to scala2-library-cc/src/scala/collection/immutable/Seq.scala diff --git a/tests/pos-special/stdlib/collection/immutable/SeqMap.scala b/scala2-library-cc/src/scala/collection/immutable/SeqMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/SeqMap.scala rename to scala2-library-cc/src/scala/collection/immutable/SeqMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Set.scala b/scala2-library-cc/src/scala/collection/immutable/Set.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/Set.scala rename to scala2-library-cc/src/scala/collection/immutable/Set.scala diff --git a/tests/pos-special/stdlib/collection/immutable/SortedMap.scala b/scala2-library-cc/src/scala/collection/immutable/SortedMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/SortedMap.scala rename to scala2-library-cc/src/scala/collection/immutable/SortedMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/SortedSet.scala b/scala2-library-cc/src/scala/collection/immutable/SortedSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/SortedSet.scala rename to scala2-library-cc/src/scala/collection/immutable/SortedSet.scala diff --git a/tests/pos-special/stdlib/collection/immutable/StrictOptimizedSeqOps.scala b/scala2-library-cc/src/scala/collection/immutable/StrictOptimizedSeqOps.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/StrictOptimizedSeqOps.scala rename to scala2-library-cc/src/scala/collection/immutable/StrictOptimizedSeqOps.scala diff --git a/tests/pos-special/stdlib/collection/immutable/TreeMap.scala b/scala2-library-cc/src/scala/collection/immutable/TreeMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/TreeMap.scala rename to scala2-library-cc/src/scala/collection/immutable/TreeMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/TreeSeqMap.scala b/scala2-library-cc/src/scala/collection/immutable/TreeSeqMap.scala similarity index 98% rename from tests/pos-special/stdlib/collection/immutable/TreeSeqMap.scala rename to scala2-library-cc/src/scala/collection/immutable/TreeSeqMap.scala index fe194fa9de5a..dc59d21b8b19 100644 --- a/tests/pos-special/stdlib/collection/immutable/TreeSeqMap.scala +++ b/scala2-library-cc/src/scala/collection/immutable/TreeSeqMap.scala @@ -303,7 +303,7 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { else EmptyByInsertion }.asInstanceOf[TreeSeqMap[K, V]] - def from[K, V](it: collection.IterableOnce[(K, V)]^): TreeSeqMap[K, V] = + def from[K, V](it: collection.IterableOnce[(K, V)]^): TreeSeqMap[K, V] = it match { case om: TreeSeqMap[K, V] => om case _ => (newBuilder[K, V] ++= it).result() @@ -311,10 +311,10 @@ object TreeSeqMap extends MapFactory[TreeSeqMap] { @inline private def increment(ord: Int) = if (ord == Int.MaxValue) Int.MinValue else ord + 1 - def newBuilder[K, V]: mutable.Builder[(K, V), TreeSeqMap[K, V]] = newBuilder(OrderBy.Insertion) - def newBuilder[K, V](orderedBy: OrderBy): mutable.Builder[(K, V), TreeSeqMap[K, V]] = new Builder[K, V](orderedBy) + def newBuilder[K, V]: mutable.Builder[(K, V), TreeSeqMap[K, V]] = newBuilder(OrderBy.Insertion) + def newBuilder[K, V](orderedBy: OrderBy): mutable.Builder[(K, V), TreeSeqMap[K, V]] = new Builder[K, V](orderedBy) - final class Builder[K, V](orderedBy: OrderBy) extends mutable.Builder[(K, V), TreeSeqMap[K, V]] { + final class Builder[K, V](orderedBy: OrderBy) extends mutable.Builder[(K, V), TreeSeqMap[K, V]] { private[this] val bdr = new MapBuilderImpl[K, (Int, V)] private[this] var ong = Ordering.empty[K] private[this] var ord = 0 diff --git a/tests/pos-special/stdlib/collection/immutable/TreeSet.scala b/scala2-library-cc/src/scala/collection/immutable/TreeSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/TreeSet.scala rename to scala2-library-cc/src/scala/collection/immutable/TreeSet.scala diff --git a/tests/pos-special/stdlib/collection/immutable/Vector.scala b/scala2-library-cc/src/scala/collection/immutable/Vector.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/Vector.scala rename to scala2-library-cc/src/scala/collection/immutable/Vector.scala diff --git a/tests/pos-special/stdlib/collection/immutable/VectorMap.scala b/scala2-library-cc/src/scala/collection/immutable/VectorMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/VectorMap.scala rename to scala2-library-cc/src/scala/collection/immutable/VectorMap.scala diff --git a/tests/pos-special/stdlib/collection/immutable/WrappedString.scala b/scala2-library-cc/src/scala/collection/immutable/WrappedString.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/WrappedString.scala rename to scala2-library-cc/src/scala/collection/immutable/WrappedString.scala diff --git a/tests/pos-special/stdlib/collection/immutable/package.scala b/scala2-library-cc/src/scala/collection/immutable/package.scala similarity index 100% rename from tests/pos-special/stdlib/collection/immutable/package.scala rename to scala2-library-cc/src/scala/collection/immutable/package.scala diff --git a/tests/pos-special/stdlib/collection/mutable/AnyRefMap.scala b/scala2-library-cc/src/scala/collection/mutable/AnyRefMap.scala similarity index 91% rename from tests/pos-special/stdlib/collection/mutable/AnyRefMap.scala rename to scala2-library-cc/src/scala/collection/mutable/AnyRefMap.scala index 8f1ac07e725e..480babbf4b91 100644 --- a/tests/pos-special/stdlib/collection/mutable/AnyRefMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/AnyRefMap.scala @@ -43,7 +43,7 @@ import language.experimental.captureChecking * rapidly as 2^30^ is approached. * */ -class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, initialBufferSize: Int, initBlank: Boolean) +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]] with StrictOptimizedIterableOps[(K, V), Iterable, AnyRefMap[K, V]] @@ -478,11 +478,11 @@ class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K -> V, init } // The implicit dummy parameter is necessary to distinguish these methods from the base methods they overload (not override) - def map[K2 <: AnyRef, V2](f: ((K, V)) => (K2, V2))(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] = + def map[K2 <: AnyRef, V2](f: ((K, V)) => (K2, V2))(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] = AnyRefMap.from(new View.Map(this, f)) - def flatMap[K2 <: AnyRef, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] = + def flatMap[K2 <: AnyRef, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] = AnyRefMap.from(new View.FlatMap(this, f)) - def collect[K2 <: AnyRef, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] = + def collect[K2 <: AnyRef, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit dummy: DummyImplicit): AnyRefMap[K2, V2] = strictOptimizedCollect(AnyRefMap.newBuilder[K2, V2], pf) override def clear(): Unit = { @@ -515,7 +515,7 @@ object AnyRefMap { * * This builder can be reused to create multiple instances. */ - final class AnyRefMapBuilder[K <: AnyRef, V] extends ReusableBuilder[(K, V), AnyRefMap[K, V]] { + final class AnyRefMapBuilder[K <: AnyRef, V] extends ReusableBuilder[(K, V), AnyRefMap[K, V]] { private[collection] var elems: AnyRefMap[K, V] = new AnyRefMap[K, V] def addOne(entry: (K, V)): this.type = { elems += entry @@ -527,11 +527,11 @@ object AnyRefMap { } /** Creates a new `AnyRefMap` with zero or more key/value pairs. */ - def apply[K <: AnyRef, V](elems: (K, V)*): AnyRefMap[K, V] = buildFromIterableOnce(elems) + def apply[K <: AnyRef, V](elems: (K, V)*): AnyRefMap[K, V] = buildFromIterableOnce(elems) - def newBuilder[K <: AnyRef, V]: ReusableBuilder[(K, V), AnyRefMap[K, V]] = new AnyRefMapBuilder[K, V] + def newBuilder[K <: AnyRef, V]: ReusableBuilder[(K, V), AnyRefMap[K, V]] = new AnyRefMapBuilder[K, V] - private def buildFromIterableOnce[K <: AnyRef, V](elems: IterableOnce[(K, V)]^): AnyRefMap[K, V] = { + private def buildFromIterableOnce[K <: AnyRef, V](elems: IterableOnce[(K, V)]^): AnyRefMap[K, V] = { var sz = elems.knownSize if(sz < 0) sz = 4 val arm = new AnyRefMap[K, V](sz * 2) @@ -541,10 +541,10 @@ object AnyRefMap { } /** Creates a new empty `AnyRefMap`. */ - def empty[K <: AnyRef, V]: AnyRefMap[K, V] = new AnyRefMap[K, V] + def empty[K <: AnyRef, V]: AnyRefMap[K, V] = new AnyRefMap[K, V] /** Creates a new empty `AnyRefMap` with the supplied default */ - def withDefault[K <: AnyRef, V](default: K -> V): AnyRefMap[K, V] = new AnyRefMap[K, V](default) + def withDefault[K <: AnyRef, V](default: K -> V): AnyRefMap[K, V] = new AnyRefMap[K, V](default) /** Creates a new `AnyRefMap` from an existing source collection. A source collection * which is already an `AnyRefMap` gets cloned. @@ -554,7 +554,7 @@ object AnyRefMap { * @tparam V the type of the values * @return a new `AnyRefMap` with the elements of `source` */ - def from[K <: AnyRef, V](source: IterableOnce[(K, V)]^): AnyRefMap[K, V] = source match { + def from[K <: AnyRef, V](source: IterableOnce[(K, V)]^): AnyRefMap[K, V] = source match { case source: AnyRefMap[_, _] => source.clone().asInstanceOf[AnyRefMap[K, V]] case _ => buildFromIterableOnce(source) } @@ -562,7 +562,7 @@ object AnyRefMap { /** Creates a new `AnyRefMap` from arrays of keys and values. * Equivalent to but more efficient than `AnyRefMap((keys zip values): _*)`. */ - def fromZip[K <: AnyRef, V](keys: Array[K], values: Array[V]): AnyRefMap[K, V] = { + def fromZip[K <: AnyRef, V](keys: Array[K], values: Array[V]): AnyRefMap[K, V] = { val sz = math.min(keys.length, values.length) val arm = new AnyRefMap[K, V](sz * 2) var i = 0 @@ -574,7 +574,7 @@ object AnyRefMap { /** Creates a new `AnyRefMap` from keys and values. * Equivalent to but more efficient than `AnyRefMap((keys zip values): _*)`. */ - def fromZip[K <: AnyRef, V](keys: Iterable[K]^, values: Iterable[V]^): AnyRefMap[K, V] = { + def fromZip[K <: AnyRef, V](keys: Iterable[K]^, values: Iterable[V]^): AnyRefMap[K, V] = { val sz = math.min(keys.size, values.size) val arm = new AnyRefMap[K, V](sz * 2) val ki = keys.iterator @@ -584,7 +584,7 @@ object AnyRefMap { arm } - implicit def toFactory[K <: AnyRef, V](dummy: AnyRefMap.type): Factory[(K, V), AnyRefMap[K, V]] = ToFactory.asInstanceOf[Factory[(K, V), AnyRefMap[K, V]]] + implicit def toFactory[K <: AnyRef, V](dummy: AnyRefMap.type): Factory[(K, V), AnyRefMap[K, V]] = ToFactory.asInstanceOf[Factory[(K, V), AnyRefMap[K, V]]] @SerialVersionUID(3L) private[this] object ToFactory extends Factory[(AnyRef, AnyRef), AnyRefMap[AnyRef, AnyRef]] with Serializable { @@ -592,12 +592,12 @@ object AnyRefMap { def newBuilder: Builder[(AnyRef, AnyRef), AnyRefMap[AnyRef, AnyRef]] = AnyRefMap.newBuilder[AnyRef, AnyRef] } - implicit def toBuildFrom[K <: AnyRef, V](factory: AnyRefMap.type): BuildFrom[Any, (K, V), AnyRefMap[K, V]] = ToBuildFrom.asInstanceOf[BuildFrom[Any, (K, V), AnyRefMap[K, V]]] + implicit def toBuildFrom[K <: AnyRef, V](factory: AnyRefMap.type): BuildFrom[Any, (K, V), AnyRefMap[K, V]] = ToBuildFrom.asInstanceOf[BuildFrom[Any, (K, V), AnyRefMap[K, V]]] private[this] object ToBuildFrom extends BuildFrom[Any, (AnyRef, AnyRef), AnyRefMap[AnyRef, AnyRef]] { def fromSpecific(from: Any)(it: IterableOnce[(AnyRef, AnyRef)]^) = AnyRefMap.from(it) def newBuilder(from: Any) = AnyRefMap.newBuilder[AnyRef, AnyRef] } - implicit def iterableFactory[K <: AnyRef, V]: Factory[(K, V), AnyRefMap[K, V]] = toFactory[K, V](this) - implicit def buildFromAnyRefMap[K <: AnyRef, V]: BuildFrom[AnyRefMap[_, _], (K, V), AnyRefMap[K, V]] = toBuildFrom(this) + implicit def iterableFactory[K <: AnyRef, V]: Factory[(K, V), AnyRefMap[K, V]] = toFactory[K, V](this) + implicit def buildFromAnyRefMap[K <: AnyRef, V]: BuildFrom[AnyRefMap[_, _], (K, V), AnyRefMap[K, V]] = toBuildFrom(this) } diff --git a/tests/pos-special/stdlib/collection/mutable/ArrayBuffer.scala b/scala2-library-cc/src/scala/collection/mutable/ArrayBuffer.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ArrayBuffer.scala rename to scala2-library-cc/src/scala/collection/mutable/ArrayBuffer.scala diff --git a/tests/pos-special/stdlib/collection/mutable/ArrayBuilder.scala b/scala2-library-cc/src/scala/collection/mutable/ArrayBuilder.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ArrayBuilder.scala rename to scala2-library-cc/src/scala/collection/mutable/ArrayBuilder.scala diff --git a/tests/pos-special/stdlib/collection/mutable/ArrayDeque.scala b/scala2-library-cc/src/scala/collection/mutable/ArrayDeque.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ArrayDeque.scala rename to scala2-library-cc/src/scala/collection/mutable/ArrayDeque.scala diff --git a/tests/pos-special/stdlib/collection/mutable/ArraySeq.scala b/scala2-library-cc/src/scala/collection/mutable/ArraySeq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ArraySeq.scala rename to scala2-library-cc/src/scala/collection/mutable/ArraySeq.scala diff --git a/tests/pos-special/stdlib/collection/mutable/BitSet.scala b/scala2-library-cc/src/scala/collection/mutable/BitSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/BitSet.scala rename to scala2-library-cc/src/scala/collection/mutable/BitSet.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Buffer.scala b/scala2-library-cc/src/scala/collection/mutable/Buffer.scala similarity index 99% rename from tests/pos-special/stdlib/collection/mutable/Buffer.scala rename to scala2-library-cc/src/scala/collection/mutable/Buffer.scala index 1f7fc76972a2..f9aa9cf28c72 100644 --- a/tests/pos-special/stdlib/collection/mutable/Buffer.scala +++ b/scala2-library-cc/src/scala/collection/mutable/Buffer.scala @@ -104,7 +104,6 @@ trait Buffer[A] @throws[IndexOutOfBoundsException] @throws[IllegalArgumentException] def remove(idx: Int, count: Int): Unit - /** Removes a single element from this buffer, at its first occurrence. * If the buffer does not contain that element, it is unchanged. * diff --git a/tests/pos-special/stdlib/collection/mutable/Builder.scala b/scala2-library-cc/src/scala/collection/mutable/Builder.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Builder.scala rename to scala2-library-cc/src/scala/collection/mutable/Builder.scala diff --git a/tests/pos-special/stdlib/collection/mutable/CheckedIndexedSeqView.scala b/scala2-library-cc/src/scala/collection/mutable/CheckedIndexedSeqView.scala similarity index 99% rename from tests/pos-special/stdlib/collection/mutable/CheckedIndexedSeqView.scala rename to scala2-library-cc/src/scala/collection/mutable/CheckedIndexedSeqView.scala index 152b6cc9ffc7..9ce0399e0662 100644 --- a/tests/pos-special/stdlib/collection/mutable/CheckedIndexedSeqView.scala +++ b/scala2-library-cc/src/scala/collection/mutable/CheckedIndexedSeqView.scala @@ -16,7 +16,6 @@ package mutable import language.experimental.captureChecking private[mutable] trait CheckedIndexedSeqView[+A] extends IndexedSeqView[A] { - this: CheckedIndexedSeqView[A]^ => protected val mutationCount: () => Int diff --git a/tests/pos-special/stdlib/collection/mutable/Cloneable.scala b/scala2-library-cc/src/scala/collection/mutable/Cloneable.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Cloneable.scala rename to scala2-library-cc/src/scala/collection/mutable/Cloneable.scala diff --git a/tests/pos-special/stdlib/collection/mutable/CollisionProofHashMap.scala b/scala2-library-cc/src/scala/collection/mutable/CollisionProofHashMap.scala similarity index 95% rename from tests/pos-special/stdlib/collection/mutable/CollisionProofHashMap.scala rename to scala2-library-cc/src/scala/collection/mutable/CollisionProofHashMap.scala index 0679ab7be201..ff3bab1dd818 100644 --- a/tests/pos-special/stdlib/collection/mutable/CollisionProofHashMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/CollisionProofHashMap.scala @@ -33,7 +33,7 @@ import language.experimental.captureChecking * @define mayNotTerminateInf * @define willNotTerminateInf */ -final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double)(implicit ordering: Ordering[K]) +final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Double)(implicit ordering: Ordering[K]) extends AbstractMap[K, V] with MapOps[K, V, Map, CollisionProofHashMap[K, V]] //-- with StrictOptimizedIterableOps[(K, V), Iterable, CollisionProofHashMap[K, V]] @@ -744,17 +744,17 @@ final class CollisionProofHashMap[K, V](initialCapacity: Int, loadFactor: Doubl object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { private[collection] final val ordMsg = "No implicit Ordering[${K2}] found to build a CollisionProofHashMap[${K2}, ${V2}]. You may want to upcast to a Map[${K}, ${V}] first by calling `unsorted`." - def from[K : Ordering, V](it: scala.collection.IterableOnce[(K, V)]^): CollisionProofHashMap[K, V] = { + def from[K : Ordering, V](it: scala.collection.IterableOnce[(K, V)]^): CollisionProofHashMap[K, V] = { val k = it.knownSize val cap = if(k > 0) ((k + 1).toDouble / defaultLoadFactor).toInt else defaultInitialCapacity new CollisionProofHashMap[K, V](cap, defaultLoadFactor) ++= it } - def empty[K : Ordering, V]: CollisionProofHashMap[K, V] = new CollisionProofHashMap[K, V] + def empty[K : Ordering, V]: CollisionProofHashMap[K, V] = new CollisionProofHashMap[K, V] - def newBuilder[K : Ordering, V]: Builder[(K, V), CollisionProofHashMap[K, V]] = newBuilder(defaultInitialCapacity, defaultLoadFactor) + def newBuilder[K : Ordering, V]: Builder[(K, V), CollisionProofHashMap[K, V]] = newBuilder(defaultInitialCapacity, defaultLoadFactor) - def newBuilder[K : Ordering, V](initialCapacity: Int, loadFactor: Double): Builder[(K, V), CollisionProofHashMap[K, V]] = + def newBuilder[K : Ordering, V](initialCapacity: Int, loadFactor: Double): Builder[(K, V), CollisionProofHashMap[K, V]] = new GrowableBuilder[(K, V), CollisionProofHashMap[K, V]](new CollisionProofHashMap[K, V](initialCapacity, loadFactor)) { override def sizeHint(size: Int) = elems.sizeHint(size) } @@ -766,7 +766,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { final def defaultInitialCapacity: Int = 16 @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 { + 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) } @@ -789,7 +789,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { /////////////////////////// Red-Black Tree Node - final class RBNode[K, V](var key: K, var hash: Int, var value: V, var red: Boolean, var left: RBNode[K, V], var right: RBNode[K, V], var parent: RBNode[K, V]) extends Node { + final class RBNode[K, V](var key: K, var hash: Int, var value: V, var red: Boolean, var left: RBNode[K, V], var right: RBNode[K, V], var parent: RBNode[K, V]) extends Node { override def toString: String = "RBNode(" + key + ", " + hash + ", " + value + ", " + red + ", " + left + ", " + right + ")" @tailrec def getNode(k: K, h: Int)(implicit ord: Ordering[K]): RBNode[K, V] = { @@ -820,17 +820,17 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { } } - @`inline` private def leaf[A, B](key: A, hash: Int, value: B, red: Boolean, parent: RBNode[A, B]): RBNode[A, B] = + @`inline` private def leaf[A, B](key: A, hash: Int, value: B, red: Boolean, parent: RBNode[A, B]): RBNode[A, B] = new RBNode(key, hash, value, red, null, null, parent) - @tailrec private def minNodeNonNull[A, B](node: RBNode[A, B]): RBNode[A, B] = + @tailrec private def minNodeNonNull[A, B](node: RBNode[A, B]): RBNode[A, B] = if (node.left eq null) node else minNodeNonNull(node.left) /** * Returns the node that follows `node` in an in-order tree traversal. If `node` has the maximum key (and is, * therefore, the last node), this method returns `null`. */ - private def successor[A, B](node: RBNode[A, B]): RBNode[A, B] = { + private def successor[A, B](node: RBNode[A, B]): RBNode[A, B] = { if (node.right ne null) minNodeNonNull(node.right) else { var x = node @@ -843,7 +843,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { } } - private final class RBNodesIterator[A, B](tree: RBNode[A, B])(implicit @unused ord: Ordering[A]) extends AbstractIterator[RBNode[A, B]] { + private final class RBNodesIterator[A, B](tree: RBNode[A, B])(implicit @unused ord: Ordering[A]) extends AbstractIterator[RBNode[A, B]] { private[this] var nextNode: RBNode[A, B] = if(tree eq null) null else minNodeNonNull(tree) def hasNext: Boolean = nextNode ne null @@ -859,7 +859,7 @@ object CollisionProofHashMap extends SortedMapFactory[CollisionProofHashMap] { /////////////////////////// Linked List Node - private final class LLNode[K, V](var key: K, var hash: Int, var value: V, var next: LLNode[K, V]) extends Node { + private final class LLNode[K, V](var key: K, var hash: Int, var value: V, var next: LLNode[K, V]) extends Node { override def toString = s"LLNode($key, $value, $hash) -> $next" private[this] def eq(a: Any, b: Any): Boolean = diff --git a/tests/pos-special/stdlib/collection/mutable/Growable.scala b/scala2-library-cc/src/scala/collection/mutable/Growable.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Growable.scala rename to scala2-library-cc/src/scala/collection/mutable/Growable.scala diff --git a/tests/pos-special/stdlib/collection/mutable/GrowableBuilder.scala b/scala2-library-cc/src/scala/collection/mutable/GrowableBuilder.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/GrowableBuilder.scala rename to scala2-library-cc/src/scala/collection/mutable/GrowableBuilder.scala diff --git a/tests/pos-special/stdlib/collection/mutable/HashMap.scala b/scala2-library-cc/src/scala/collection/mutable/HashMap.scala similarity index 97% rename from tests/pos-special/stdlib/collection/mutable/HashMap.scala rename to scala2-library-cc/src/scala/collection/mutable/HashMap.scala index 1ba651b47819..89a9f3f186f7 100644 --- a/tests/pos-special/stdlib/collection/mutable/HashMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/HashMap.scala @@ -33,7 +33,7 @@ import language.experimental.captureChecking * @define willNotTerminateInf */ @deprecatedInheritance("HashMap will be made final; use .withDefault for the common use case of computing a default value", "2.13.0") -class HashMap[K, V](initialCapacity: Int, loadFactor: Double) +class HashMap[K, V](initialCapacity: Int, loadFactor: Double) extends AbstractMap[K, V] with MapOps[K, V, HashMap, HashMap[K, V]] with StrictOptimizedIterableOps[(K, V), Iterable, HashMap[K, V]] @@ -597,17 +597,17 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double) @SerialVersionUID(3L) object HashMap extends MapFactory[HashMap] { - def empty[K, V]: HashMap[K, V] = new HashMap[K, V] + def empty[K, V]: HashMap[K, V] = new HashMap[K, V] - def from[K, V](it: collection.IterableOnce[(K, V)]^): HashMap[K, V] = { + def from[K, V](it: collection.IterableOnce[(K, V)]^): HashMap[K, V] = { val k = it.knownSize val cap = if(k > 0) ((k + 1).toDouble / defaultLoadFactor).toInt else defaultInitialCapacity new HashMap[K, V](cap, defaultLoadFactor).addAll(it) } - def newBuilder[K, V]: Builder[(K, V), HashMap[K, V]] = newBuilder(defaultInitialCapacity, defaultLoadFactor) + def newBuilder[K, V]: Builder[(K, V), HashMap[K, V]] = newBuilder(defaultInitialCapacity, defaultLoadFactor) - def newBuilder[K, V](initialCapacity: Int, loadFactor: Double): Builder[(K, V), HashMap[K, V]] = + def newBuilder[K, V](initialCapacity: Int, loadFactor: Double): Builder[(K, V), HashMap[K, V]] = new GrowableBuilder[(K, V), HashMap[K, V]](new HashMap[K, V](initialCapacity, loadFactor)) { override def sizeHint(size: Int) = elems.sizeHint(size) } @@ -619,7 +619,7 @@ object HashMap extends MapFactory[HashMap] { final def defaultInitialCapacity: Int = 16 @SerialVersionUID(3L) - private final class DeserializationFactory[K, V](val tableLength: Int, val loadFactor: Double) extends Factory[(K, V), HashMap[K, V]] with Serializable { + private final class DeserializationFactory[K, V](val tableLength: Int, val loadFactor: Double) extends Factory[(K, V), HashMap[K, V]] with Serializable { def fromSpecific(it: IterableOnce[(K, V)]^): HashMap[K, V] = new HashMap[K, V](tableLength, loadFactor).addAll(it) def newBuilder: Builder[(K, V), HashMap[K, V]] = HashMap.newBuilder(tableLength, loadFactor) } diff --git a/tests/pos-special/stdlib/collection/mutable/HashSet.scala b/scala2-library-cc/src/scala/collection/mutable/HashSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/HashSet.scala rename to scala2-library-cc/src/scala/collection/mutable/HashSet.scala diff --git a/tests/pos-special/stdlib/collection/mutable/HashTable.scala b/scala2-library-cc/src/scala/collection/mutable/HashTable.scala similarity index 99% rename from tests/pos-special/stdlib/collection/mutable/HashTable.scala rename to scala2-library-cc/src/scala/collection/mutable/HashTable.scala index 64af941eac1f..461df6cea22c 100644 --- a/tests/pos-special/stdlib/collection/mutable/HashTable.scala +++ b/scala2-library-cc/src/scala/collection/mutable/HashTable.scala @@ -412,7 +412,7 @@ private[collection] object HashTable { /** Class used internally. */ -private[collection] trait HashEntry[A, E <: HashEntry[A, E]] { +private[collection] trait HashEntry[A, E <: HashEntry[A, E]] { val key: A var next: E = _ } diff --git a/tests/pos-special/stdlib/collection/mutable/ImmutableBuilder.scala b/scala2-library-cc/src/scala/collection/mutable/ImmutableBuilder.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ImmutableBuilder.scala rename to scala2-library-cc/src/scala/collection/mutable/ImmutableBuilder.scala diff --git a/tests/pos-special/stdlib/collection/mutable/IndexedSeq.scala b/scala2-library-cc/src/scala/collection/mutable/IndexedSeq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/IndexedSeq.scala rename to scala2-library-cc/src/scala/collection/mutable/IndexedSeq.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Iterable.scala b/scala2-library-cc/src/scala/collection/mutable/Iterable.scala similarity index 91% rename from tests/pos-special/stdlib/collection/mutable/Iterable.scala rename to scala2-library-cc/src/scala/collection/mutable/Iterable.scala index bf286157b376..0042e83dad6f 100644 --- a/tests/pos-special/stdlib/collection/mutable/Iterable.scala +++ b/scala2-library-cc/src/scala/collection/mutable/Iterable.scala @@ -19,7 +19,6 @@ trait Iterable[A] extends collection.Iterable[A] with collection.IterableOps[A, Iterable, Iterable[A]] with IterableFactoryDefaults[A, Iterable] { - this: Iterable[A]^ => override def iterableFactory: IterableFactory[Iterable] = Iterable } @@ -33,5 +32,4 @@ trait Iterable[A] object Iterable extends IterableFactory.Delegate[Iterable](ArrayBuffer) /** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */ -abstract class AbstractIterable[A] extends scala.collection.AbstractIterable[A] with Iterable[A]: - this: AbstractIterable[A]^ => +abstract class AbstractIterable[A] extends scala.collection.AbstractIterable[A] with Iterable[A] diff --git a/tests/pos-special/stdlib/collection/mutable/LinkedHashMap.scala b/scala2-library-cc/src/scala/collection/mutable/LinkedHashMap.scala similarity index 98% rename from tests/pos-special/stdlib/collection/mutable/LinkedHashMap.scala rename to scala2-library-cc/src/scala/collection/mutable/LinkedHashMap.scala index 528c39e49bdf..e3fc9d6aefd6 100644 --- a/tests/pos-special/stdlib/collection/mutable/LinkedHashMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/LinkedHashMap.scala @@ -34,7 +34,7 @@ import language.experimental.captureChecking * @define orderDependentFold */ @deprecatedInheritance("LinkedHashMap will be made final; use .withDefault for the common use case of computing a default value", "2.13.11") -class LinkedHashMap[K, V] +class LinkedHashMap[K, V] extends AbstractMap[K, V] with SeqMap[K, V] with MapOps[K, V, LinkedHashMap, LinkedHashMap[K, V]] @@ -477,20 +477,20 @@ class LinkedHashMap[K, V] @SerialVersionUID(3L) object LinkedHashMap extends MapFactory[LinkedHashMap] { - def empty[K, V] = new LinkedHashMap[K, V] + def empty[K, V] = new LinkedHashMap[K, V] - def from[K, V](it: collection.IterableOnce[(K, V)]^) = { + def from[K, V](it: collection.IterableOnce[(K, V)]^) = { val newlhm = empty[K, V] newlhm.sizeHint(it.knownSize) newlhm.addAll(it) newlhm } - def newBuilder[K, V] = new GrowableBuilder(empty[K, V]) + def newBuilder[K, V] = new GrowableBuilder(empty[K, V]) /** Class for the linked hash map entry, used internally. */ - private[mutable] final class LinkedEntry[K, V](val key: K, val hash: Int, var value: V) { + private[mutable] final class LinkedEntry[K, V](val key: K, val hash: Int, var value: V) { var earlier: LinkedEntry[K, V] = null var later: LinkedEntry[K, V] = null var next: LinkedEntry[K, V] = null diff --git a/tests/pos-special/stdlib/collection/mutable/LinkedHashSet.scala b/scala2-library-cc/src/scala/collection/mutable/LinkedHashSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/LinkedHashSet.scala rename to scala2-library-cc/src/scala/collection/mutable/LinkedHashSet.scala diff --git a/tests/pos-special/stdlib/collection/mutable/ListBuffer.scala b/scala2-library-cc/src/scala/collection/mutable/ListBuffer.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ListBuffer.scala rename to scala2-library-cc/src/scala/collection/mutable/ListBuffer.scala diff --git a/tests/pos-special/stdlib/collection/mutable/ListMap.scala b/scala2-library-cc/src/scala/collection/mutable/ListMap.scala similarity index 90% rename from tests/pos-special/stdlib/collection/mutable/ListMap.scala rename to scala2-library-cc/src/scala/collection/mutable/ListMap.scala index e4f9322050d5..26e904e271a1 100644 --- a/tests/pos-special/stdlib/collection/mutable/ListMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/ListMap.scala @@ -31,7 +31,7 @@ import language.experimental.captureChecking * @define orderDependentFold */ @deprecated("Use an immutable.ListMap assigned to a var instead of mutable.ListMap", "2.13.0") -class ListMap[K, V] +class ListMap[K, V] extends AbstractMap[K, V] with MapOps[K, V, ListMap, ListMap[K, V]] with StrictOptimizedIterableOps[(K, V), Iterable, ListMap[K, V]] @@ -77,7 +77,7 @@ class ListMap[K, V] @SerialVersionUID(3L) @deprecated("Use an immutable.ListMap assigned to a var instead of mutable.ListMap", "2.13.0") object ListMap extends MapFactory[ListMap] { - def empty[K, V]: ListMap[K, V] = new ListMap[K, V] - def from[K, V](it: IterableOnce[(K, V)]^): ListMap[K,V] = Growable.from(empty[K, V], it) - def newBuilder[K, V]: Builder[(K, V), ListMap[K,V]] = new GrowableBuilder(empty[K, V]) + def empty[K, V]: ListMap[K, V] = new ListMap[K, V] + def from[K, V](it: IterableOnce[(K, V)]^): ListMap[K,V] = Growable.from(empty[K, V], it) + def newBuilder[K, V]: Builder[(K, V), ListMap[K,V]] = new GrowableBuilder(empty[K, V]) } diff --git a/tests/pos-special/stdlib/collection/mutable/LongMap.scala b/scala2-library-cc/src/scala/collection/mutable/LongMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/LongMap.scala rename to scala2-library-cc/src/scala/collection/mutable/LongMap.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Map.scala b/scala2-library-cc/src/scala/collection/mutable/Map.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Map.scala rename to scala2-library-cc/src/scala/collection/mutable/Map.scala diff --git a/tests/pos-special/stdlib/collection/mutable/MultiMap.scala b/scala2-library-cc/src/scala/collection/mutable/MultiMap.scala similarity index 98% rename from tests/pos-special/stdlib/collection/mutable/MultiMap.scala rename to scala2-library-cc/src/scala/collection/mutable/MultiMap.scala index 93b0d6ae4d73..0b250a5548ef 100644 --- a/tests/pos-special/stdlib/collection/mutable/MultiMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/MultiMap.scala @@ -52,7 +52,7 @@ import language.experimental.captureChecking * @define Coll `MultiMap` */ @deprecated("Use a scala.collection.mutable.MultiDict in the scala-collection-contrib module", "2.13.0") -trait MultiMap[K, V] extends Map[K, Set[V]] { +trait MultiMap[K, V] extends Map[K, Set[V]] { /** Creates a new set. * * Classes that use this trait as a mixin can override this method diff --git a/tests/pos-special/stdlib/collection/mutable/MutationTracker.scala b/scala2-library-cc/src/scala/collection/mutable/MutationTracker.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/MutationTracker.scala rename to scala2-library-cc/src/scala/collection/mutable/MutationTracker.scala diff --git a/tests/pos-special/stdlib/collection/mutable/OpenHashMap.scala b/scala2-library-cc/src/scala/collection/mutable/OpenHashMap.scala similarity index 97% rename from tests/pos-special/stdlib/collection/mutable/OpenHashMap.scala rename to scala2-library-cc/src/scala/collection/mutable/OpenHashMap.scala index 978245d5bffb..d29be3ffea5e 100644 --- a/tests/pos-special/stdlib/collection/mutable/OpenHashMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/OpenHashMap.scala @@ -26,10 +26,10 @@ import language.experimental.captureChecking @SerialVersionUID(3L) object OpenHashMap extends MapFactory[OpenHashMap] { - def empty[K, V] = new OpenHashMap[K, V] - def from[K, V](it: IterableOnce[(K, V)]^): OpenHashMap[K,V] = empty ++= it + def empty[K, V] = new OpenHashMap[K, V] + def from[K, V](it: IterableOnce[(K, V)]^): OpenHashMap[K,V] = empty ++= it - def newBuilder[K, V]: Builder[(K, V), OpenHashMap[K,V]] = + def newBuilder[K, V]: Builder[(K, V), OpenHashMap[K,V]] = new GrowableBuilder[(K, V), OpenHashMap[K, V]](empty) /** A hash table entry. @@ -39,7 +39,7 @@ object OpenHashMap extends MapFactory[OpenHashMap] { * If its `key` is not the default value of type `Key`, the entry is occupied. * If the entry is occupied, `hash` contains the hash value of `key`. */ - final private class OpenEntry[Key, Value](var key: Key, + final private class OpenEntry[Key, Value](var key: Key, var hash: Int, var value: Option[Value]) @@ -62,7 +62,7 @@ object OpenHashMap extends MapFactory[OpenHashMap] { * @define willNotTerminateInf */ @deprecated("Use HashMap or one of the specialized versions (LongMap, AnyRefMap) instead of OpenHashMap", "2.13.0") -class OpenHashMap[Key, Value](initialSize : Int) +class OpenHashMap[Key, Value](initialSize : Int) extends AbstractMap[Key, Value] with MapOps[Key, Value, OpenHashMap, OpenHashMap[Key, Value]] with StrictOptimizedIterableOps[(Key, Value), Iterable, OpenHashMap[Key, Value]] diff --git a/tests/pos-special/stdlib/collection/mutable/PriorityQueue.scala b/scala2-library-cc/src/scala/collection/mutable/PriorityQueue.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/PriorityQueue.scala rename to scala2-library-cc/src/scala/collection/mutable/PriorityQueue.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Queue.scala b/scala2-library-cc/src/scala/collection/mutable/Queue.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Queue.scala rename to scala2-library-cc/src/scala/collection/mutable/Queue.scala diff --git a/tests/pos-special/stdlib/collection/mutable/RedBlackTree.scala b/scala2-library-cc/src/scala/collection/mutable/RedBlackTree.scala similarity index 93% rename from tests/pos-special/stdlib/collection/mutable/RedBlackTree.scala rename to scala2-library-cc/src/scala/collection/mutable/RedBlackTree.scala index 4e079bca3245..f808a4257eef 100644 --- a/tests/pos-special/stdlib/collection/mutable/RedBlackTree.scala +++ b/scala2-library-cc/src/scala/collection/mutable/RedBlackTree.scala @@ -32,25 +32,25 @@ private[collection] object RedBlackTree { // Therefore, while obtaining the size of the whole tree is O(1), knowing the number of entries inside a range is O(n) // on the size of the range. - final class Tree[A, B](var root: Node[A, B], var size: Int) { + final class Tree[A, B](var root: Node[A, B], var size: Int) { def treeCopy(): Tree[A, B] = new Tree(copyTree(root), size) } - final class Node[A, B](var key: A, var value: B, var red: Boolean, var left: Node[A, B], var right: Node[A, B], var parent: Node[A, B]) { + final class Node[A, B](var key: A, var value: B, var red: Boolean, var left: Node[A, B], var right: Node[A, B], var parent: Node[A, B]) { override def toString: String = "Node(" + key + ", " + value + ", " + red + ", " + left + ", " + right + ")" } object Tree { - def empty[A, B]: Tree[A, B] = new Tree(null, 0) + def empty[A, B]: Tree[A, B] = new Tree(null, 0) } object Node { - @`inline` def apply[A, B](key: A, value: B, red: Boolean, + @`inline` def apply[A, B](key: A, value: B, red: Boolean, left: Node[A, B], right: Node[A, B], parent: Node[A, B]): Node[A, B] = new Node(key, value, red, left, right, parent) - @`inline` def leaf[A, B](key: A, value: B, red: Boolean, parent: Node[A, B]): Node[A, B] = + @`inline` def leaf[A, B](key: A, value: B, red: Boolean, parent: Node[A, B]): Node[A, B] = new Node(key, value, red, null, null, parent) def unapply[A, B](t: Node[A, B]) = Some((t.key, t.value, t.left, t.right, t.parent)) @@ -181,7 +181,7 @@ private[collection] object RedBlackTree { // ---- insertion ---- - def insert[A, B](tree: Tree[A, B], key: A, value: B)(implicit ord: Ordering[A]): Unit = { + def insert[A, B](tree: Tree[A, B], key: A, value: B)(implicit ord: Ordering[A]): Unit = { var y: Node[A, B] = null var x = tree.root var cmp = 1 @@ -477,16 +477,16 @@ private[collection] object RedBlackTree { if (node.right ne null) transformNodeNonNull(node.right, f) } - def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[(A, B)] = + def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[(A, B)] = new EntriesIterator(tree, start, end) def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None, end: Option[A] = None): Iterator[A] = new KeysIterator(tree, start, end) - def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[B] = + def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[B] = new ValuesIterator(tree, start, end) - private[this] abstract class TreeIterator[A, B, R](tree: Tree[A, B], start: Option[A], end: Option[A]) + private[this] abstract class TreeIterator[A, B, R](tree: Tree[A, B], start: Option[A], end: Option[A]) (implicit ord: Ordering[A]) extends AbstractIterator[R] { protected def nextResult(node: Node[A, B]): R @@ -514,19 +514,19 @@ private[collection] object RedBlackTree { setNullIfAfterEnd() } - private[this] final class EntriesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) + private[this] final class EntriesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) extends TreeIterator[A, B, (A, B)](tree, start, end) { def nextResult(node: Node[A, B]) = (node.key, node.value) } - private[this] final class KeysIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) + private[this] final class KeysIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) extends TreeIterator[A, B, A](tree, start, end) { def nextResult(node: Node[A, B]) = node.key } - private[this] final class ValuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) + private[this] final class ValuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A]) extends TreeIterator[A, B, B](tree, start, end) { def nextResult(node: Node[A, B]) = node.value @@ -623,7 +623,7 @@ private[collection] object RedBlackTree { } /** Build a Tree suitable for a TreeMap from an ordered sequence of key/value pairs */ - def fromOrderedEntries[A, B](xs: Iterator[(A, B)], size: Int): Tree[A, B] = { + def fromOrderedEntries[A, B](xs: Iterator[(A, B)], size: Int): Tree[A, B] = { val maxUsedDepth = 32 - Integer.numberOfLeadingZeros(size) // maximum depth of non-leaf nodes def f(level: Int, size: Int): Node[A, B] = size match { case 0 => null @@ -643,7 +643,7 @@ private[collection] object RedBlackTree { new Tree(f(1, size), size) } - def copyTree[A, B](n: Node[A, B]): Node[A, B] = + def copyTree[A, B](n: Node[A, B]): Node[A, B] = if(n eq null) null else { val c = new Node(n.key, n.value, n.red, copyTree(n.left), copyTree(n.right), null) if(c.left != null) c.left.parent = c diff --git a/tests/pos-special/stdlib/collection/mutable/ReusableBuilder.scala b/scala2-library-cc/src/scala/collection/mutable/ReusableBuilder.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/ReusableBuilder.scala rename to scala2-library-cc/src/scala/collection/mutable/ReusableBuilder.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Seq.scala b/scala2-library-cc/src/scala/collection/mutable/Seq.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Seq.scala rename to scala2-library-cc/src/scala/collection/mutable/Seq.scala diff --git a/tests/pos-special/stdlib/collection/mutable/SeqMap.scala b/scala2-library-cc/src/scala/collection/mutable/SeqMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/SeqMap.scala rename to scala2-library-cc/src/scala/collection/mutable/SeqMap.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Set.scala b/scala2-library-cc/src/scala/collection/mutable/Set.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Set.scala rename to scala2-library-cc/src/scala/collection/mutable/Set.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Shrinkable.scala b/scala2-library-cc/src/scala/collection/mutable/Shrinkable.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Shrinkable.scala rename to scala2-library-cc/src/scala/collection/mutable/Shrinkable.scala diff --git a/tests/pos-special/stdlib/collection/mutable/SortedMap.scala b/scala2-library-cc/src/scala/collection/mutable/SortedMap.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/SortedMap.scala rename to scala2-library-cc/src/scala/collection/mutable/SortedMap.scala diff --git a/tests/pos-special/stdlib/collection/mutable/SortedSet.scala b/scala2-library-cc/src/scala/collection/mutable/SortedSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/SortedSet.scala rename to scala2-library-cc/src/scala/collection/mutable/SortedSet.scala diff --git a/tests/pos-special/stdlib/collection/mutable/Stack.scala b/scala2-library-cc/src/scala/collection/mutable/Stack.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/Stack.scala rename to scala2-library-cc/src/scala/collection/mutable/Stack.scala diff --git a/tests/pos-special/stdlib/collection/mutable/StringBuilder.scala b/scala2-library-cc/src/scala/collection/mutable/StringBuilder.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/StringBuilder.scala rename to scala2-library-cc/src/scala/collection/mutable/StringBuilder.scala diff --git a/tests/pos-special/stdlib/collection/mutable/TreeMap.scala b/scala2-library-cc/src/scala/collection/mutable/TreeMap.scala similarity index 96% rename from tests/pos-special/stdlib/collection/mutable/TreeMap.scala rename to scala2-library-cc/src/scala/collection/mutable/TreeMap.scala index dbb87a950d74..d36e1b9d207d 100644 --- a/tests/pos-special/stdlib/collection/mutable/TreeMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/TreeMap.scala @@ -29,7 +29,7 @@ import language.experimental.captureChecking * @define Coll mutable.TreeMap * @define coll mutable tree map */ -sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: Ordering[K]) +sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: Ordering[K]) extends AbstractMap[K, V] with SortedMap[K, V] with SortedMapOps[K, V, TreeMap, TreeMap[K, V]] @@ -248,11 +248,11 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: @SerialVersionUID(3L) object TreeMap extends SortedMapFactory[TreeMap] { - def from[K : Ordering, V](it: IterableOnce[(K, V)]^): TreeMap[K, V] = + def from[K : Ordering, V](it: IterableOnce[(K, V)]^): TreeMap[K, V] = Growable.from(empty[K, V], it) - def empty[K : Ordering, V]: TreeMap[K, V] = new TreeMap[K, V]() + def empty[K : Ordering, V]: TreeMap[K, V] = new TreeMap[K, V]() - def newBuilder[K: Ordering, V]: Builder[(K, V), TreeMap[K, V]] = new GrowableBuilder(empty[K, V]) + def newBuilder[K: Ordering, V]: Builder[(K, V), TreeMap[K, V]] = new GrowableBuilder(empty[K, V]) } diff --git a/tests/pos-special/stdlib/collection/mutable/TreeSet.scala b/scala2-library-cc/src/scala/collection/mutable/TreeSet.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/TreeSet.scala rename to scala2-library-cc/src/scala/collection/mutable/TreeSet.scala diff --git a/tests/pos-special/stdlib/collection/mutable/UnrolledBuffer.scala b/scala2-library-cc/src/scala/collection/mutable/UnrolledBuffer.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/UnrolledBuffer.scala rename to scala2-library-cc/src/scala/collection/mutable/UnrolledBuffer.scala diff --git a/tests/pos-special/stdlib/collection/mutable/WeakHashMap.scala b/scala2-library-cc/src/scala/collection/mutable/WeakHashMap.scala similarity index 83% rename from tests/pos-special/stdlib/collection/mutable/WeakHashMap.scala rename to scala2-library-cc/src/scala/collection/mutable/WeakHashMap.scala index 1f94281a0b59..1ccd36c3e25f 100644 --- a/tests/pos-special/stdlib/collection/mutable/WeakHashMap.scala +++ b/scala2-library-cc/src/scala/collection/mutable/WeakHashMap.scala @@ -34,7 +34,7 @@ import language.experimental.captureChecking * @define willNotTerminateInf */ @SerialVersionUID(3L) -class WeakHashMap[K, V] extends JMapWrapper[K, V](new java.util.WeakHashMap) +class WeakHashMap[K, V] extends JMapWrapper[K, V](new java.util.WeakHashMap) with JMapWrapperLike[K, V, WeakHashMap, WeakHashMap[K, V]] with MapFactoryDefaults[K, V, WeakHashMap, Iterable] { override def empty = new WeakHashMap[K, V] @@ -49,8 +49,8 @@ class WeakHashMap[K, V] extends JMapWrapper[K, V](new java.util.WeakHashMap) */ @SerialVersionUID(3L) object WeakHashMap extends MapFactory[WeakHashMap] { - def empty[K, V]: WeakHashMap[K,V] = new WeakHashMap[K, V] - def from[K, V](it: collection.IterableOnce[(K, V)]^): WeakHashMap[K,V] = Growable.from(empty[K, V], it) - def newBuilder[K, V]: Builder[(K, V), WeakHashMap[K,V]] = new GrowableBuilder(WeakHashMap.empty[K, V]) + def empty[K, V]: WeakHashMap[K,V] = new WeakHashMap[K, V] + def from[K, V](it: collection.IterableOnce[(K, V)]^): WeakHashMap[K,V] = Growable.from(empty[K, V], it) + def newBuilder[K, V]: Builder[(K, V), WeakHashMap[K,V]] = new GrowableBuilder(WeakHashMap.empty[K, V]) } diff --git a/tests/pos-special/stdlib/collection/mutable/package.scala b/scala2-library-cc/src/scala/collection/mutable/package.scala similarity index 100% rename from tests/pos-special/stdlib/collection/mutable/package.scala rename to scala2-library-cc/src/scala/collection/mutable/package.scala diff --git a/tests/pos-special/stdlib/collection/package.scala b/scala2-library-cc/src/scala/collection/package.scala similarity index 100% rename from tests/pos-special/stdlib/collection/package.scala rename to scala2-library-cc/src/scala/collection/package.scala diff --git a/scala2-library-cc/src/scala/language.scala b/scala2-library-cc/src/scala/language.scala new file mode 100644 index 000000000000..757b9dac1076 --- /dev/null +++ b/scala2-library-cc/src/scala/language.scala @@ -0,0 +1,213 @@ +/* + * 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 + +/** + * The `scala.language` object controls the language features available to the programmer, as proposed in the + * [[https://docs.google.com/document/d/1nlkvpoIRkx7at1qJEZafJwthZ3GeIklTFhqmXMvTX9Q/edit '''SIP-18 document''']]. + * + * Each of these features has to be explicitly imported into the current scope to become available: + * {{{ + * import language.postfixOps // or language._ + * List(1, 2, 3) reverse + * }}} + * + * The language features are: + * - [[dynamics `dynamics`]] enables defining calls rewriting using the [[scala.Dynamic `Dynamic`]] trait + * - [[existentials `existentials`]] enables writing existential types + * - [[higherKinds `higherKinds`]] enables writing higher-kinded types + * - [[implicitConversions `implicitConversions`]] enables defining implicit methods and members + * - [[postfixOps `postfixOps`]] enables postfix operators (not recommended) + * - [[reflectiveCalls `reflectiveCalls`]] enables using structural types + * - [[experimental `experimental`]] contains newer features that have not yet been tested in production + * + * @groupname production Language Features + * @groupname experimental Experimental Language Features + * @groupprio experimental 10 + */ +object language { + + import languageFeature._ + + /** Only where this feature is enabled, can direct or indirect subclasses of trait scala.Dynamic + * be defined. If `dynamics` is not enabled, a definition of a class, trait, + * or object that has `Dynamic` as a base trait is rejected by the compiler. + * + * Selections of dynamic members of existing subclasses of trait `Dynamic` are unaffected; + * they can be used anywhere. + * + * '''Why introduce the feature?''' To enable flexible DSLs and convenient interfacing + * with dynamic languages. + * + * '''Why control it?''' Dynamic member selection can undermine static checkability + * of programs. Furthermore, dynamic member selection often relies on reflection, + * which is not available on all platforms. + * + * @group production + */ + implicit lazy val dynamics: dynamics = languageFeature.dynamics + + /** Only where this feature is enabled, is postfix operator notation `(expr op)` permitted. + * If `postfixOps` is not enabled, an expression using postfix notation is rejected by the compiler. + * + * '''Why keep the feature?''' Postfix notation is preserved for backward + * compatibility only. Historically, several DSLs written in Scala need the notation. + * + * '''Why control it?''' Postfix operators interact poorly with semicolon inference. + * Most programmers avoid them for this reason alone. Postfix syntax is + * associated with an abuse of infix notation, `a op1 b op2 c op3`, + * that can be harder to read than ordinary method invocation with judicious + * use of parentheses. It is recommended not to enable this feature except for + * legacy code. + * + * @group production + */ + implicit lazy val postfixOps: postfixOps = languageFeature.postfixOps + + /** Where this feature is enabled, accesses to members of structural types that need + * reflection are supported. If `reflectiveCalls` is not enabled, an expression + * requiring reflection will trigger a warning from the compiler. + * + * A structural type is a type of the form + * `Parents { Decls }` where `Decls` contains declarations of new members that do + * not override any member in `Parents`. To access one of these members, a + * reflective call is needed. + * + * '''Why keep the feature?''' Structural types provide great flexibility because + * they avoid the need to define inheritance hierarchies a priori. Besides, + * their definition falls out quite naturally from Scala’s concept of type refinement. + * + * '''Why control it?''' Reflection is not available on all platforms. Popular tools + * such as ProGuard have problems dealing with it. Even where reflection is available, + * reflective dispatch can lead to surprising performance degradations. + * + * @group production + */ + implicit lazy val reflectiveCalls: reflectiveCalls = languageFeature.reflectiveCalls + + /** Where this feature is enabled, definitions of implicit conversions are allowed. + * If `implicitConversions` is not enabled, the definition of an implicit + * conversion will trigger a warning from the compiler. + * + * An implicit conversion is an implicit value of unary function type `A => B`, + * or an implicit method that has in its first parameter section a single, + * non-implicit parameter. Examples: + * + * {{{ + * implicit def stringToInt(s: String): Int = s.length + * implicit val conv = (s: String) => s.length + * implicit def listToX(xs: List[T])(implicit f: T => X): X = ... + * }}} + * + * Implicit classes and implicit values of other types are not governed by this + * language feature. + * + * '''Why keep the feature?''' Implicit conversions are central to many aspects + * of Scala’s core libraries. + * + * '''Why control it?''' Implicit conversions are known to cause many pitfalls + * if over-used. And there is a tendency to over-use them because they look + * very powerful and their effects seem to be easy to understand. Also, in + * most situations using implicit parameters leads to a better design than + * implicit conversions. + * + * @group production + */ + implicit lazy val implicitConversions: implicitConversions = languageFeature.implicitConversions + + /** Where this feature is enabled, higher-kinded types can be written. + * If `higherKinds` is not enabled, a higher-kinded type such as `F[A]` + * will trigger a warning from the compiler. + * + * '''Why keep the feature?''' Higher-kinded types enable the definition of very general + * abstractions such as functor, monad, or arrow. A significant set of advanced + * libraries relies on them. Higher-kinded types are also at the core of the + * scala-virtualized effort to produce high-performance parallel DSLs through staging. + * + * '''Why control it?''' Higher kinded types in Scala lead to a Turing-complete + * type system, where compiler termination is no longer guaranteed. They tend + * to be useful mostly for type-level computation and for highly generic design + * patterns. The level of abstraction implied by these design patterns is often + * a barrier to understanding for newcomers to a Scala codebase. Some syntactic + * aspects of higher-kinded types are hard to understand for the uninitiated and + * type inference is less effective for them than for normal types. Because we are + * not completely happy with them yet, it is possible that some aspects of + * higher-kinded types will change in future versions of Scala. So an explicit + * enabling also serves as a warning that code involving higher-kinded types + * might have to be slightly revised in the future. + * + * @group production + */ + @deprecated("higherKinds no longer needs to be imported explicitly", "2.13.1") + implicit lazy val higherKinds: higherKinds = languageFeature.higherKinds + + /** Where this feature is enabled, existential types that cannot be expressed as wildcard + * types can be written and are allowed in inferred types of values or return + * types of methods. If `existentials` is not enabled, those cases will trigger + * a warning from the compiler. + * + * Existential types with wildcard type syntax such as `List[_]`, + * or `Map[String, _]` are not affected. + * + * '''Why keep the feature?''' Existential types are needed to make sense of Java’s wildcard + * types and raw types and the erased types of run-time values. + * + * '''Why control it?''' Having complex existential types in a code base usually makes + * application code very brittle, with a tendency to produce type errors with + * obscure error messages. Therefore, going overboard with existential types + * is generally perceived not to be a good idea. Also, complicated existential types + * might be no longer supported in a future simplification of the language. + * + * @group production + */ + implicit lazy val existentials: existentials = languageFeature.existentials + + /** The experimental object contains features that are known to have unstable API or + * behavior that may change in future releases. + * + * Experimental features '''may undergo API changes''' in future releases, so production + * code should not rely on them. + * + * Programmers are encouraged to try out experimental features and + * [[https://github.com/scala/bug/issues report any bugs or API inconsistencies]] + * they encounter so they can be improved in future releases. + * + * @group experimental + */ + object experimental { + + import languageFeature.experimental._ + + /** Experimental support for capture checking; implies support for pureFunctions + * + * @see [[https://dotty.epfl.ch/docs/reference/experimental/cc]] + */ + implicit lazy val captureChecking: existentials = languageFeature.existentials + + /** Only where this feature is enabled, are macro definitions allowed. + * If `macros` is not enabled, macro definitions are rejected by the compiler. + * + * Macro implementations and macro applications are not governed by this + * language feature; they can be used anywhere. + * + * '''Why introduce the feature?''' Macros promise to make the language more regular, + * replacing ad-hoc language constructs with a general powerful abstraction + * capability that can express them. Macros are also a more disciplined and + * powerful replacement for compiler plugins. + * + * '''Why control it?''' For their very power, macros can lead to code that is hard + * to debug and understand. + */ + implicit lazy val macros: macros = languageFeature.experimental.macros + } +} diff --git a/tests/pos-special/stdlib/runtime/PStatics.scala b/scala2-library-cc/src/scala/runtime/PStatics.scala similarity index 100% rename from tests/pos-special/stdlib/runtime/PStatics.scala rename to scala2-library-cc/src/scala/runtime/PStatics.scala diff --git a/scaladoc-testcases/src/tests/abstractmembersignatures.scala b/scaladoc-testcases/src/tests/abstractmembersignatures.scala index a32336d8f76d..60ae99b87461 100644 --- a/scaladoc-testcases/src/tests/abstractmembersignatures.scala +++ b/scaladoc-testcases/src/tests/abstractmembersignatures.scala @@ -9,6 +9,8 @@ trait TestTrait: class TestClass: def shouldBeConcrete: Int = 1 +abstract class TestInheritedAbstractMembers extends TestTrait + abstract class AbstractTestClass: def shouldBeAbstract: Int def shouldBeConcrete: Int = 1 diff --git a/scaladoc-testcases/src/tests/enumSignatures.scala b/scaladoc-testcases/src/tests/enumSignatures.scala index 70bb25728ebb..b120a62ef4c3 100644 --- a/scaladoc-testcases/src/tests/enumSignatures.scala +++ b/scaladoc-testcases/src/tests/enumSignatures.scala @@ -4,14 +4,14 @@ package enumSignatures enum Enum1 { - case A - case B - case C + case A //expected: case A extends Enum1 + case B //expected: case B extends Enum1 + case C //expected: case C extends Enum1 } enum Enum2(val i: Int): - case A(s: String) extends Enum2/*<-*/(1)/*->*/ - case B(t: String) extends Enum2/*<-*/(2)/*->*/ - case C(u: String) extends Enum2/*<-*/(3)/*->*/ + case A(s: String) extends Enum2(1) //expected: final case class A(s: String) extends Enum2 + case B(t: String) extends Enum2(2) //expected: final case class B(t: String) extends Enum2 + case C(u: String) extends Enum2(3) //expected: final case class C(u: String) extends Enum2 enum Enum3(val param: Int): case A extends Enum3/*<-*/(1)/*->*/ with A @@ -19,9 +19,9 @@ enum Enum3(val param: Int): case C extends Enum3/*<-*/(3)/*->*/ enum Enum4[+T]: - case G(s: String) + case G(s: String) //expected: final case class G[+T](s: String) case B extends Enum4[Int] with A - case C[V](s: String) extends Enum4[V] - case D[T](s: String) extends Enum4[T] + case C[V](s: String) extends Enum4[V] //expected: final case class C[V](s: String) extends Enum4[V] + case D[T](s: String) extends Enum4[T] //expected: final case class D[T](s: String) extends Enum4[T] trait A \ No newline at end of file diff --git a/scaladoc-testcases/src/tests/nonScala3Parent.scala b/scaladoc-testcases/src/tests/nonScala3Parent.scala index 91183d25b583..c5a29b2d6132 100644 --- a/scaladoc-testcases/src/tests/nonScala3Parent.scala +++ b/scaladoc-testcases/src/tests/nonScala3Parent.scala @@ -4,7 +4,7 @@ package nonScala3Parent import javax.swing.JPanel import javax.swing.JFrame -// https://github.com/lampepfl/dotty/issues/15927 +// https://github.com/scala/scala3/issues/15927 trait Foo1 extends Numeric[Any] trait Foo2 extends JPanel diff --git a/scaladoc/resources/dotty_res/scripts/ux.js b/scaladoc/resources/dotty_res/scripts/ux.js index dd6e798f17a5..7b875fbcef8e 100644 --- a/scaladoc/resources/dotty_res/scripts/ux.js +++ b/scaladoc/resources/dotty_res/scripts/ux.js @@ -4,6 +4,8 @@ const attrsToCopy = [ "data-githubContributorsUrl", "data-githubContributorsFilename", "data-pathToRoot", + "data-rawLocation", + "data-dynamicSideMenu", ] /** @@ -25,7 +27,7 @@ function savePageState(doc) { } return { mainDiv: doc.querySelector("#main")?.innerHTML, - leftColumn: doc.querySelector("#leftColumn").innerHTML, + leftColumn: dynamicSideMenu ? null : doc.querySelector("#leftColumn").innerHTML, title: doc.title, attrs, }; @@ -38,12 +40,15 @@ function savePageState(doc) { function loadPageState(doc, saved) { doc.title = saved.title; doc.querySelector("#main").innerHTML = saved.mainDiv; - doc.querySelector("#leftColumn").innerHTML = saved.leftColumn; + if (!dynamicSideMenu) + doc.querySelector("#leftColumn").innerHTML = saved.leftColumn; for (const attr of attrsToCopy) { doc.documentElement.setAttribute(attr, saved.attrs[attr]); } } +const attachedElements = new WeakSet() + function attachAllListeners() { if (observer) { observer.disconnect(); @@ -97,19 +102,19 @@ function attachAllListeners() { } } -document - .querySelectorAll(".documentableElement .signature") - .forEach((signature) => { - const short = signature.querySelector(".signature-short"); - const long = signature.querySelector(".signature-long"); - const extender = document.createElement("span"); - const extenderDots = document.createTextNode("..."); - extender.appendChild(extenderDots); - extender.classList.add("extender"); - if (short && long && signature.children[1].hasChildNodes()) { - signature.children[0].append(extender); - } - }); + document + .querySelectorAll(".documentableElement .signature") + .forEach((signature) => { + const short = signature.querySelector(".signature-short"); + const long = signature.querySelector(".signature-long"); + const extender = document.createElement("span"); + const extenderDots = document.createTextNode("..."); + extender.appendChild(extenderDots); + extender.classList.add("extender"); + if (short && long && signature.children[1].hasChildNodes()) { + signature.children[0].append(extender); + } + }); const documentableLists = document.getElementsByClassName("documentableList"); [...documentableLists].forEach((list) => { @@ -151,6 +156,8 @@ document return; } const url = new URL(href); + if (attachedElements.has(el)) return; + attachedElements.add(el); el.addEventListener("click", (e) => { if ( url.href.replace(/#.*/, "") === window.location.href.replace(/#.*/, "") @@ -166,6 +173,7 @@ document e.preventDefault(); e.stopPropagation(); $.get(href, function (data) { + const oldLoc = getRawLoc(); if (window.history.state === null) { window.history.replaceState(savePageState(document), ""); } @@ -174,6 +182,11 @@ document const state = savePageState(parsedDocument); window.history.pushState(state, "", href); loadPageState(document, state); + const newLoc = getRawLoc(); + if (dynamicSideMenu) { + updateMenu(oldLoc, newLoc); + } + window.dispatchEvent(new Event(DYNAMIC_PAGE_LOAD)); document .querySelector("#main") @@ -182,11 +195,15 @@ document }); }); - $(".ar").on("click", function (e) { - $(this).parent().parent().toggleClass("expanded"); - $(this).toggleClass("expanded"); - e.stopPropagation(); - }); + document.querySelectorAll('.ar').forEach((el) => { + if (attachedElements.has(el)) return; + attachedElements.add(el); + el.addEventListener('click', (e) => { + e.stopPropagation(); + el.parentElement.parentElement.classList.toggle("expanded"); + el.classList.toggle("expanded"); + }) + }) document.querySelectorAll(".documentableList .ar").forEach((arrow) => { arrow.addEventListener("click", () => { @@ -195,7 +212,9 @@ document }); }); - document.querySelectorAll(".nh").forEach((el) => + document.querySelectorAll(".nh").forEach((el) => { + if (attachedElements.has(el)) return; + attachedElements.add(el); el.addEventListener("click", () => { if ( el.lastChild.href.replace("#", "") === @@ -206,8 +225,8 @@ document } else { el.lastChild.click(); } - }), - ); + }); + }); const toggleShowAllElem = (element) => { if (element.textContent == "Show all") { @@ -345,7 +364,7 @@ window.addEventListener(DYNAMIC_PAGE_LOAD, () => { attachAllListeners(); }); -window.addEventListener("dynamicPageLoad", () => { +window.addEventListener(DYNAMIC_PAGE_LOAD, () => { const sideMenuOpen = sessionStorage.getItem("sideMenuOpen"); if (sideMenuOpen) { if (document.querySelector("#leftColumn").classList.contains("show")) { @@ -365,10 +384,136 @@ window.addEventListener("dynamicPageLoad", () => { } }); +let dynamicSideMenu = false; +/** @param {Element} elem @param {boolean} hide */ +function updatePath(elem, hide, first = true) { + if (elem.classList.contains("side-menu")) return; + const span = elem.firstElementChild + const btn = span.firstElementChild + if (hide) { + elem.classList.remove("expanded"); + span.classList.remove("h100", "selected", "expanded", "cs"); + if (btn) btn.classList.remove("expanded"); + } else { + elem.classList.add("expanded"); + span.classList.add("h100", "expanded", "cs"); + if (btn) btn.classList.add("expanded"); + if (first) span.classList.add("selected"); + } + updatePath(elem.parentElement, hide, false); +} +let updateMenu = null; +function getRawLoc() { + return document.documentElement.getAttribute("data-rawLocation")?.split("/")?.filter(c => c !== ""); +} + +/** + * @template {keyof HTMLElementTagNameMap} T + * @param {T} el type of element to create + * @param {{ cls?: string | null, id?: string | null, href?: string | null }} attrs element attributes + * @param {Array<HTMLElement | string | null>} chldr element children + * @returns {HTMLElementTagNameMap[T]} + */ +function render(el, { cls = null, id = null, href = null, loc = null } = {}, chldr = []) { + const r = document.createElement(el); + if (cls) cls.split(" ").filter(x => x !== "").forEach(c => r.classList.add(c)); + if (id) r.id = id; + if (href) r.href = href; + if (loc) r.setAttribute("data-loc", loc); + chldr.filter(c => c !== null).forEach(c => + r.appendChild(typeof c === "string" ? document.createTextNode(c) : c) + ); + return r; +} +function renderDynamicSideMenu() { + const pathToRoot = document.documentElement.getAttribute("data-pathToRoot") + const path = pathToRoot + "dynamicSideMenu.json"; + const rawLocation = getRawLoc(); + const baseUrl = window.location.pathname.split("/").slice(0, + -1 - pathToRoot.split("/").filter(c => c != "").length + ); + function linkTo(loc) { + return `${baseUrl}/${loc.join("/")}.html`; + } + fetch(path).then(r => r.json()).then(menu => { + function renderNested(item, nestLevel, prefix, isApi) { + const name = item.name; + const newName = + isApi && item.kind === "package" && name.startsWith(prefix + ".") + ? name.substring(prefix.length + 1) + : name; + const newPrefix = + prefix == "" + ? newName + : prefix + "." + newName; + const chldr = + item.children.map(x => renderNested(x, nestLevel + 1, newPrefix, isApi)); + const link = render("span", { cls: `nh ${isApi ? "" : "de"}` }, [ + chldr.length ? render("button", { cls: "ar icon-button" }) : null, + render("a", { href: linkTo(item.location) }, [ + item.kind && render("span", { cls: `micon ${item.kind.slice(0, 2)}` }), + render("span", {}, [newName]), + ]), + ]); + const loc = item.location.join("/"); + const ret = render("div", { cls: `ni n${nestLevel}`, loc: item.location.join("/") }, [link, ...chldr]); + return ret; + } + const d = render("div", { cls: "switcher-container" }, [ + menu.docs && render("a", { + id: "docs-nav-button", + cls: "switcher h100", + href: linkTo(menu.docs.location) + }, ["Docs"]), + menu.api && render("a", { + id: "api-nav-button", + cls: "switcher h100", + href: linkTo(menu.api.location) + }, ["API"]), + ]); + const d1 = menu.docs && render("nav", { cls: "side-menu", id: "docs-nav" }, + menu.docs.children.map(item => renderNested(item, 0, "", false)) + ); + const d2 = menu.api && render("nav", { cls: "side-menu", id: "api-nav" }, + menu.api.children.map(item => renderNested(item, 0, "", true)) + ); + + document.getElementById("leftColumn").appendChild(d); + d1 && document.getElementById("leftColumn").appendChild(d1); + d2 && document.getElementById("leftColumn").appendChild(d2); + updateMenu = (oldLoc, newLoc) => { + if (oldLoc) { + const elem = document.querySelector(`[data-loc="${oldLoc.join("/")}"]`); + if (elem) updatePath(elem, true); + } + if (d1 && d2) { + if (newLoc[0] && newLoc[0] == menu.api.location[0]) { + d1.hidden = true; + d2.hidden = false; + } else { + d1.hidden = false; + d2.hidden = true; + } + } + const elem = document.querySelector(`[data-loc="${newLoc.join("/")}"]`); + if (elem) updatePath(elem, false) + } + updateMenu(null, rawLocation); + + window.dispatchEvent(new Event(DYNAMIC_PAGE_LOAD)); + }) +} + window.addEventListener("DOMContentLoaded", () => { hljs.registerLanguage("scala", highlightDotty); hljs.registerAliases(["dotty", "scala3"], "scala"); - window.dispatchEvent(new Event(DYNAMIC_PAGE_LOAD)); + + dynamicSideMenu = document.documentElement.getAttribute("data-dynamicSideMenu") === "true"; + if (dynamicSideMenu) { + renderDynamicSideMenu(); + } else { + window.dispatchEvent(new Event(DYNAMIC_PAGE_LOAD)); + } }); const elements = document.querySelectorAll(".documentableElement"); diff --git a/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala b/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala index 260529b024db..a2485085a927 100644 --- a/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala +++ b/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala @@ -45,7 +45,8 @@ object Scaladoc: apiSubdirectory : Boolean = false, scastieConfiguration: String = "", defaultTemplate: Option[String] = None, - quickLinks: List[QuickLink] = List.empty + quickLinks: List[QuickLink] = List.empty, + dynamicSideMenu: Boolean = false, ) def run(args: Array[String], rootContext: CompilerContext): Reporter = @@ -228,7 +229,8 @@ object Scaladoc: apiSubdirectory.get, scastieConfiguration.get, defaultTemplate.nonDefault, - quickLinksParsed + quickLinksParsed, + dynamicSideMenu.get, ) (Some(docArgs), newContext) } diff --git a/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala b/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala index 403acb19305d..4802f5d24ecc 100644 --- a/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala +++ b/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala @@ -133,5 +133,8 @@ class ScaladocSettings extends SettingGroup with AllScalaSettings: "List of quick links that is displayed in the header of documentation." ) + val dynamicSideMenu: Setting[Boolean] = + BooleanSetting("-dynamic-side-menu", "Generate side menu via JS instead of embedding it in every html file", false) + def scaladocSpecificSettings: Set[Setting[?]] = - Set(sourceLinks, legacySourceLink, syntax, revision, externalDocumentationMappings, socialLinks, skipById, skipByRegex, deprecatedSkipPackages, docRootContent, snippetCompiler, generateInkuire, defaultTemplate, scastieConfiguration, quickLinks) + Set(sourceLinks, legacySourceLink, syntax, revision, externalDocumentationMappings, socialLinks, skipById, skipByRegex, deprecatedSkipPackages, docRootContent, snippetCompiler, generateInkuire, defaultTemplate, scastieConfiguration, quickLinks, dynamicSideMenu) diff --git a/scaladoc/src/dotty/tools/scaladoc/api.scala b/scaladoc/src/dotty/tools/scaladoc/api.scala index 159db2ecaf7b..8ff40644fac2 100644 --- a/scaladoc/src/dotty/tools/scaladoc/api.scala +++ b/scaladoc/src/dotty/tools/scaladoc/api.scala @@ -60,7 +60,7 @@ enum Kind(val name: String): case Trait(override val typeParams: Seq[TypeParameter], override val argsLists: Seq[TermParameterList]) extends Kind("trait") with Classlike case Enum(override val typeParams: Seq[TypeParameter], override val argsLists: Seq[TermParameterList]) extends Kind("enum") with Classlike - case EnumCase(kind: Object.type | Kind.Type | Val.type | Class) extends Kind("case") + case EnumCase(kind: Object.type | Kind.Type | Val.type | Class) extends Kind(kind.name) case Def(paramLists: Seq[Either[TermParameterList,TypeParameterList]]) extends Kind("def") case Extension(on: ExtensionTarget, m: Kind.Def) extends Kind("def") @@ -146,9 +146,9 @@ case class HierarchyGraph(edges: Seq[(LinkToType, LinkToType)], sealedNodes: Set def vertecies: Seq[LinkToType] = edges.flatten((a, b) => Seq(a, b)).distinct def verteciesWithId: Map[LinkToType, Int] = vertecies.zipWithIndex.toMap def +(edge: (LinkToType, LinkToType)): HierarchyGraph = this ++ Seq(edge) - def ++(edges: Seq[(LinkToType, LinkToType)]): HierarchyGraph = + def ++(edges: Seq[(LinkToType, LinkToType)]): HierarchyGraph = this.copy(edges = this.edges.view.concat(edges).distinct.toSeq) - + object HierarchyGraph: def empty = HierarchyGraph(Seq.empty) def withEdges(edges: Seq[(LinkToType, LinkToType)]) = HierarchyGraph.empty ++ edges diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala index 20f3335a44ef..7dff3e5637c6 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala @@ -31,6 +31,8 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do case _ => Nil case _ => Nil) :+ (Attr("data-pathToRoot") := pathToRoot(page.link.dri)) + :+ (Attr("data-rawLocation") := rawLocation(page.link.dri).mkString("/")) + :+ (Attr("data-dynamicSideMenu") := ctx.args.dynamicSideMenu.toString) val htmlTag = html(attrs*)( head((mkHead(page) :+ docHead)*), @@ -46,8 +48,35 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do override def render(): Unit = val renderedResources = renderResources() + if ctx.args.dynamicSideMenu then serializeSideMenu() super.render() + private def serializeSideMenu() = + import com.fasterxml.jackson.databind.* + import com.fasterxml.jackson.databind.node.ObjectNode + import com.fasterxml.jackson.databind.node.TextNode + val mapper = new ObjectMapper(); + + def serializePage(page: Page): ObjectNode = + import scala.jdk.CollectionConverters.SeqHasAsJava + val children = mapper.createArrayNode().addAll(page.children.filterNot(_.hidden).map(serializePage).asJava) + val location = mapper.createArrayNode().addAll(rawLocation(page.link.dri).map(TextNode(_)).asJava) + val obj = mapper.createObjectNode() + obj.set("name", new TextNode(page.link.name)) + obj.set("location", location) + obj.set("kind", page.content match + case m: Member if m.needsOwnPage => new TextNode(m.kind.name) + case _ => null + ) + obj.set("children", children) + obj + + val rootNode = mapper.createObjectNode() + rootNode.set("docs", rootDocsPage.map(serializePage).orNull) + rootNode.set("api", rootApiPage.map(serializePage).orNull) + val jsonString = mapper.writer().writeValueAsString(rootNode); + renderResource(Resource.Text("dynamicSideMenu.json", jsonString)) + private def renderResources(): Seq[String] = import scala.util.Using import scala.jdk.CollectionConverters._ @@ -218,7 +247,8 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do )).dropRight(1) div(cls := "breadcrumbs container")(innerTags*) - val (apiNavOpt, docsNavOpt): (Option[(Boolean, Seq[AppliedTag])], Option[(Boolean, Seq[AppliedTag])]) = buildNavigation(link) + val dynamicSideMenu = ctx.args.dynamicSideMenu + val (apiNavOpt, docsNavOpt) = if dynamicSideMenu then (None, None) else buildNavigation(link) def textFooter: String = args.projectFooter.getOrElse("") @@ -266,7 +296,7 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do ), span(id := "mobile-sidebar-toggle", cls := "floating-button"), div(id := "leftColumn", cls := "body-small")( - Seq( + if dynamicSideMenu then Nil else Seq( div(cls:= "switcher-container")( docsNavOpt match { case Some(isDocsActive, docsNav) => diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala index 612444fd4ffd..021fdb5eef37 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala @@ -323,6 +323,7 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext val (allInherited, allDefined) = nonExperimental.partition(isInherited) val (depDefined, defined) = allDefined.partition(isDeprecated) val (depInherited, inherited) = allInherited.partition(isDeprecated) + val (abstractInherited, concreteInherited) = inherited.partition(isAbstract) val normalizedName = name.toLowerCase val definedWithGroup = if Set("methods", "fields").contains(normalizedName) then val (abstr, concr) = defined.partition(isAbstract) @@ -335,7 +336,8 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext definedWithGroup ++ List( actualGroup(s"Deprecated ${normalizedName}", depDefined), - actualGroup(s"Inherited ${normalizedName}", inherited), + actualGroup(s"Inherited ${normalizedName}", concreteInherited), + actualGroup(s"Inherited and Abstract ${normalizedName}", abstractInherited), actualGroup(s"Deprecated and Inherited ${normalizedName}", depInherited), actualGroup(name = s"Experimental ${normalizedName}", experimental) ) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala index 35cf1cb6eec3..373a26dd0297 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala @@ -298,7 +298,7 @@ trait TypesSupport: } case tpe => - val msg = s"Encountered unsupported type. Report this problem to https://github.com/lampepfl/dotty/.\n" + + val msg = s"Encountered unsupported type. Report this problem to https://github.com/scala/scala3/.\n" + s"${tpe.show(using Printer.TypeReprStructure)}" throw MatchError(msg) diff --git a/scaladoc/src/dotty/tools/scaladoc/translators/ScalaSignatureProvider.scala b/scaladoc/src/dotty/tools/scaladoc/translators/ScalaSignatureProvider.scala index fd8dfc4f5b6c..a3ce15d70c64 100644 --- a/scaladoc/src/dotty/tools/scaladoc/translators/ScalaSignatureProvider.scala +++ b/scaladoc/src/dotty/tools/scaladoc/translators/ScalaSignatureProvider.scala @@ -75,7 +75,7 @@ class ScalaSignatureProvider: MemberSignature( builder.modifiersAndVisibility(entry), - builder.kind(entry.kind), + List(), builder.name(entry.name, entry.dri), builder.keyword(" extends ").signature(modifiedType) ) diff --git a/scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala b/scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala index 540364ec10bf..0c8211865928 100644 --- a/scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala @@ -27,7 +27,7 @@ abstract class ScaladocTest(val name: String): tastyFiles = tastyFiles(name), output = getTempDir().getRoot, projectVersion = Some("1.0"), - sourceLinks = List("github://lampepfl/dotty/master") + sourceLinks = List("github://scala/scala3/master") ) @Test diff --git a/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala b/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala index 824aec6daa16..72124ab2fbcc 100644 --- a/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala @@ -18,10 +18,10 @@ class AbstractMembers extends ScaladocTest("abstractmembersignatures"): def runTest = { afterRendering { val actualSignatures = signaturesFromDocumentation() - actualSignatures.foreach { (k, v) => k match case "Abstract methods" => assertTrue(v.forall(_._2 == "shouldBeAbstract")) case "Concrete methods" => assertTrue(v.forall(_._2 == "shouldBeConcrete")) + case "Inherited and Abstract methods" => assertTrue(v.forall(_._2 == "shouldBeAbstract")) case "Classlikes" => assertTrue(v.forall((m, n) => m.contains("abstract") == n.contains("Abstract"))) case _ => } diff --git a/scaladoc/test/dotty/tools/scaladoc/signatures/TranslatableSignaturesTestCases.scala b/scaladoc/test/dotty/tools/scaladoc/signatures/TranslatableSignaturesTestCases.scala index 5067bf5974ca..2b654d186aef 100644 --- a/scaladoc/test/dotty/tools/scaladoc/signatures/TranslatableSignaturesTestCases.scala +++ b/scaladoc/test/dotty/tools/scaladoc/signatures/TranslatableSignaturesTestCases.scala @@ -45,7 +45,7 @@ class ExtensionMethodParamsSignature extends SignatureTest("extensionParams", Si class ClassModifiers extends SignatureTest("classModifiers", SignatureTest.classlikeKinds) -class EnumSignatures extends SignatureTest("enumSignatures", SignatureTest.all) +class EnumSignatures extends SignatureTest("enumSignatures", "case" +: SignatureTest.all) class StructuralTypes extends SignatureTest("structuralTypes", SignatureTest.members) diff --git a/staging/src/scala/quoted/staging/Compiler.scala b/staging/src/scala/quoted/staging/Compiler.scala index 7f380dabd4e2..b37e8d4f70f2 100644 --- a/staging/src/scala/quoted/staging/Compiler.scala +++ b/staging/src/scala/quoted/staging/Compiler.scala @@ -13,15 +13,27 @@ object Compiler: /** Create a new instance of the compiler using the the classloader of the application. * - * Usage: - * ``` - * import scala.quoted.staging._ - * given Compiler = Compiler.make(getClass.getClassLoader) - * ``` + * Usage: + * ``` + * import scala.quoted.staging._ + * given Compiler = + * object Dummy + * Compiler.make(Dummy.getClass.getClassLoader) + * ``` * - * @param appClassloader classloader of the application that generated the quotes - * @param settings compiler settings - * @return A new instance of the compiler + * Note that we use an instance of `Dummy` to get the classloader that loaded the application. + * Any other instance of a class defined in the application would also work. + * Using a class defined in the standard library should be avoided as it might be loaded by a different classloader. + * + * If the given compiler is defined in one of your classes (e.i. not as a top-level definition), then + * the compiler can be instantiated with: + * ``` + * given Compiler = Compiler.make(this.getClass.getClassLoader) + * ``` + * + * @param appClassloader classloader of the application that generated the quotes + * @param settings compiler settings + * @return A new instance of the compiler */ def make(appClassloader: ClassLoader)(implicit settings: Settings): Compiler = new Compiler: diff --git a/staging/src/scala/quoted/staging/QuoteDriver.scala b/staging/src/scala/quoted/staging/QuoteDriver.scala index 93e19f195e00..e894a7bc40f2 100644 --- a/staging/src/scala/quoted/staging/QuoteDriver.scala +++ b/staging/src/scala/quoted/staging/QuoteDriver.scala @@ -53,7 +53,19 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver: val method = clazz.getMethod("apply") val inst = clazz.getConstructor().newInstance() - method.invoke(inst).asInstanceOf[T] + try method.invoke(inst).asInstanceOf[T] + catch case ex: java.lang.reflect.InvocationTargetException => + ex.getCause match + case _: java.lang.NoClassDefFoundError => + throw new Exception( + s"""`scala.quoted.staging.run` failed to load a class. + |The classloader used for the `staging.Compiler` instance might not be the correct one. + |Make sure that this classloader is the one that loaded the missing class. + |Note that the classloader that loads the standard library might not be the same as + |the one that loaded the application classes.""".stripMargin, + ex) + + case _ => throw ex end match end run diff --git a/tasty/src/dotty/tools/tasty/TastyFormat.scala b/tasty/src/dotty/tools/tasty/TastyFormat.scala index a7150dc726c7..a2f5a44a10d1 100644 --- a/tasty/src/dotty/tools/tasty/TastyFormat.scala +++ b/tasty/src/dotty/tools/tasty/TastyFormat.scala @@ -316,7 +316,7 @@ 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 = 3 diff --git a/tests/cmdTest-sbt-tests/sourcepath-with-inline-api-hash/project/build.properties b/tests/cmdTest-sbt-tests/sourcepath-with-inline-api-hash/project/build.properties index 52413ab79a18..e8a1e246e8ad 100644 --- a/tests/cmdTest-sbt-tests/sourcepath-with-inline-api-hash/project/build.properties +++ b/tests/cmdTest-sbt-tests/sourcepath-with-inline-api-hash/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.3 +sbt.version=1.9.7 diff --git a/tests/cmdTest-sbt-tests/sourcepath-with-inline/project/build.properties b/tests/cmdTest-sbt-tests/sourcepath-with-inline/project/build.properties index 52413ab79a18..e8a1e246e8ad 100644 --- a/tests/cmdTest-sbt-tests/sourcepath-with-inline/project/build.properties +++ b/tests/cmdTest-sbt-tests/sourcepath-with-inline/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.3 +sbt.version=1.9.7 diff --git a/tests/coverage/pos/Constructor.scoverage.check b/tests/coverage/pos/Constructor.scoverage.check index cb676686eac5..a95bb21488b8 100644 --- a/tests/coverage/pos/Constructor.scoverage.check +++ b/tests/coverage/pos/Constructor.scoverage.check @@ -174,9 +174,9 @@ def g 9 Constructor.scala covtest -O$ +O Object -covtest.O$ +covtest.O g 203 208 @@ -191,9 +191,9 @@ def g 10 Constructor.scala covtest -O$ +O Object -covtest.O$ +covtest.O y 223 228 @@ -208,9 +208,9 @@ def y 11 Constructor.scala covtest -O$ +O Object -covtest.O$ +covtest.O <init> 235 239 @@ -225,9 +225,9 @@ g(y) 12 Constructor.scala covtest -O$ +O Object -covtest.O$ +covtest.O <init> 237 238 diff --git a/tests/coverage/pos/Enum.scoverage.check b/tests/coverage/pos/Enum.scoverage.check index 3baa74fc2e5e..6806934e0dec 100644 --- a/tests/coverage/pos/Enum.scoverage.check +++ b/tests/coverage/pos/Enum.scoverage.check @@ -72,9 +72,9 @@ def surfaceWeight 3 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 1043 1077 @@ -89,9 +89,9 @@ println("Example 1: \\n"+emptyList) 4 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 1051 1076 @@ -106,9 +106,9 @@ false 5 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 1082 1103 @@ -123,9 +123,9 @@ println(s"${list}\\n") 6 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 1090 1102 @@ -140,9 +140,9 @@ s"${list}\\n" 7 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes calculateEarthWeightOnPlanets 1195 1222 @@ -157,9 +157,9 @@ Planet.Earth.surfaceGravity 8 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes calculateEarthWeightOnPlanets 1229 1320 @@ -174,9 +174,9 @@ for p <- Planet.values do\n println(s"Your weight on $p is ${p.surfaceWei 9 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes calculateEarthWeightOnPlanets 1238 1251 @@ -191,9 +191,9 @@ Planet.values 10 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes $anonfun 1263 1320 @@ -208,9 +208,9 @@ println(s"Your weight on $p is ${p.surfaceWeight(mass)}") 11 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes $anonfun 1271 1319 @@ -225,9 +225,9 @@ s"Your weight on $p is ${p.surfaceWeight(mass)}" 12 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes $anonfun 1296 1317 @@ -242,9 +242,9 @@ p.surfaceWeight(mass) 13 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes calculateEarthWeightOnPlanets 1109 1142 @@ -259,9 +259,9 @@ def calculateEarthWeightOnPlanets 14 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 1326 1347 @@ -276,9 +276,9 @@ println("Example 2:") 15 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 1352 1385 @@ -293,9 +293,9 @@ calculateEarthWeightOnPlanets(80) 16 Enum.scala covtest -EnumTypes$ +EnumTypes Object -covtest.EnumTypes$ +covtest.EnumTypes test 901 909 diff --git a/tests/coverage/pos/For.scoverage.check b/tests/coverage/pos/For.scoverage.check index 901d34701ced..6eeab746b4c5 100644 --- a/tests/coverage/pos/For.scoverage.check +++ b/tests/coverage/pos/For.scoverage.check @@ -21,9 +21,9 @@ 0 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForLoop 43 77 @@ -38,9 +38,9 @@ for i <- 1 to 10 do\n println(i) 1 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForLoop 52 59 @@ -55,9 +55,9 @@ false 2 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForLoop 52 53 @@ -72,9 +72,9 @@ false 3 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package $anonfun 67 77 @@ -89,9 +89,9 @@ println(i) 4 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForLoop 17 32 @@ -106,9 +106,9 @@ def testForLoop 5 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package f 109 114 @@ -123,9 +123,9 @@ def f 6 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForAdvanced 141 183 @@ -140,9 +140,9 @@ for j <- 1 to 10 if f(j) do\n println(j) 7 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForAdvanced 145 165 @@ -157,9 +157,9 @@ j <- 1 to 10 if f(j) 8 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForAdvanced 150 157 @@ -174,9 +174,9 @@ false 9 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForAdvanced 150 151 @@ -191,9 +191,9 @@ false 10 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package $anonfun 161 165 @@ -208,9 +208,9 @@ f(j) 11 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package $anonfun 173 183 @@ -225,9 +225,9 @@ println(j) 12 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForAdvanced 79 98 @@ -242,9 +242,9 @@ def testForAdvanced 13 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForeach 301 344 @@ -259,9 +259,9 @@ Nil.foreach(_ => println("user code here")) 14 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package $anonfun 318 343 @@ -276,9 +276,9 @@ println("user code here") 15 For.scala covtest -For$package$ +For$package Object -covtest.For$package$ +covtest.For$package testForeach 185 200 diff --git a/tests/coverage/pos/Inlined.scoverage.check b/tests/coverage/pos/Inlined.scoverage.check index bc0ab9d99892..c74868219b67 100644 --- a/tests/coverage/pos/Inlined.scoverage.check +++ b/tests/coverage/pos/Inlined.scoverage.check @@ -21,9 +21,9 @@ 0 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 288 330 @@ -38,9 +38,9 @@ scala.runtime.Scala3RunTime.assertFailed() 1 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 288 330 @@ -55,9 +55,9 @@ scala.runtime.Scala3RunTime.assertFailed() 2 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 330 330 @@ -72,9 +72,9 @@ false 3 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 155 162 @@ -89,9 +89,9 @@ List(l) 4 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 155 169 @@ -106,9 +106,9 @@ List(l).length 5 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 288 330 @@ -123,9 +123,9 @@ scala.runtime.Scala3RunTime.assertFailed() 6 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 288 330 @@ -140,9 +140,9 @@ scala.runtime.Scala3RunTime.assertFailed() 7 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 330 330 @@ -157,9 +157,9 @@ false 8 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 180 187 @@ -174,9 +174,9 @@ List(l) 9 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 180 194 @@ -191,9 +191,9 @@ List(l).length 10 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 288 330 @@ -208,9 +208,9 @@ scala.runtime.Scala3RunTime.assertFailed() 11 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 288 330 @@ -225,9 +225,9 @@ scala.runtime.Scala3RunTime.assertFailed() 12 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 330 330 @@ -242,9 +242,9 @@ false 13 Inlined.scala covtest -Inlined$package$ +Inlined$package Object -covtest.Inlined$package$ +covtest.Inlined$package testInlined 86 101 diff --git a/tests/coverage/pos/InlinedFromLib.scoverage.check b/tests/coverage/pos/InlinedFromLib.scoverage.check index 263281cfad39..5aff5473f6d9 100644 --- a/tests/coverage/pos/InlinedFromLib.scoverage.check +++ b/tests/coverage/pos/InlinedFromLib.scoverage.check @@ -21,9 +21,9 @@ 0 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 169 183 @@ -38,9 +38,9 @@ assert(l == 1) 1 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 169 183 @@ -55,9 +55,9 @@ assert(l == 1) 2 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 169 183 @@ -72,9 +72,9 @@ assert(l == 1) 3 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 198 205 @@ -89,9 +89,9 @@ List(l) 4 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 198 212 @@ -106,9 +106,9 @@ List(l).length 5 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 186 213 @@ -123,9 +123,9 @@ assert(l == List(l).length) 6 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 186 213 @@ -140,9 +140,9 @@ assert(l == List(l).length) 7 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 186 213 @@ -157,9 +157,9 @@ assert(l == List(l).length) 8 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 223 230 @@ -174,9 +174,9 @@ List(l) 9 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 223 237 @@ -191,9 +191,9 @@ List(l).length 10 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 216 243 @@ -208,9 +208,9 @@ assert(List(l).length == 1) 11 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 216 243 @@ -225,9 +225,9 @@ assert(List(l).length == 1) 12 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 216 243 @@ -242,9 +242,9 @@ assert(List(l).length == 1) 13 InlinedFromLib.scala covtest -InlinedFromLib$package$ +InlinedFromLib$package Object -covtest.InlinedFromLib$package$ +covtest.InlinedFromLib$package testInlined 129 144 diff --git a/tests/coverage/pos/Literals.scoverage.check b/tests/coverage/pos/Literals.scoverage.check index f23c481c1145..cd58a841d5b6 100644 --- a/tests/coverage/pos/Literals.scoverage.check +++ b/tests/coverage/pos/Literals.scoverage.check @@ -21,9 +21,9 @@ 0 Literals.scala covtest -Literals$package$ +Literals$package Object -covtest.Literals$package$ +covtest.Literals$package block 31 50 @@ -38,9 +38,9 @@ println("not this") 1 Literals.scala covtest -Literals$package$ +Literals$package Object -covtest.Literals$package$ +covtest.Literals$package block 17 26 @@ -55,9 +55,9 @@ def block 2 Literals.scala covtest -Literals$package$ +Literals$package Object -covtest.Literals$package$ +covtest.Literals$package f 177 180 @@ -72,9 +72,9 @@ false 3 Literals.scala covtest -Literals$package$ +Literals$package Object -covtest.Literals$package$ +covtest.Literals$package f 137 142 @@ -89,9 +89,9 @@ def f 4 Literals.scala covtest -Literals$package$ +Literals$package Object -covtest.Literals$package$ +covtest.Literals$package main 201 212 @@ -106,9 +106,9 @@ f(0,1,2)(3) 5 Literals.scala covtest -Literals$package$ +Literals$package Object -covtest.Literals$package$ +covtest.Literals$package main 182 190 diff --git a/tests/coverage/pos/MatchCaseClasses.scoverage.check b/tests/coverage/pos/MatchCaseClasses.scoverage.check index 0911532b1977..16574b6c770e 100644 --- a/tests/coverage/pos/MatchCaseClasses.scoverage.check +++ b/tests/coverage/pos/MatchCaseClasses.scoverage.check @@ -21,9 +21,9 @@ 0 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 151 163 @@ -38,9 +38,9 @@ println("a") 1 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 148 163 @@ -55,9 +55,9 @@ false 2 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 184 196 @@ -72,9 +72,9 @@ println("b") 3 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 181 196 @@ -89,9 +89,9 @@ false 4 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 225 237 @@ -106,9 +106,9 @@ println("c") 5 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 222 237 @@ -123,9 +123,9 @@ false 6 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 275 285 @@ -140,9 +140,9 @@ println(y) 7 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 292 304 @@ -157,9 +157,9 @@ println("d") 8 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 275 304 @@ -174,9 +174,9 @@ println(y)\n println("d") 9 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 325 337 @@ -191,9 +191,9 @@ println("e") 10 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 322 337 @@ -208,9 +208,9 @@ false 11 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 352 368 @@ -225,9 +225,9 @@ println("other") 12 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 349 368 @@ -242,9 +242,9 @@ false 13 MatchCaseClasses.scala covtest -MatchCaseClasses$ +MatchCaseClasses Object -covtest.MatchCaseClasses$ +covtest.MatchCaseClasses f 101 106 diff --git a/tests/coverage/pos/MatchNumbers.scoverage.check b/tests/coverage/pos/MatchNumbers.scoverage.check index ccb8a627f46e..43e01018f0ac 100644 --- a/tests/coverage/pos/MatchNumbers.scoverage.check +++ b/tests/coverage/pos/MatchNumbers.scoverage.check @@ -21,9 +21,9 @@ 0 MatchNumbers.scala covtest -MatchNumbers$ +MatchNumbers Object -covtest.MatchNumbers$ +covtest.MatchNumbers f 127 132 @@ -38,9 +38,9 @@ false 1 MatchNumbers.scala covtest -MatchNumbers$ +MatchNumbers Object -covtest.MatchNumbers$ +covtest.MatchNumbers f 149 153 @@ -55,9 +55,9 @@ false 2 MatchNumbers.scala covtest -MatchNumbers$ +MatchNumbers Object -covtest.MatchNumbers$ +covtest.MatchNumbers f 171 181 @@ -72,9 +72,9 @@ false 3 MatchNumbers.scala covtest -MatchNumbers$ +MatchNumbers Object -covtest.MatchNumbers$ +covtest.MatchNumbers f 69 74 @@ -89,9 +89,9 @@ def f 4 MatchNumbers.scala covtest -MatchNumbers$ +MatchNumbers Object -covtest.MatchNumbers$ +covtest.MatchNumbers <init> 185 189 @@ -106,9 +106,9 @@ f(0) 5 MatchNumbers.scala covtest -MatchNumbers$ +MatchNumbers Object -covtest.MatchNumbers$ +covtest.MatchNumbers <init> 192 197 diff --git a/tests/coverage/pos/PolymorphicExtensions.scoverage.check b/tests/coverage/pos/PolymorphicExtensions.scoverage.check index 33be52244cdf..64795070b34f 100644 --- a/tests/coverage/pos/PolymorphicExtensions.scoverage.check +++ b/tests/coverage/pos/PolymorphicExtensions.scoverage.check @@ -21,9 +21,9 @@ 0 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt foo 61 68 @@ -38,9 +38,9 @@ def foo 1 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt get 114 121 @@ -55,9 +55,9 @@ def get 2 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt tap 170 173 @@ -72,9 +72,9 @@ false 3 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt tap 139 146 @@ -89,9 +89,9 @@ def tap 4 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt <init> 177 189 @@ -106,9 +106,9 @@ false 5 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt <init> 177 186 @@ -123,9 +123,9 @@ false 6 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt <init> 277 287 @@ -140,9 +140,9 @@ false 7 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt foo 370 377 @@ -157,9 +157,9 @@ def foo 8 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt bar 405 421 @@ -174,9 +174,9 @@ foo.tap(println) 9 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt bar 405 412 @@ -191,9 +191,9 @@ foo.tap 10 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt bar 405 408 @@ -208,9 +208,9 @@ foo 11 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt $anonfun 413 420 @@ -225,9 +225,9 @@ println 12 PolymorphicExtensions.scala covtest -PolyExt$ +PolyExt Object -covtest.PolyExt$ +covtest.PolyExt bar 390 397 diff --git a/tests/coverage/pos/PolymorphicMethods.scoverage.check b/tests/coverage/pos/PolymorphicMethods.scoverage.check index ae6413869f06..b66aaeb92661 100644 --- a/tests/coverage/pos/PolymorphicMethods.scoverage.check +++ b/tests/coverage/pos/PolymorphicMethods.scoverage.check @@ -21,9 +21,9 @@ 0 PolymorphicMethods.scala covtest -PolyMeth$ +PolyMeth Object -covtest.PolyMeth$ +covtest.PolyMeth f 36 41 @@ -38,9 +38,9 @@ def f 1 PolymorphicMethods.scala covtest -PolyMeth$ +PolyMeth Object -covtest.PolyMeth$ +covtest.PolyMeth <init> 60 69 @@ -55,9 +55,9 @@ this.f(0) 2 PolymorphicMethods.scala covtest -PolyMeth$ +PolyMeth Object -covtest.PolyMeth$ +covtest.PolyMeth <init> 147 170 @@ -72,9 +72,9 @@ C[String]().f("str", 0) 3 PolymorphicMethods.scala covtest -PolyMeth$ +PolyMeth Object -covtest.PolyMeth$ +covtest.PolyMeth <init> 147 158 diff --git a/tests/coverage/pos/Select.scoverage.check b/tests/coverage/pos/Select.scoverage.check index 5300716cae90..cfe719552e44 100644 --- a/tests/coverage/pos/Select.scoverage.check +++ b/tests/coverage/pos/Select.scoverage.check @@ -140,9 +140,9 @@ override def print 7 Select.scala covtest -Select$package$ +Select$package Object -covtest.Select$package$ +covtest.Select$package test 237 240 @@ -157,9 +157,9 @@ A() 8 Select.scala covtest -Select$package$ +Select$package Object -covtest.Select$package$ +covtest.Select$package test 254 259 @@ -174,9 +174,9 @@ new A 9 Select.scala covtest -Select$package$ +Select$package Object -covtest.Select$package$ +covtest.Select$package test 263 281 @@ -191,9 +191,9 @@ a.instance.print() 10 Select.scala covtest -Select$package$ +Select$package Object -covtest.Select$package$ +covtest.Select$package test 263 273 @@ -208,9 +208,9 @@ a.instance 11 Select.scala covtest -Select$package$ +Select$package Object -covtest.Select$package$ +covtest.Select$package test 345 354 @@ -225,9 +225,9 @@ a.print() 12 Select.scala covtest -Select$package$ +Select$package Object -covtest.Select$package$ +covtest.Select$package test 208 216 diff --git a/tests/coverage/pos/StructuralTypes.scoverage.check b/tests/coverage/pos/StructuralTypes.scoverage.check index 2e897f6e8016..a487ac29c9de 100644 --- a/tests/coverage/pos/StructuralTypes.scoverage.check +++ b/tests/coverage/pos/StructuralTypes.scoverage.check @@ -72,9 +72,9 @@ def selectDynamic 3 StructuralTypes.scala covtest -StructuralTypes$ +StructuralTypes Object -covtest.StructuralTypes$ +covtest.StructuralTypes test 277 293 @@ -89,9 +89,9 @@ false 4 StructuralTypes.scala covtest -StructuralTypes$ +StructuralTypes Object -covtest.StructuralTypes$ +covtest.StructuralTypes test 295 306 @@ -106,9 +106,9 @@ false 5 StructuralTypes.scala covtest -StructuralTypes$ +StructuralTypes Object -covtest.StructuralTypes$ +covtest.StructuralTypes test 333 344 @@ -123,9 +123,9 @@ person.name 6 StructuralTypes.scala covtest -StructuralTypes$ +StructuralTypes Object -covtest.StructuralTypes$ +covtest.StructuralTypes test 234 242 diff --git a/tests/coverage/pos/TypeLambdas.scoverage.check b/tests/coverage/pos/TypeLambdas.scoverage.check index 091a5cf4da57..de519038c367 100644 --- a/tests/coverage/pos/TypeLambdas.scoverage.check +++ b/tests/coverage/pos/TypeLambdas.scoverage.check @@ -21,9 +21,9 @@ 0 TypeLambdas.scala covtest -TypeLambdas$ +TypeLambdas Object -covtest.TypeLambdas$ +covtest.TypeLambdas test 306 319 @@ -38,9 +38,9 @@ Map(1 -> "1") 1 TypeLambdas.scala covtest -TypeLambdas$ +TypeLambdas Object -covtest.TypeLambdas$ +covtest.TypeLambdas test 310 318 @@ -55,9 +55,9 @@ false 2 TypeLambdas.scala covtest -TypeLambdas$ +TypeLambdas Object -covtest.TypeLambdas$ +covtest.TypeLambdas test 324 334 @@ -72,9 +72,9 @@ println(m) 3 TypeLambdas.scala covtest -TypeLambdas$ +TypeLambdas Object -covtest.TypeLambdas$ +covtest.TypeLambdas test 382 396 @@ -89,9 +89,9 @@ println(tuple) 4 TypeLambdas.scala covtest -TypeLambdas$ +TypeLambdas Object -covtest.TypeLambdas$ +covtest.TypeLambdas test 259 267 diff --git a/tests/coverage/pos/i16502.scoverage.check b/tests/coverage/pos/i16502.scoverage.check index 4bc50c0f91c3..127c68063f73 100644 --- a/tests/coverage/pos/i16502.scoverage.check +++ b/tests/coverage/pos/i16502.scoverage.check @@ -21,9 +21,9 @@ 0 i16502.scala <empty> -i16502$package$ +i16502$package Object -<empty>.i16502$package$ +<empty>.i16502$package $anonfun 76 85 @@ -38,9 +38,9 @@ Future(1) 1 i16502.scala <empty> -i16502$package$ +i16502$package Object -<empty>.i16502$package$ +<empty>.i16502$package asyncSum 27 39 @@ -55,9 +55,9 @@ def asyncSum 2 i16502.scala <empty> -i16502$package$ +i16502$package Object -<empty>.i16502$package$ +<empty>.i16502$package Test 174 182 @@ -72,9 +72,9 @@ asyncSum 3 i16502.scala <empty> -i16502$package$ +i16502$package Object -<empty>.i16502$package$ +<empty>.i16502$package Test 87 101 diff --git a/tests/coverage/pos/scoverage-samples-implicit-class.scoverage.check b/tests/coverage/pos/scoverage-samples-implicit-class.scoverage.check index d44faf848942..f9bb9e0cd6a3 100644 --- a/tests/coverage/pos/scoverage-samples-implicit-class.scoverage.check +++ b/tests/coverage/pos/scoverage-samples-implicit-class.scoverage.check @@ -191,9 +191,9 @@ def ! 10 scoverage-samples-implicit-class.scala org.scoverage.samples -scoverage-samples-implicit-class$package$ +scoverage-samples-implicit-class$package Object -org.scoverage.samples.scoverage-samples-implicit-class$package$ +org.scoverage.samples.scoverage-samples-implicit-class$package StringOpssssss 79 108 diff --git a/tests/coverage/run/currying/test.scoverage.check b/tests/coverage/run/currying/test.scoverage.check index 183e42fba2d5..abc1876942db 100644 --- a/tests/coverage/run/currying/test.scoverage.check +++ b/tests/coverage/run/currying/test.scoverage.check @@ -21,9 +21,9 @@ 0 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test f1 15 21 @@ -38,9 +38,9 @@ def f1 1 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test f2 56 62 @@ -55,9 +55,9 @@ def f2 2 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test g1 114 120 @@ -72,9 +72,9 @@ def g1 3 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test g2 175 181 @@ -89,9 +89,9 @@ def g2 4 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 277 297 @@ -106,9 +106,9 @@ println(f1(0)(1)(2)) 5 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 285 296 @@ -123,9 +123,9 @@ f1(0)(1)(2) 6 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 302 322 @@ -140,9 +140,9 @@ println(f2(0)(1)(2)) 7 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 310 321 @@ -157,9 +157,9 @@ f2(0)(1)(2) 8 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 310 318 @@ -174,9 +174,9 @@ f2(0)(1) 9 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 310 315 @@ -191,9 +191,9 @@ f2(0) 10 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 310 312 @@ -208,9 +208,9 @@ f2 11 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 327 365 @@ -225,9 +225,9 @@ println(g1(using 0)(using 1)(using 2)) 12 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 335 364 @@ -242,9 +242,9 @@ g1(using 0)(using 1)(using 2) 13 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 370 408 @@ -259,9 +259,9 @@ println(g2(using 0)(using 1)(using 2)) 14 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 378 407 @@ -276,9 +276,9 @@ g2(using 0)(using 1)(using 2) 15 currying/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 235 243 diff --git a/tests/coverage/run/erased/test.scoverage.check b/tests/coverage/run/erased/test.scoverage.check index 979d88ecd78f..dedf5689c490 100644 --- a/tests/coverage/run/erased/test.scoverage.check +++ b/tests/coverage/run/erased/test.scoverage.check @@ -21,9 +21,9 @@ 0 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package foo 181 203 @@ -38,9 +38,9 @@ println(s"foo(a)($b)") 1 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package foo 189 202 @@ -55,9 +55,9 @@ s"foo(a)($b)" 2 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package foo 132 139 @@ -72,9 +72,9 @@ def foo 3 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package identity 245 269 @@ -89,9 +89,9 @@ println(s"identity($s)") 4 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package identity 253 268 @@ -106,9 +106,9 @@ s"identity($s)" 5 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package identity 209 221 @@ -123,9 +123,9 @@ def identity 6 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 300 323 @@ -140,9 +140,9 @@ foo(parameterless)("b") 7 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 326 342 @@ -157,9 +157,9 @@ foo(e("a"))("b") 8 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 345 374 @@ -174,9 +174,9 @@ foo(e("a"))(identity("idem")) 9 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 357 373 @@ -191,9 +191,9 @@ identity("idem") 10 erased/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 275 289 diff --git a/tests/coverage/run/extend-case-class/test.scoverage.check b/tests/coverage/run/extend-case-class/test.scoverage.check index 891f4ac198ca..b355140d2520 100644 --- a/tests/coverage/run/extend-case-class/test.scoverage.check +++ b/tests/coverage/run/extend-case-class/test.scoverage.check @@ -21,9 +21,9 @@ 0 extend-case-class/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 282 303 @@ -38,9 +38,9 @@ println(c.scaleLimit) 1 extend-case-class/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 306 337 @@ -55,9 +55,9 @@ println(DecimalConf.scaleLimit) 2 extend-case-class/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 206 220 diff --git a/tests/coverage/run/i16940/i16940.scoverage.check b/tests/coverage/run/i16940/i16940.scoverage.check index f8ff25537b0f..357080ba9da8 100644 --- a/tests/coverage/run/i16940/i16940.scoverage.check +++ b/tests/coverage/run/i16940/i16940.scoverage.check @@ -21,9 +21,9 @@ 0 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 353 552 @@ -38,9 +38,9 @@ Await.result(\n Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSyn 1 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 371 533 @@ -55,9 +55,9 @@ Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true 2 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 371 454 @@ -72,9 +72,9 @@ Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true 3 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 387 453 @@ -89,9 +89,9 @@ Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true)) 4 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 391 421 @@ -106,9 +106,9 @@ brokenSynchronizedBlock(false) 5 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 423 452 @@ -123,9 +123,9 @@ brokenSynchronizedBlock(true) 6 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test $anonfun 486 499 @@ -140,9 +140,9 @@ println(test) 7 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test $anonfun 508 525 @@ -157,9 +157,9 @@ assert(test == 2) 8 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test $anonfun 508 525 @@ -174,9 +174,9 @@ assert(test == 2) 9 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test $anonfun 508 525 @@ -191,9 +191,9 @@ assert(test == 2) 10 i16940/i16940.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 539 548 @@ -208,9 +208,9 @@ false 11 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 189 323 @@ -225,9 +225,9 @@ Future {\n if (option) {\n Thread.sleep(500)\n }\n synchronized {\n val 12 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 218 235 @@ -242,9 +242,9 @@ Thread.sleep(500) 13 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 212 239 @@ -259,9 +259,9 @@ false 14 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 239 239 @@ -276,9 +276,9 @@ false 15 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 242 321 @@ -293,9 +293,9 @@ synchronized {\n val tmp = test\n Thread.sleep(1000)\n test = tmp + 1\n 16 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 280 298 @@ -310,9 +310,9 @@ Thread.sleep(1000) 17 i16940/i16940.scala <empty> -i16940$package$ +i16940$package Object -<empty>.i16940$package$ +<empty>.i16940$package brokenSynchronizedBlock 128 155 diff --git a/tests/coverage/run/i18233-min/i18233-min.scoverage.check b/tests/coverage/run/i18233-min/i18233-min.scoverage.check index 7c9144c289bc..7570ebaaed96 100644 --- a/tests/coverage/run/i18233-min/i18233-min.scoverage.check +++ b/tests/coverage/run/i18233-min/i18233-min.scoverage.check @@ -21,9 +21,9 @@ 0 i18233-min/i18233-min.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 131 145 @@ -38,9 +38,9 @@ println(aList) 1 i18233-min/i18233-min.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 139 144 @@ -55,9 +55,9 @@ aList 2 i18233-min/i18233-min.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 148 168 @@ -72,9 +72,9 @@ println(anotherList) 3 i18233-min/i18233-min.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 156 167 @@ -89,9 +89,9 @@ anotherList 4 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package aList 14 36 @@ -106,9 +106,9 @@ List(Array[String]()*) 5 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package aList 19 34 @@ -123,9 +123,9 @@ Array[String]() 6 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package aList 0 9 @@ -140,9 +140,9 @@ def aList 7 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package arr 50 69 @@ -157,9 +157,9 @@ Array("abc", "def") 8 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package arr 38 45 @@ -174,9 +174,9 @@ def arr 9 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package anotherList 91 101 @@ -191,9 +191,9 @@ List(arr*) 10 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package anotherList 96 99 @@ -208,9 +208,9 @@ arr 11 i18233-min/i18233-min.scala <empty> -i18233-min$package$ +i18233-min$package Object -<empty>.i18233-min$package$ +<empty>.i18233-min$package anotherList 71 86 diff --git a/tests/coverage/run/i18233/i18233.scoverage.check b/tests/coverage/run/i18233/i18233.scoverage.check index e632292e782e..878ca8a14705 100644 --- a/tests/coverage/run/i18233/i18233.scoverage.check +++ b/tests/coverage/run/i18233/i18233.scoverage.check @@ -21,9 +21,9 @@ 0 i18233/i18233.scala <empty> -Foo$ +Foo Object -<empty>.Foo$ +<empty>.Foo render 54 72 @@ -38,9 +38,9 @@ List(values.tail*) 1 i18233/i18233.scala <empty> -Foo$ +Foo Object -<empty>.Foo$ +<empty>.Foo render 59 65 @@ -55,9 +55,9 @@ values 2 i18233/i18233.scala <empty> -Foo$ +Foo Object -<empty>.Foo$ +<empty>.Foo render 59 70 @@ -72,9 +72,9 @@ values.tail 3 i18233/i18233.scala <empty> -Foo$ +Foo Object -<empty>.Foo$ +<empty>.Foo render 54 81 @@ -89,9 +89,9 @@ List(values.tail*).mkString 4 i18233/i18233.scala <empty> -Foo$ +Foo Object -<empty>.Foo$ +<empty>.Foo render 41 51 @@ -106,9 +106,9 @@ def render 5 i18233/i18233.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 111 130 @@ -123,9 +123,9 @@ println(Foo.render) 6 i18233/i18233.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test <init> 119 129 diff --git a/tests/coverage/run/inheritance/test.scoverage.check b/tests/coverage/run/inheritance/test.scoverage.check index d4ca12879ea3..387a080463e2 100644 --- a/tests/coverage/run/inheritance/test.scoverage.check +++ b/tests/coverage/run/inheritance/test.scoverage.check @@ -55,9 +55,9 @@ A(2,2) 2 inheritance/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 161 176 @@ -72,9 +72,9 @@ println(C1().x) 3 inheritance/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 169 173 @@ -89,9 +89,9 @@ C1() 4 inheritance/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 211 226 @@ -106,9 +106,9 @@ println(C2().x) 5 inheritance/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 219 223 @@ -123,9 +123,9 @@ C2() 6 inheritance/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 136 150 diff --git a/tests/coverage/run/inline-def/test.scoverage.check b/tests/coverage/run/inline-def/test.scoverage.check index f8a852707146..17fa7c049107 100644 --- a/tests/coverage/run/inline-def/test.scoverage.check +++ b/tests/coverage/run/inline-def/test.scoverage.check @@ -21,9 +21,9 @@ 0 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 225 228 @@ -38,9 +38,9 @@ A() 1 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 231 243 @@ -55,9 +55,9 @@ println(a.x) 2 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 246 260 @@ -72,9 +72,9 @@ println(a.foo) 3 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 134 148 @@ -89,9 +89,9 @@ false 4 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 263 277 @@ -106,9 +106,9 @@ println(a.bar) 5 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 176 190 @@ -123,9 +123,9 @@ false 6 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 295 309 @@ -140,9 +140,9 @@ println(b.foo) 7 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 303 308 @@ -157,9 +157,9 @@ b.foo 8 inline-def/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 192 206 diff --git a/tests/coverage/run/interpolation/test.scoverage.check b/tests/coverage/run/interpolation/test.scoverage.check index b2373483737e..37562dab5509 100644 --- a/tests/coverage/run/interpolation/test.scoverage.check +++ b/tests/coverage/run/interpolation/test.scoverage.check @@ -21,9 +21,9 @@ 0 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test simple 60 78 @@ -38,9 +38,9 @@ s"$a, ${b.length}" 1 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test simple 68 76 @@ -55,9 +55,9 @@ b.length 2 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test simple 16 26 @@ -72,9 +72,9 @@ def simple 3 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test hexa 113 126 @@ -89,9 +89,9 @@ f"0x${i}%04x" 4 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test hexa 82 90 @@ -106,9 +106,9 @@ def hexa 5 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 195 224 @@ -123,9 +123,9 @@ List("d", "o", "t", "t", "y") 6 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 229 278 @@ -140,9 +140,9 @@ xs.zipWithIndex.map((s, i) => println(s"$i: $s")) 7 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 229 244 @@ -157,9 +157,9 @@ xs.zipWithIndex 8 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test $anonfun 259 277 @@ -174,9 +174,9 @@ println(s"$i: $s") 9 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test $anonfun 267 276 @@ -191,9 +191,9 @@ s"$i: $s" 10 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 284 309 @@ -208,9 +208,9 @@ println(simple(1, "abc")) 11 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 292 308 @@ -225,9 +225,9 @@ simple(1, "abc") 12 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 314 332 @@ -242,9 +242,9 @@ println(hexa(127)) 13 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 322 331 @@ -259,9 +259,9 @@ hexa(127) 14 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 337 355 @@ -276,9 +276,9 @@ println(raw"a\\nb") 15 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 345 354 @@ -293,9 +293,9 @@ raw"a\\nb" 16 interpolation/test.scala <empty> -Test$ +Test Object -<empty>.Test$ +<empty>.Test main 130 138 diff --git a/tests/coverage/run/java-methods/test.scoverage.check b/tests/coverage/run/java-methods/test.scoverage.check index e39efe8f3aa8..891af1804831 100644 --- a/tests/coverage/run/java-methods/test.scoverage.check +++ b/tests/coverage/run/java-methods/test.scoverage.check @@ -21,9 +21,9 @@ 0 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 61 83 @@ -38,9 +38,9 @@ StaticMethods.simple() 1 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 86 127 @@ -55,9 +55,9 @@ StaticMethods.withTypeParam[Any](a => ()) 2 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 140 152 @@ -72,9 +72,9 @@ JavaObject() 3 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 155 162 @@ -89,9 +89,9 @@ obj.f() 4 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 165 194 @@ -106,9 +106,9 @@ println(obj.identity[Int](0)) 5 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 173 193 @@ -123,9 +123,9 @@ obj.identity[Int](0) 6 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 197 211 @@ -140,9 +140,9 @@ println("ok!") 7 java-methods/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 36 50 diff --git a/tests/coverage/run/lifting-bool/test.scoverage.check b/tests/coverage/run/lifting-bool/test.scoverage.check index 80d0bfad9c59..5eb3d864939f 100644 --- a/tests/coverage/run/lifting-bool/test.scoverage.check +++ b/tests/coverage/run/lifting-bool/test.scoverage.check @@ -21,9 +21,9 @@ 0 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package notCalled 19 22 @@ -38,9 +38,9 @@ false 1 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package notCalled 1 14 @@ -55,9 +55,9 @@ def notCalled 2 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package f 24 29 @@ -72,9 +72,9 @@ def f 3 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 109 120 @@ -89,9 +89,9 @@ notCalled() 4 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 159 170 @@ -106,9 +106,9 @@ notCalled() 5 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 219 230 @@ -123,9 +123,9 @@ notCalled() 6 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 267 278 @@ -140,9 +140,9 @@ notCalled() 7 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 318 329 @@ -157,9 +157,9 @@ notCalled() 8 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 341 367 @@ -174,9 +174,9 @@ println(s"$a $b $c $d $e") 9 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 349 366 @@ -191,9 +191,9 @@ s"$a $b $c $d $e" 10 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 379 393 @@ -208,9 +208,9 @@ f(true, false) 11 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 396 406 @@ -225,9 +225,9 @@ println(x) 12 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 422 466 @@ -242,9 +242,9 @@ f(true || notCalled(), false && notCalled()) 13 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 432 443 @@ -259,9 +259,9 @@ notCalled() 14 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 454 465 @@ -276,9 +276,9 @@ notCalled() 15 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 469 479 @@ -293,9 +293,9 @@ println(x) 16 lifting-bool/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 68 82 diff --git a/tests/coverage/run/lifting/test.scoverage.check b/tests/coverage/run/lifting/test.scoverage.check index 0c2ee042e912..136b8e2e4fbb 100644 --- a/tests/coverage/run/lifting/test.scoverage.check +++ b/tests/coverage/run/lifting/test.scoverage.check @@ -208,9 +208,9 @@ def ex 11 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 221 224 @@ -225,9 +225,9 @@ A() 12 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package f 241 246 @@ -242,9 +242,9 @@ def f 13 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 264 286 @@ -259,9 +259,9 @@ a.msg(i, 0, a.integer) 14 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 276 285 @@ -276,9 +276,9 @@ a.integer 15 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 289 299 @@ -293,9 +293,9 @@ println(x) 16 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 306 334 @@ -310,9 +310,9 @@ a.ex.msg(i, 0, a.ex.integer) 17 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 306 310 @@ -327,9 +327,9 @@ a.ex 18 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 321 325 @@ -344,9 +344,9 @@ a.ex 19 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 321 333 @@ -361,9 +361,9 @@ a.ex.integer 20 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 337 347 @@ -378,9 +378,9 @@ println(x) 21 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 354 370 @@ -395,9 +395,9 @@ a.msg(f(), 0, i) 22 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 360 363 @@ -412,9 +412,9 @@ f() 23 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 373 383 @@ -429,9 +429,9 @@ println(x) 24 lifting/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 188 202 diff --git a/tests/coverage/run/parameterless/test.scoverage.check b/tests/coverage/run/parameterless/test.scoverage.check index 6f15f3a5e93f..5050180e7886 100644 --- a/tests/coverage/run/parameterless/test.scoverage.check +++ b/tests/coverage/run/parameterless/test.scoverage.check @@ -21,9 +21,9 @@ 0 parameterless/test.scala <empty> -O$ +O Object -<empty>.O$ +<empty>.O f 32 46 @@ -38,9 +38,9 @@ println("O.f") 1 parameterless/test.scala <empty> -O$ +O Object -<empty>.O$ +<empty>.O f 12 17 @@ -55,9 +55,9 @@ def f 2 parameterless/test.scala <empty> -O$ +O Object -<empty>.O$ +<empty>.O g 87 101 @@ -72,9 +72,9 @@ println("O.g") 3 parameterless/test.scala <empty> -O$ +O Object -<empty>.O$ +<empty>.O g 64 69 @@ -89,9 +89,9 @@ def g 4 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package f 162 174 @@ -106,9 +106,9 @@ println("f") 5 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package f 142 147 @@ -123,9 +123,9 @@ def f 6 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package g 213 225 @@ -140,9 +140,9 @@ println("g") 7 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package g 190 195 @@ -157,9 +157,9 @@ def g 8 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 249 250 @@ -174,9 +174,9 @@ f 9 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 261 262 @@ -191,9 +191,9 @@ g 10 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 265 275 @@ -208,9 +208,9 @@ println(f) 11 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 273 274 @@ -225,9 +225,9 @@ f 12 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 278 288 @@ -242,9 +242,9 @@ println(g) 13 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 286 287 @@ -259,9 +259,9 @@ g 14 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 291 303 @@ -276,9 +276,9 @@ println(O.f) 15 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 299 302 @@ -293,9 +293,9 @@ O.f 16 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 306 318 @@ -310,9 +310,9 @@ println(O.g) 17 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 314 317 @@ -327,9 +327,9 @@ O.g 18 parameterless/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 117 131 diff --git a/tests/coverage/run/trait/test.scoverage.check b/tests/coverage/run/trait/test.scoverage.check index c5b6123e7e2b..19a88ebc7f6f 100644 --- a/tests/coverage/run/trait/test.scoverage.check +++ b/tests/coverage/run/trait/test.scoverage.check @@ -55,9 +55,9 @@ Impl2() 2 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 170 188 @@ -72,9 +72,9 @@ println(Impl1().x) 3 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 178 185 @@ -89,9 +89,9 @@ Impl1() 4 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 178 187 @@ -106,9 +106,9 @@ Impl1().x 5 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 196 214 @@ -123,9 +123,9 @@ println(Impl2().p) 6 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 204 211 @@ -140,9 +140,9 @@ Impl2() 7 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 225 243 @@ -157,9 +157,9 @@ println(Impl3().p) 8 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 233 240 @@ -174,9 +174,9 @@ Impl3() 9 trait/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 145 159 diff --git a/tests/coverage/run/type-apply/test.scoverage.check b/tests/coverage/run/type-apply/test.scoverage.check index 6907a0aa516f..7d76b11f2f8b 100644 --- a/tests/coverage/run/type-apply/test.scoverage.check +++ b/tests/coverage/run/type-apply/test.scoverage.check @@ -21,9 +21,9 @@ 0 type-apply/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 163 201 @@ -38,9 +38,9 @@ println(List(1,2,3).map(a => List(a))) 1 type-apply/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 171 200 @@ -55,9 +55,9 @@ List(1,2,3).map(a => List(a)) 2 type-apply/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 171 182 @@ -72,9 +72,9 @@ List(1,2,3) 3 type-apply/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package $anonfun 192 199 @@ -89,9 +89,9 @@ List(a) 4 type-apply/test.scala <empty> -test$package$ +test$package Object -<empty>.test$package$ +<empty>.test$package Test 0 14 diff --git a/tests/coverage/run/varargs/test_1.scoverage.check b/tests/coverage/run/varargs/test_1.scoverage.check index 5b287586a540..3c31f9388409 100644 --- a/tests/coverage/run/varargs/test_1.scoverage.check +++ b/tests/coverage/run/varargs/test_1.scoverage.check @@ -21,9 +21,9 @@ 0 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package repeated 48 60 @@ -38,9 +38,9 @@ def repeated 1 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package f 79 84 @@ -55,9 +55,9 @@ def f 2 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 120 130 @@ -72,9 +72,9 @@ repeated() 3 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 133 153 @@ -89,9 +89,9 @@ repeated(f(""), "b") 4 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 142 147 @@ -106,9 +106,9 @@ f("") 5 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 156 178 @@ -123,9 +123,9 @@ JavaVarargs_1.method() 6 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 181 205 @@ -140,9 +140,9 @@ JavaVarargs_1.method("") 7 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 217 248 @@ -157,9 +157,9 @@ JavaVarargs_1.multiple("first") 8 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 251 261 @@ -174,9 +174,9 @@ println(m) 9 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 268 302 @@ -191,9 +191,9 @@ JavaVarargs_1.multiple(f("first")) 10 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 291 301 @@ -208,9 +208,9 @@ f("first") 11 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 305 315 @@ -225,9 +225,9 @@ println(m) 12 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 322 371 @@ -242,9 +242,9 @@ JavaVarargs_1.multiple(f("first"), "a", "b", "c") 13 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 345 355 @@ -259,9 +259,9 @@ f("first") 14 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 374 384 @@ -276,9 +276,9 @@ println(m) 15 varargs/test_1.scala <empty> -test_1$package$ +test_1$package Object -<empty>.test_1$package$ +<empty>.test_1$package Test 101 115 diff --git a/tests/neg/i8984.check b/tests/disabled/neg/i8984.check similarity index 100% rename from tests/neg/i8984.check rename to tests/disabled/neg/i8984.check diff --git a/tests/disabled/neg/i8984.scala b/tests/disabled/neg/i8984.scala new file mode 100644 index 000000000000..d31fa45db6e2 --- /dev/null +++ b/tests/disabled/neg/i8984.scala @@ -0,0 +1,20 @@ +import scala.annotation.tailrec +type |@[F[+_], G[+_]] = [a] =>> F[a] | G[a] + +object Fix: // error + opaque type T[+F[+_]] = ApplyFix.T[F] + + def apply[F[+_]](f: F[Fix[F]]): T[F] = ApplyFix(f) // error // error + + extension [F[+_]](fix: T[F]) // error + def value: F[Fix[F]] = ApplyFix.unwrap(fix) + + object ApplyFix: + opaque type T[+F[+_]] = F[Fix[F]] + + def apply[F[+_]](f: F[Fix[F]]): T[F] = f + + def unwrap[F[+_]](v: T[F]): F[Fix[F]] = v + +type Fix[+F[+_]] = Fix.T[F] + diff --git a/tests/explicit-nulls/pos/i19202.scala b/tests/explicit-nulls/pos/i19202.scala new file mode 100644 index 000000000000..1bba0875f9a9 --- /dev/null +++ b/tests/explicit-nulls/pos/i19202.scala @@ -0,0 +1,27 @@ +class Test { + def test1(s: String | Null): Unit = { + if s == null then return + + case class XXX() + } + + def test2(s: String | Null): Unit = { + if s == "" then return + + case class XXX() + } + + def test3(s: String | Null): Unit = { + if s == null then return + + case class XXX() + () + } + + def test4(s: String | Null): String | Null = { + if s == null then return "" + + case class XXX() + "xxx" + } +} \ No newline at end of file diff --git a/tests/explicit-nulls/pos/nn2.scala b/tests/explicit-nulls/pos/nn2.scala index a39618b97f22..6c2c67396899 100644 --- a/tests/explicit-nulls/pos/nn2.scala +++ b/tests/explicit-nulls/pos/nn2.scala @@ -1,5 +1,5 @@ // Test that is fixed when explicit nulls are enabled. -// https://github.com/lampepfl/dotty/issues/6247 +// https://github.com/scala/scala3/issues/6247 class Foo { val x1: String|Null = null diff --git a/tests/init-global/neg/i11262.scala b/tests/init-global/neg/i11262.scala deleted file mode 100644 index c1c01f6aad8c..000000000000 --- a/tests/init-global/neg/i11262.scala +++ /dev/null @@ -1,2 +0,0 @@ -object A { val x: String = B.y } // error -object B { val y: String = A.x } // error diff --git a/tests/init-global/neg/i15883.scala b/tests/init-global/neg/i15883.scala deleted file mode 100644 index 80051c13b92b..000000000000 --- a/tests/init-global/neg/i15883.scala +++ /dev/null @@ -1,2 +0,0 @@ -val a = b // error -val b = 1 diff --git a/tests/init-global/warn/context-sensitivity.check b/tests/init-global/warn/context-sensitivity.check new file mode 100644 index 000000000000..bc0453b1bc88 --- /dev/null +++ b/tests/init-global/warn/context-sensitivity.check @@ -0,0 +1,10 @@ +-- Warning: tests/init-global/warn/context-sensitivity.scala:9:21 ------------------------------------------------------ +9 | def foo(): Int = A.m // warn + | ^^^ + | Access uninitialized field value m. Calling trace: + | ├── object A: [ context-sensitivity.scala:14 ] + | │ ^ + | ├── val m: Int = box1.value.foo() [ context-sensitivity.scala:17 ] + | │ ^^^^^^^^^^^^^^^^ + | └── def foo(): Int = A.m // warn [ context-sensitivity.scala:9 ] + | ^^^ diff --git a/tests/init-global/neg/context-sensitivity.scala b/tests/init-global/warn/context-sensitivity.scala old mode 100755 new mode 100644 similarity index 89% rename from tests/init-global/neg/context-sensitivity.scala rename to tests/init-global/warn/context-sensitivity.scala index 626fd41bb43f..9150a81619cc --- a/tests/init-global/neg/context-sensitivity.scala +++ b/tests/init-global/warn/context-sensitivity.scala @@ -6,7 +6,7 @@ class C(var x: Int) extends Foo { } class D(var y: Int) extends Foo { - def foo(): Int = A.m // error + def foo(): Int = A.m // warn } class Box(var value: Foo) @@ -15,3 +15,4 @@ object A: val box1: Box = new Box(new C(5)) val box2: Box = new Box(new D(10)) val m: Int = box1.value.foo() + diff --git a/tests/init-global/neg/global-cycle1.check b/tests/init-global/warn/global-cycle1.check similarity index 59% rename from tests/init-global/neg/global-cycle1.check rename to tests/init-global/warn/global-cycle1.check index c68b8b51a419..adee7e47dd54 100644 --- a/tests/init-global/neg/global-cycle1.check +++ b/tests/init-global/warn/global-cycle1.check @@ -1,20 +1,20 @@ --- Error: tests/init-global/neg/global-cycle1.scala:1:7 ---------------------------------------------------------------- -1 |object A { // error +-- Warning: tests/init-global/warn/global-cycle1.scala:1:7 ------------------------------------------------------------- +1 |object A { // warn | ^ | Cyclic initialization: object A -> object B -> object A. Calling trace: - | ├── object A { // error [ global-cycle1.scala:1 ] + | ├── object A { // warn [ global-cycle1.scala:1 ] | │ ^ | ├── val a: Int = B.b [ global-cycle1.scala:2 ] | │ ^ | ├── object B { [ global-cycle1.scala:5 ] | │ ^ - | └── val b: Int = A.a // error [ global-cycle1.scala:6 ] + | └── val b: Int = A.a // warn [ global-cycle1.scala:6 ] | ^ --- Error: tests/init-global/neg/global-cycle1.scala:6:17 --------------------------------------------------------------- -6 | val b: Int = A.a // error +-- Warning: tests/init-global/warn/global-cycle1.scala:6:17 ------------------------------------------------------------ +6 | val b: Int = A.a // warn | ^^^ | Access uninitialized field value a. Calling trace: | ├── object B { [ global-cycle1.scala:5 ] | │ ^ - | └── val b: Int = A.a // error [ global-cycle1.scala:6 ] + | └── val b: Int = A.a // warn [ global-cycle1.scala:6 ] | ^^^ diff --git a/tests/init-global/neg/global-cycle1.scala b/tests/init-global/warn/global-cycle1.scala similarity index 50% rename from tests/init-global/neg/global-cycle1.scala rename to tests/init-global/warn/global-cycle1.scala index 592f5a652dc8..e3951f155b76 100644 --- a/tests/init-global/neg/global-cycle1.scala +++ b/tests/init-global/warn/global-cycle1.scala @@ -1,9 +1,9 @@ -object A { // error +object A { // warn val a: Int = B.b } object B { - val b: Int = A.a // error + val b: Int = A.a // warn } @main diff --git a/tests/init-global/warn/global-cycle14.check b/tests/init-global/warn/global-cycle14.check new file mode 100644 index 000000000000..ebdb4667f877 --- /dev/null +++ b/tests/init-global/warn/global-cycle14.check @@ -0,0 +1,20 @@ +-- Warning: tests/init-global/warn/global-cycle14.scala:8:7 ------------------------------------------------------------ +8 |object A { // warn + | ^ + | Cyclic initialization: object A -> object B -> object A. Calling trace: + | ├── object A { // warn [ global-cycle14.scala:8 ] + | │ ^ + | ├── val n: Int = B.m [ global-cycle14.scala:9 ] + | │ ^ + | ├── object B { [ global-cycle14.scala:12 ] + | │ ^ + | └── val m: Int = A.n // warn [ global-cycle14.scala:13 ] + | ^ +-- Warning: tests/init-global/warn/global-cycle14.scala:13:17 ---------------------------------------------------------- +13 | val m: Int = A.n // warn + | ^^^ + | Access uninitialized field value n. Calling trace: + | ├── object B { [ global-cycle14.scala:12 ] + | │ ^ + | └── val m: Int = A.n // warn [ global-cycle14.scala:13 ] + | ^^^ diff --git a/tests/init-global/neg/global-cycle14.scala b/tests/init-global/warn/global-cycle14.scala similarity index 69% rename from tests/init-global/neg/global-cycle14.scala rename to tests/init-global/warn/global-cycle14.scala index bcacbebb74fa..696c7ba672f3 100644 --- a/tests/init-global/neg/global-cycle14.scala +++ b/tests/init-global/warn/global-cycle14.scala @@ -5,10 +5,10 @@ object O { val d = Data(3) } -object A { // error +object A { // warn val n: Int = B.m } object B { - val m: Int = A.n // error + val m: Int = A.n // warn } diff --git a/tests/init-global/warn/global-cycle2.check b/tests/init-global/warn/global-cycle2.check new file mode 100644 index 000000000000..37c99b36ac25 --- /dev/null +++ b/tests/init-global/warn/global-cycle2.check @@ -0,0 +1,10 @@ +-- Warning: tests/init-global/warn/global-cycle2.scala:6:21 ------------------------------------------------------------ +6 | def foo(): Int = A.a * 2 // warn + | ^^^ + | Access uninitialized field value a. Calling trace: + | ├── object A { [ global-cycle2.scala:1 ] + | │ ^ + | ├── val a: Int = B.foo() [ global-cycle2.scala:2 ] + | │ ^^^^^^^ + | └── def foo(): Int = A.a * 2 // warn [ global-cycle2.scala:6 ] + | ^^^ diff --git a/tests/init-global/neg/global-cycle2.scala b/tests/init-global/warn/global-cycle2.scala similarity index 57% rename from tests/init-global/neg/global-cycle2.scala rename to tests/init-global/warn/global-cycle2.scala index d86fe09fb0fa..90ca855b00e8 100644 --- a/tests/init-global/neg/global-cycle2.scala +++ b/tests/init-global/warn/global-cycle2.scala @@ -3,5 +3,5 @@ object A { } object B { - def foo(): Int = A.a * 2 // error + def foo(): Int = A.a * 2 // warn } diff --git a/tests/init-global/warn/global-cycle3.check b/tests/init-global/warn/global-cycle3.check new file mode 100644 index 000000000000..d250c3fda5e3 --- /dev/null +++ b/tests/init-global/warn/global-cycle3.check @@ -0,0 +1,10 @@ +-- Warning: tests/init-global/warn/global-cycle3.scala:2:21 ------------------------------------------------------------ +2 | def foo(): Int = B.a + 10 // warn + | ^^^ + | Access uninitialized field value a. Calling trace: + | ├── object B { [ global-cycle3.scala:5 ] + | │ ^ + | ├── val a: Int = A(4).foo() [ global-cycle3.scala:6 ] + | │ ^^^^^^^^^^ + | └── def foo(): Int = B.a + 10 // warn [ global-cycle3.scala:2 ] + | ^^^ diff --git a/tests/init-global/neg/global-cycle3.scala b/tests/init-global/warn/global-cycle3.scala similarity index 61% rename from tests/init-global/neg/global-cycle3.scala rename to tests/init-global/warn/global-cycle3.scala index 405e007b044a..9d72ac6321fb 100644 --- a/tests/init-global/neg/global-cycle3.scala +++ b/tests/init-global/warn/global-cycle3.scala @@ -1,5 +1,5 @@ class A(x: Int) { - def foo(): Int = B.a + 10 // error + def foo(): Int = B.a + 10 // warn } object B { diff --git a/tests/init-global/warn/global-cycle4.check b/tests/init-global/warn/global-cycle4.check new file mode 100644 index 000000000000..030f62782631 --- /dev/null +++ b/tests/init-global/warn/global-cycle4.check @@ -0,0 +1,10 @@ +-- Warning: tests/init-global/warn/global-cycle4.scala:10:21 ----------------------------------------------------------- +10 | def foo(): Int = O.a + 10 // warn + | ^^^ + | Access uninitialized field value a. Calling trace: + | ├── object O { [ global-cycle4.scala:17 ] + | │ ^ + | ├── val a: Int = D(5).bar().foo() [ global-cycle4.scala:18 ] + | │ ^^^^^^^^^^^^^^^^ + | └── def foo(): Int = O.a + 10 // warn [ global-cycle4.scala:10 ] + | ^^^ diff --git a/tests/init-global/neg/global-cycle4.scala b/tests/init-global/warn/global-cycle4.scala similarity index 83% rename from tests/init-global/neg/global-cycle4.scala rename to tests/init-global/warn/global-cycle4.scala index 8c1627afeae4..dea2a0b486cf 100644 --- a/tests/init-global/neg/global-cycle4.scala +++ b/tests/init-global/warn/global-cycle4.scala @@ -7,7 +7,7 @@ class B extends A { } class C extends A { - def foo(): Int = O.a + 10 // error + def foo(): Int = O.a + 10 // warn } class D(x: Int) { diff --git a/tests/init-global/warn/global-cycle5.check b/tests/init-global/warn/global-cycle5.check new file mode 100644 index 000000000000..072a80e4530f --- /dev/null +++ b/tests/init-global/warn/global-cycle5.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/global-cycle5.scala:10:17 ----------------------------------------------------------- +10 | val b: Int = A.a.foo() // warn + | ^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B { [ global-cycle5.scala:9 ] + |│ ^ + |└── val b: Int = A.a.foo() // warn [ global-cycle5.scala:10 ] + | ^^^ diff --git a/tests/init-global/neg/global-cycle5.scala b/tests/init-global/warn/global-cycle5.scala old mode 100755 new mode 100644 similarity index 85% rename from tests/init-global/neg/global-cycle5.scala rename to tests/init-global/warn/global-cycle5.scala index 1ba3435d3830..7c3710cb815b --- a/tests/init-global/neg/global-cycle5.scala +++ b/tests/init-global/warn/global-cycle5.scala @@ -7,7 +7,7 @@ object A { } object B { - val b: Int = A.a.foo() // error + val b: Int = A.a.foo() // warn } class Y extends X { diff --git a/tests/init-global/warn/global-cycle6.check b/tests/init-global/warn/global-cycle6.check new file mode 100644 index 000000000000..b6454a5d2cce --- /dev/null +++ b/tests/init-global/warn/global-cycle6.check @@ -0,0 +1,28 @@ +-- Warning: tests/init-global/warn/global-cycle6.scala:1:7 ------------------------------------------------------------- +1 |object A { // warn + | ^ + | Cyclic initialization: object A -> object B -> object A. Calling trace: + | ├── object A { // warn [ global-cycle6.scala:1 ] + | │ ^ + | ├── val n: Int = B.m [ global-cycle6.scala:2 ] + | │ ^ + | ├── object B { [ global-cycle6.scala:8 ] + | │ ^ + | ├── val a = new A.Inner [ global-cycle6.scala:9 ] + | │ ^^^^^^^^^^^ + | ├── class Inner { [ global-cycle6.scala:3 ] + | │ ^ + | └── println(n) // warn [ global-cycle6.scala:4 ] + | ^ +-- Warning: tests/init-global/warn/global-cycle6.scala:4:12 ------------------------------------------------------------ +4 | println(n) // warn + | ^ + | Access uninitialized field value n. Calling trace: + | ├── object B { [ global-cycle6.scala:8 ] + | │ ^ + | ├── val a = new A.Inner [ global-cycle6.scala:9 ] + | │ ^^^^^^^^^^^ + | ├── class Inner { [ global-cycle6.scala:3 ] + | │ ^ + | └── println(n) // warn [ global-cycle6.scala:4 ] + | ^ diff --git a/tests/init-global/neg/global-cycle6.scala b/tests/init-global/warn/global-cycle6.scala similarity index 79% rename from tests/init-global/neg/global-cycle6.scala rename to tests/init-global/warn/global-cycle6.scala index 36e3ab0b6a94..030e08d37117 100644 --- a/tests/init-global/neg/global-cycle6.scala +++ b/tests/init-global/warn/global-cycle6.scala @@ -1,7 +1,7 @@ -object A { // error +object A { // warn val n: Int = B.m class Inner { - println(n) // error + println(n) // warn } } diff --git a/tests/init-global/warn/global-cycle7.check b/tests/init-global/warn/global-cycle7.check new file mode 100644 index 000000000000..366857885769 --- /dev/null +++ b/tests/init-global/warn/global-cycle7.check @@ -0,0 +1,20 @@ +-- Warning: tests/init-global/warn/global-cycle7.scala:1:7 ------------------------------------------------------------- +1 |object A { // warn + | ^ + | Cyclic initialization: object A -> object B -> object A. Calling trace: + | ├── object A { // warn [ global-cycle7.scala:1 ] + | │ ^ + | ├── val n: Int = B.m [ global-cycle7.scala:2 ] + | │ ^ + | ├── object B { [ global-cycle7.scala:5 ] + | │ ^ + | └── val m: Int = A.n // warn [ global-cycle7.scala:6 ] + | ^ +-- Warning: tests/init-global/warn/global-cycle7.scala:6:17 ------------------------------------------------------------ +6 | val m: Int = A.n // warn + | ^^^ + | Access uninitialized field value n. Calling trace: + | ├── object B { [ global-cycle7.scala:5 ] + | │ ^ + | └── val m: Int = A.n // warn [ global-cycle7.scala:6 ] + | ^^^ diff --git a/tests/init-global/neg/global-cycle7.scala b/tests/init-global/warn/global-cycle7.scala similarity index 80% rename from tests/init-global/neg/global-cycle7.scala rename to tests/init-global/warn/global-cycle7.scala index aea75726fbf7..30b74ceb95c4 100644 --- a/tests/init-global/neg/global-cycle7.scala +++ b/tests/init-global/warn/global-cycle7.scala @@ -1,9 +1,9 @@ -object A { // error +object A { // warn val n: Int = B.m } object B { - val m: Int = A.n // error + val m: Int = A.n // warn } abstract class TokensCommon { diff --git a/tests/init-global/warn/global-cycle8.check b/tests/init-global/warn/global-cycle8.check new file mode 100644 index 000000000000..93c9699c653e --- /dev/null +++ b/tests/init-global/warn/global-cycle8.check @@ -0,0 +1,16 @@ +-- Warning: tests/init-global/warn/global-cycle8.scala:9:7 ------------------------------------------------------------- +9 |object O { // warn + | ^ + | Cyclic initialization: object O -> object P -> object O. Calling trace: + | ├── object O { // warn [ global-cycle8.scala:9 ] + | │ ^ + | ├── println(P.m) [ global-cycle8.scala:11 ] + | │ ^ + | ├── object P { [ global-cycle8.scala:14 ] + | │ ^ + | ├── val m = Q.bar(new B) [ global-cycle8.scala:15 ] + | │ ^^^^^^^^^^^^ + | ├── def bar(b: B) = b.a.foo() [ global-cycle8.scala:19 ] + | │ ^^^^^^^^^ + | └── def foo() = println(O.n) [ global-cycle8.scala:2 ] + | ^ diff --git a/tests/init-global/neg/global-cycle8.scala b/tests/init-global/warn/global-cycle8.scala similarity index 85% rename from tests/init-global/neg/global-cycle8.scala rename to tests/init-global/warn/global-cycle8.scala index 344dc3241395..de4e6620585d 100644 --- a/tests/init-global/neg/global-cycle8.scala +++ b/tests/init-global/warn/global-cycle8.scala @@ -6,7 +6,7 @@ class B { val a = new A } -object O { // error +object O { // warn val n: Int = 10 println(P.m) } diff --git a/tests/init-global/warn/global-irrelevance1.check b/tests/init-global/warn/global-irrelevance1.check new file mode 100644 index 000000000000..447ba6b6b29a --- /dev/null +++ b/tests/init-global/warn/global-irrelevance1.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/global-irrelevance1.scala:5:12 ------------------------------------------------------ +5 | var y = A.x * 2 // warn + | ^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ global-irrelevance1.scala:4 ] + |│ ^ + |└── var y = A.x * 2 // warn [ global-irrelevance1.scala:5 ] + | ^^^ diff --git a/tests/init-global/neg/global-irrelevance1.scala b/tests/init-global/warn/global-irrelevance1.scala similarity index 55% rename from tests/init-global/neg/global-irrelevance1.scala rename to tests/init-global/warn/global-irrelevance1.scala index 903d3b14ae18..d19099f287ba 100644 --- a/tests/init-global/neg/global-irrelevance1.scala +++ b/tests/init-global/warn/global-irrelevance1.scala @@ -2,4 +2,4 @@ object A: var x = 6 object B: - var y = A.x * 2 // error \ No newline at end of file + var y = A.x * 2 // warn \ No newline at end of file diff --git a/tests/init-global/warn/global-irrelevance2.check b/tests/init-global/warn/global-irrelevance2.check new file mode 100644 index 000000000000..156b34fa6aa5 --- /dev/null +++ b/tests/init-global/warn/global-irrelevance2.check @@ -0,0 +1,13 @@ +-- Warning: tests/init-global/warn/global-irrelevance2.scala:5:6 ------------------------------------------------------- +5 | A.x = b * 2 // warn + | ^^^^^^^^^^^^ + | Mutating object A during initialization of object B. + | Mutating other static objects during the initialization of one static object is forbidden. Calling trace: + | ├── object B: [ global-irrelevance2.scala:7 ] + | │ ^ + | ├── new B(10) [ global-irrelevance2.scala:8 ] + | │ ^^^^^^^^^ + | ├── class B(b: Int): [ global-irrelevance2.scala:4 ] + | │ ^ + | └── A.x = b * 2 // warn [ global-irrelevance2.scala:5 ] + | ^^^^^^^^^^^^ diff --git a/tests/init-global/neg/global-irrelevance2.scala b/tests/init-global/warn/global-irrelevance2.scala similarity index 72% rename from tests/init-global/neg/global-irrelevance2.scala rename to tests/init-global/warn/global-irrelevance2.scala index 66b06677b689..9bf7acab4343 100644 --- a/tests/init-global/neg/global-irrelevance2.scala +++ b/tests/init-global/warn/global-irrelevance2.scala @@ -2,7 +2,7 @@ object A: var x = 6 class B(b: Int): - A.x = b * 2 // error + A.x = b * 2 // warn object B: new B(10) diff --git a/tests/init-global/warn/global-irrelevance3.check b/tests/init-global/warn/global-irrelevance3.check new file mode 100644 index 000000000000..dba945224f97 --- /dev/null +++ b/tests/init-global/warn/global-irrelevance3.check @@ -0,0 +1,11 @@ +-- Warning: tests/init-global/warn/global-irrelevance3.scala:9:13 ------------------------------------------------------ +9 | (() => x) // warn + | ^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ global-irrelevance3.scala:13 ] + |│ ^ + |├── var y = A.p.g() [ global-irrelevance3.scala:14 ] + |│ ^^^^^^^ + |└── (() => x) // warn [ global-irrelevance3.scala:9 ] + | ^ diff --git a/tests/init-global/neg/global-irrelevance3.scala b/tests/init-global/warn/global-irrelevance3.scala similarity index 87% rename from tests/init-global/neg/global-irrelevance3.scala rename to tests/init-global/warn/global-irrelevance3.scala index 2f36d65d917e..f8db31f14a72 100644 --- a/tests/init-global/neg/global-irrelevance3.scala +++ b/tests/init-global/warn/global-irrelevance3.scala @@ -6,7 +6,7 @@ object A: var x = 6 new Pair( y => x = y, - (() => x) // error + (() => x) // warn ) diff --git a/tests/init-global/warn/global-irrelevance4.check b/tests/init-global/warn/global-irrelevance4.check new file mode 100644 index 000000000000..7253e5b39688 --- /dev/null +++ b/tests/init-global/warn/global-irrelevance4.check @@ -0,0 +1,11 @@ +-- Warning: tests/init-global/warn/global-irrelevance4.scala:8:9 ------------------------------------------------------- +8 | (y => x = y), // warn + | ^^^^^^^^^^ + | Mutating object A during initialization of object B. + | Mutating other static objects during the initialization of one static object is forbidden. Calling trace: + | ├── object B: [ global-irrelevance4.scala:12 ] + | │ ^ + | ├── A.p.f(10) [ global-irrelevance4.scala:13 ] + | │ ^^^^^^^^^ + | └── (y => x = y), // warn [ global-irrelevance4.scala:8 ] + | ^^^^^^^^^^ diff --git a/tests/init-global/neg/global-irrelevance4.scala b/tests/init-global/warn/global-irrelevance4.scala similarity index 84% rename from tests/init-global/neg/global-irrelevance4.scala rename to tests/init-global/warn/global-irrelevance4.scala index 7a2a778814b2..4ddf3d78e4ae 100644 --- a/tests/init-global/neg/global-irrelevance4.scala +++ b/tests/init-global/warn/global-irrelevance4.scala @@ -5,7 +5,7 @@ object A: def foo(): Pair = var x = 6 new Pair( - (y => x = y), // error + (y => x = y), // warn () => x ) diff --git a/tests/init-global/warn/global-irrelevance5.check b/tests/init-global/warn/global-irrelevance5.check new file mode 100644 index 000000000000..c3581e0b9bbc --- /dev/null +++ b/tests/init-global/warn/global-irrelevance5.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/global-irrelevance5.scala:6:17 ------------------------------------------------------ +6 | var y = A.array(0) * 2 // warn + | ^^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ global-irrelevance5.scala:5 ] + |│ ^ + |└── var y = A.array(0) * 2 // warn [ global-irrelevance5.scala:6 ] + | ^^^^^^^^^^ diff --git a/tests/init-global/neg/global-irrelevance5.scala b/tests/init-global/warn/global-irrelevance5.scala similarity index 69% rename from tests/init-global/neg/global-irrelevance5.scala rename to tests/init-global/warn/global-irrelevance5.scala index fd5bde3032aa..f557157ded21 100644 --- a/tests/init-global/neg/global-irrelevance5.scala +++ b/tests/init-global/warn/global-irrelevance5.scala @@ -3,4 +3,4 @@ object A: array(0) = 10 object B: - var y = A.array(0) * 2 // error + var y = A.array(0) * 2 // warn diff --git a/tests/init-global/warn/global-irrelevance6.check b/tests/init-global/warn/global-irrelevance6.check new file mode 100644 index 000000000000..3e447a915ba3 --- /dev/null +++ b/tests/init-global/warn/global-irrelevance6.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/global-irrelevance6.scala:9:17 ------------------------------------------------------ +9 | var y = A.array(0).foo() * 2 // warn + | ^^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ global-irrelevance6.scala:8 ] + |│ ^ + |└── var y = A.array(0).foo() * 2 // warn [ global-irrelevance6.scala:9 ] + | ^^^^^^^^^^ diff --git a/tests/init-global/neg/global-irrelevance6.scala b/tests/init-global/warn/global-irrelevance6.scala similarity index 78% rename from tests/init-global/neg/global-irrelevance6.scala rename to tests/init-global/warn/global-irrelevance6.scala index 78699b6988b6..43983f05ffac 100644 --- a/tests/init-global/neg/global-irrelevance6.scala +++ b/tests/init-global/warn/global-irrelevance6.scala @@ -6,4 +6,4 @@ object A: val n = array(0).foo() // ok, no crash object B: - var y = A.array(0).foo() * 2 // error + var y = A.array(0).foo() * 2 // warn diff --git a/tests/init-global/warn/global-irrelevance7.check b/tests/init-global/warn/global-irrelevance7.check new file mode 100644 index 000000000000..c5f0da1a204b --- /dev/null +++ b/tests/init-global/warn/global-irrelevance7.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/global-irrelevance7.scala:10:17 ----------------------------------------------------- +10 | var y = A.array(0).foo() * 2 // warn + | ^^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ global-irrelevance7.scala:9 ] + |│ ^ + |└── var y = A.array(0).foo() * 2 // warn [ global-irrelevance7.scala:10 ] + | ^^^^^^^^^^ diff --git a/tests/init-global/neg/global-irrelevance7.scala b/tests/init-global/warn/global-irrelevance7.scala similarity index 80% rename from tests/init-global/neg/global-irrelevance7.scala rename to tests/init-global/warn/global-irrelevance7.scala index 2c860cbc4259..5f92dde9a3f9 100644 --- a/tests/init-global/neg/global-irrelevance7.scala +++ b/tests/init-global/warn/global-irrelevance7.scala @@ -7,4 +7,4 @@ object A: val n = array(0).foo() // ok object B: - var y = A.array(0).foo() * 2 // error + var y = A.array(0).foo() * 2 // warn diff --git a/tests/init-global/warn/global-list.check b/tests/init-global/warn/global-list.check new file mode 100644 index 000000000000..f8a57918e411 --- /dev/null +++ b/tests/init-global/warn/global-list.check @@ -0,0 +1,36 @@ +-- Warning: tests/init-global/warn/global-list.scala:3:7 --------------------------------------------------------------- +3 |object O: // warn + | ^ + | Cyclic initialization: object O -> object Foo -> object O. Calling trace: + | ├── object O: // warn [ global-list.scala:3 ] + | │ ^ + | ├── val a = Foo("Apple") [ global-list.scala:4 ] + | │ ^^^ + | ├── object Foo: [ global-list.scala:8 ] + | │ ^ + | └── val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn [ global-list.scala:9 ] + | ^ +-- Warning: tests/init-global/warn/global-list.scala:9:30 -------------------------------------------------------------- +9 | val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn + | ^^^ + | Access uninitialized field value a. Calling trace: + | ├── object Foo: [ global-list.scala:8 ] + | │ ^ + | └── val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn [ global-list.scala:9 ] + | ^^^ +-- Warning: tests/init-global/warn/global-list.scala:9:35 -------------------------------------------------------------- +9 | val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn + | ^^^ + | Access uninitialized field value b. Calling trace: + | ├── object Foo: [ global-list.scala:8 ] + | │ ^ + | └── val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn [ global-list.scala:9 ] + | ^^^ +-- Warning: tests/init-global/warn/global-list.scala:9:40 -------------------------------------------------------------- +9 | val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn + | ^^^ + | Access uninitialized field value c. Calling trace: + | ├── object Foo: [ global-list.scala:8 ] + | │ ^ + | └── val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn [ global-list.scala:9 ] + | ^^^ diff --git a/tests/init-global/neg/global-list.scala b/tests/init-global/warn/global-list.scala old mode 100755 new mode 100644 similarity index 52% rename from tests/init-global/neg/global-list.scala rename to tests/init-global/warn/global-list.scala index cdef6dbf3bbe..8202d03584a9 --- a/tests/init-global/neg/global-list.scala +++ b/tests/init-global/warn/global-list.scala @@ -1,9 +1,9 @@ case class Foo(name: String) -object O: // error +object O: // warn val a = Foo("Apple") val b = Foo("Banana") val c = Foo("Cherry") object Foo: - val all: List[Foo] = List(O.a, O.b, O.c) // error // error // error \ No newline at end of file + val all: List[Foo] = List(O.a, O.b, O.c) // warn // warn // warn \ No newline at end of file diff --git a/tests/init-global/warn/global-local-var.check b/tests/init-global/warn/global-local-var.check new file mode 100644 index 000000000000..028ad87e6716 --- /dev/null +++ b/tests/init-global/warn/global-local-var.check @@ -0,0 +1,12 @@ +-- Warning: tests/init-global/warn/global-local-var.scala:10:6 --------------------------------------------------------- +10 | B.a + 10 + sum // warn + | ^^^ + | Access uninitialized field value a. Calling trace: + | ├── object B { [ global-local-var.scala:14 ] + | │ ^ + | ├── val a: Int = A(4).foo() [ global-local-var.scala:15 ] + | │ ^^^^^^^^^^ + | ├── def foo(): Int = { [ global-local-var.scala:2 ] + | │ ^ + | └── B.a + 10 + sum // warn [ global-local-var.scala:10 ] + | ^^^ diff --git a/tests/init-global/neg/global-local-var.scala b/tests/init-global/warn/global-local-var.scala similarity index 85% rename from tests/init-global/neg/global-local-var.scala rename to tests/init-global/warn/global-local-var.scala index 6965a42bd37f..384694d7aa15 100644 --- a/tests/init-global/neg/global-local-var.scala +++ b/tests/init-global/warn/global-local-var.scala @@ -7,7 +7,7 @@ class A(x: Int) { sum += i i += 1 - B.a + 10 + sum // error + B.a + 10 + sum // warn } } diff --git a/tests/init-global/warn/global-region1.check b/tests/init-global/warn/global-region1.check new file mode 100644 index 000000000000..342de87cfa05 --- /dev/null +++ b/tests/init-global/warn/global-region1.check @@ -0,0 +1,10 @@ +-- Warning: tests/init-global/warn/global-region1.scala:3:51 ----------------------------------------------------------- +3 |class D(var y: Int) extends B { def foo(): Int = A.m } // warn + | ^^^ + | Access uninitialized field value m. Calling trace: + | ├── object A: [ global-region1.scala:6 ] + | │ ^ + | ├── val m: Int = box1.value.foo() [ global-region1.scala:9 ] + | │ ^^^^^^^^^^^^^^^^ + | └── class D(var y: Int) extends B { def foo(): Int = A.m } // warn [ global-region1.scala:3 ] + | ^^^ diff --git a/tests/init-global/neg/global-region1.scala b/tests/init-global/warn/global-region1.scala similarity index 76% rename from tests/init-global/neg/global-region1.scala rename to tests/init-global/warn/global-region1.scala index 48473717b5b5..91789507a373 100644 --- a/tests/init-global/neg/global-region1.scala +++ b/tests/init-global/warn/global-region1.scala @@ -1,6 +1,6 @@ trait B { def foo(): Int } class C(var x: Int) extends B { def foo(): Int = 20 } -class D(var y: Int) extends B { def foo(): Int = A.m } // error +class D(var y: Int) extends B { def foo(): Int = A.m } // warn class Box(var value: B) object A: diff --git a/tests/init-global/warn/i11262.check b/tests/init-global/warn/i11262.check new file mode 100644 index 000000000000..ac80445e9886 --- /dev/null +++ b/tests/init-global/warn/i11262.check @@ -0,0 +1,14 @@ +-- Warning: tests/init-global/warn/i11262.scala:1:7 -------------------------------------------------------------------- +1 |object A { val x: String = B.y } // warn + | ^ + | Cyclic initialization: object A -> object B -> object A. Calling trace: + | ├── object A { val x: String = B.y } // warn [ i11262.scala:1 ] + | │ ^ + | └── object B { val y: String = A.x } // warn [ i11262.scala:2 ] + | ^ +-- Warning: tests/init-global/warn/i11262.scala:2:29 ------------------------------------------------------------------- +2 |object B { val y: String = A.x } // warn + | ^^^ + | Access uninitialized field value x. Calling trace: + | └── object B { val y: String = A.x } // warn [ i11262.scala:2 ] + | ^^^ diff --git a/tests/init-global/warn/i11262.scala b/tests/init-global/warn/i11262.scala new file mode 100644 index 000000000000..896e4db4a0ed --- /dev/null +++ b/tests/init-global/warn/i11262.scala @@ -0,0 +1,2 @@ +object A { val x: String = B.y } // warn +object B { val y: String = A.x } // warn diff --git a/tests/init-global/warn/i12544b.check b/tests/init-global/warn/i12544b.check new file mode 100644 index 000000000000..9f97ea36f7fa --- /dev/null +++ b/tests/init-global/warn/i12544b.check @@ -0,0 +1,20 @@ +-- Warning: tests/init-global/warn/i12544b.scala:5:9 ------------------------------------------------------------------- +5 | object nested: // warn + | ^ + | Cyclic initialization: object nested -> object Enum -> object nested. Calling trace: + | ├── object nested: // warn [ i12544b.scala:5 ] + | │ ^ + | ├── val a: Enum = Case [ i12544b.scala:6 ] + | │ ^^^^ + | ├── object Enum: [ i12544b.scala:4 ] + | │ ^ + | └── val b: Enum = f(nested.a) // warn [ i12544b.scala:8 ] + | ^^^^^^ +-- Warning: tests/init-global/warn/i12544b.scala:8:25 ------------------------------------------------------------------ +8 | val b: Enum = f(nested.a) // warn + | ^^^^^^^^ + | Access uninitialized field value a. Calling trace: + | ├── object Enum: [ i12544b.scala:4 ] + | │ ^ + | └── val b: Enum = f(nested.a) // warn [ i12544b.scala:8 ] + | ^^^^^^^^ diff --git a/tests/init-global/neg/i12544b.scala b/tests/init-global/warn/i12544b.scala similarity index 62% rename from tests/init-global/neg/i12544b.scala rename to tests/init-global/warn/i12544b.scala index 586b88df04bd..e79e9b400353 100644 --- a/tests/init-global/neg/i12544b.scala +++ b/tests/init-global/warn/i12544b.scala @@ -2,10 +2,10 @@ enum Enum: case Case object Enum: - object nested: // error + object nested: // warn val a: Enum = Case - val b: Enum = f(nested.a) // error + val b: Enum = f(nested.a) // warn def f(e: Enum): Enum = e diff --git a/tests/init-global/warn/i15883.scala b/tests/init-global/warn/i15883.scala new file mode 100644 index 000000000000..23128a745332 --- /dev/null +++ b/tests/init-global/warn/i15883.scala @@ -0,0 +1,2 @@ +val a = b // warn +val b = 1 diff --git a/tests/init-global/neg/i18628.scala b/tests/init-global/warn/i18628.scala similarity index 69% rename from tests/init-global/neg/i18628.scala rename to tests/init-global/warn/i18628.scala index 798b3204338c..afd5c14d0b7d 100644 --- a/tests/init-global/neg/i18628.scala +++ b/tests/init-global/warn/i18628.scala @@ -2,6 +2,6 @@ object Test: class Box(val x: Int) def recur(a: => Box, b: => Box): Int = - a.x + recur(a, b) + b.x // error // error + a.x + recur(a, b) + b.x // warn // warn recur(Box(1), Box(2)) \ No newline at end of file diff --git a/tests/init-global/neg/i18628_2.scala b/tests/init-global/warn/i18628_2.scala similarity index 73% rename from tests/init-global/neg/i18628_2.scala rename to tests/init-global/warn/i18628_2.scala index 4ad428035441..7f90f51ccc1a 100644 --- a/tests/init-global/neg/i18628_2.scala +++ b/tests/init-global/warn/i18628_2.scala @@ -2,6 +2,6 @@ object Test: class Box(val x: Int) def recur(a: => Box, b: Box): Int = - a.x + recur(a, b) + b.x // error + a.x + recur(a, b) + b.x // warn recur(Box(1), Box(2)) diff --git a/tests/init-global/neg/i18628_3.scala b/tests/init-global/warn/i18628_3.scala similarity index 67% rename from tests/init-global/neg/i18628_3.scala rename to tests/init-global/warn/i18628_3.scala index 101674cffb6f..0a14c7d4c73e 100644 --- a/tests/init-global/neg/i18628_3.scala +++ b/tests/init-global/warn/i18628_3.scala @@ -4,6 +4,6 @@ object Test: class Box(val x: Int) def recur(a: => Box, b: => Box): Int = - a.x + recur(a: @widen(5), b: @widen(5)) + b.x // error // error + a.x + recur(a: @widen(5), b: @widen(5)) + b.x // warn // warn recur(Box(1), Box(2)) \ No newline at end of file diff --git a/tests/init-global/warn/i9176.check b/tests/init-global/warn/i9176.check new file mode 100644 index 000000000000..05a208d1f8a1 --- /dev/null +++ b/tests/init-global/warn/i9176.check @@ -0,0 +1,8 @@ +-- Warning: tests/init-global/warn/i9176.scala:2:12 -------------------------------------------------------------------- +2 |case object A extends Foo(B) // warn + | ^ + | Cyclic initialization: object A -> object B -> object A. Calling trace: + | ├── case object A extends Foo(B) // warn [ i9176.scala:2 ] + | │ ^ + | └── case object B extends Foo(A) [ i9176.scala:3 ] + | ^ diff --git a/tests/init-global/neg/i9176.scala b/tests/init-global/warn/i9176.scala similarity index 81% rename from tests/init-global/neg/i9176.scala rename to tests/init-global/warn/i9176.scala index c93a16f2f8b1..86b65f6d8c0f 100644 --- a/tests/init-global/neg/i9176.scala +++ b/tests/init-global/warn/i9176.scala @@ -1,5 +1,5 @@ class Foo(val opposite: Foo) -case object A extends Foo(B) // error +case object A extends Foo(B) // warn case object B extends Foo(A) object Test { def main(args: Array[String]): Unit = { diff --git a/tests/init-global/neg/lazy-local-val.scala b/tests/init-global/warn/lazy-local-val.scala similarity index 78% rename from tests/init-global/neg/lazy-local-val.scala rename to tests/init-global/warn/lazy-local-val.scala index 2a645ae78db1..30ae864ab169 100644 --- a/tests/init-global/neg/lazy-local-val.scala +++ b/tests/init-global/warn/lazy-local-val.scala @@ -5,7 +5,7 @@ object A: val b = a Box(b) - val box = f(n) // error + val box = f(n) // warn val n = 10 object B: @@ -15,5 +15,5 @@ object B: lazy val b = a Box(b) - val box = f(n) // error + val box = f(n) // warn val n = 10 diff --git a/tests/init-global/neg/line-spacing.check b/tests/init-global/warn/line-spacing.check similarity index 71% rename from tests/init-global/neg/line-spacing.check rename to tests/init-global/warn/line-spacing.check index 6fa8801bb07b..c38f89ddc69e 100644 --- a/tests/init-global/neg/line-spacing.check +++ b/tests/init-global/warn/line-spacing.check @@ -1,6 +1,6 @@ --- Error: tests/init-global/neg/line-spacing.scala:4:7 ----------------------------------------------------------------- +-- Warning: tests/init-global/warn/line-spacing.scala:4:7 -------------------------------------------------------------- 3 | B -4 | .s.length // error +4 | .s.length // warn | ^ | Access uninitialized field value s. Calling trace: | ├── object B { [ line-spacing.scala:7 ] @@ -9,5 +9,5 @@ | │ ^^^ | ├── def a: Int = [ line-spacing.scala:2 ] | │ ^ - | └── .s.length // error [ line-spacing.scala:4 ] + | └── .s.length // warn [ line-spacing.scala:4 ] | ^ diff --git a/tests/init-global/neg/line-spacing.scala b/tests/init-global/warn/line-spacing.scala similarity index 75% rename from tests/init-global/neg/line-spacing.scala rename to tests/init-global/warn/line-spacing.scala index 42474decb53c..cfea71b2ee59 100644 --- a/tests/init-global/neg/line-spacing.scala +++ b/tests/init-global/warn/line-spacing.scala @@ -1,7 +1,7 @@ object A { def a: Int = B - .s.length // error + .s.length // warn } object B { diff --git a/tests/init-global/warn/mutable-array.check b/tests/init-global/warn/mutable-array.check new file mode 100644 index 000000000000..fb96b33c85a9 --- /dev/null +++ b/tests/init-global/warn/mutable-array.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/mutable-array.scala:8:19 ------------------------------------------------------------ +8 | val x: Int = box.value // warn + | ^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ mutable-array.scala:5 ] + |│ ^ + |└── val x: Int = box.value // warn [ mutable-array.scala:8 ] + | ^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-array.scala b/tests/init-global/warn/mutable-array.scala similarity index 81% rename from tests/init-global/neg/mutable-array.scala rename to tests/init-global/warn/mutable-array.scala index 3cbc23a5e127..a0ea2ea0f465 100644 --- a/tests/init-global/neg/mutable-array.scala +++ b/tests/init-global/warn/mutable-array.scala @@ -5,4 +5,4 @@ object A: object B: val boxes: Array[A.Box] = Array(A.box) val box: A.Box = boxes(0) - val x: Int = box.value // error + val x: Int = box.value // warn diff --git a/tests/init-global/warn/mutable-read1.check b/tests/init-global/warn/mutable-read1.check new file mode 100644 index 000000000000..e141ced0c70d --- /dev/null +++ b/tests/init-global/warn/mutable-read1.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/mutable-read1.scala:10:20 ----------------------------------------------------------- +10 | val n: Int = boxA.value // warn + | ^^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ mutable-read1.scala:6 ] + |│ ^ + |└── val n: Int = boxA.value // warn [ mutable-read1.scala:10 ] + | ^^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-read1.scala b/tests/init-global/warn/mutable-read1.scala old mode 100755 new mode 100644 similarity index 82% rename from tests/init-global/neg/mutable-read1.scala rename to tests/init-global/warn/mutable-read1.scala index 507a8b7d74ad..82bcfb3918c7 --- a/tests/init-global/neg/mutable-read1.scala +++ b/tests/init-global/warn/mutable-read1.scala @@ -7,4 +7,4 @@ object B: val boxB: Box = new Box(5) val boxA: Box = A.box val m: Int = boxB.value - val n: Int = boxA.value // error \ No newline at end of file + val n: Int = boxA.value // warn \ No newline at end of file diff --git a/tests/init-global/warn/mutable-read2.check b/tests/init-global/warn/mutable-read2.check new file mode 100644 index 000000000000..906a82ec09a5 --- /dev/null +++ b/tests/init-global/warn/mutable-read2.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/mutable-read2.scala:10:19 ----------------------------------------------------------- +10 | val b: Int = box.value // warn + | ^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ mutable-read2.scala:7 ] + |│ ^ + |└── val b: Int = box.value // warn [ mutable-read2.scala:10 ] + | ^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-read2.scala b/tests/init-global/warn/mutable-read2.scala old mode 100755 new mode 100644 similarity index 83% rename from tests/init-global/neg/mutable-read2.scala rename to tests/init-global/warn/mutable-read2.scala index e7653c63d8bb..3337bd3e30bb --- a/tests/init-global/neg/mutable-read2.scala +++ b/tests/init-global/warn/mutable-read2.scala @@ -7,4 +7,4 @@ object A: object B: val box: A.Box = A.box val a: Int = box.initial - val b: Int = box.value // error \ No newline at end of file + val b: Int = box.value // warn \ No newline at end of file diff --git a/tests/init-global/warn/mutable-read3.check b/tests/init-global/warn/mutable-read3.check new file mode 100644 index 000000000000..754196794a1f --- /dev/null +++ b/tests/init-global/warn/mutable-read3.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/mutable-read3.scala:9:19 ------------------------------------------------------------ +9 | val x: Int = box.value // warn + | ^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ mutable-read3.scala:5 ] + |│ ^ + |└── val x: Int = box.value // warn [ mutable-read3.scala:9 ] + | ^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-read3.scala b/tests/init-global/warn/mutable-read3.scala old mode 100755 new mode 100644 similarity index 83% rename from tests/init-global/neg/mutable-read3.scala rename to tests/init-global/warn/mutable-read3.scala index d103e112f372..7f0cbb3664c0 --- a/tests/init-global/neg/mutable-read3.scala +++ b/tests/init-global/warn/mutable-read3.scala @@ -6,4 +6,4 @@ object B: val boxes: Array[A.Box] = new Array(1) boxes(0) = A.box val box: A.Box = boxes(0) - val x: Int = box.value // error \ No newline at end of file + val x: Int = box.value // warn \ No newline at end of file diff --git a/tests/init-global/warn/mutable-read4.check b/tests/init-global/warn/mutable-read4.check new file mode 100644 index 000000000000..0ccb8e61549d --- /dev/null +++ b/tests/init-global/warn/mutable-read4.check @@ -0,0 +1,9 @@ +-- Warning: tests/init-global/warn/mutable-read4.scala:10:20 ----------------------------------------------------------- +10 | val n: Int = boxA.value // warn + | ^^^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ mutable-read4.scala:6 ] + |│ ^ + |└── val n: Int = boxA.value // warn [ mutable-read4.scala:10 ] + | ^^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-read4.scala b/tests/init-global/warn/mutable-read4.scala old mode 100755 new mode 100644 similarity index 82% rename from tests/init-global/neg/mutable-read4.scala rename to tests/init-global/warn/mutable-read4.scala index 507a8b7d74ad..82bcfb3918c7 --- a/tests/init-global/neg/mutable-read4.scala +++ b/tests/init-global/warn/mutable-read4.scala @@ -7,4 +7,4 @@ object B: val boxB: Box = new Box(5) val boxA: Box = A.box val m: Int = boxB.value - val n: Int = boxA.value // error \ No newline at end of file + val n: Int = boxA.value // warn \ No newline at end of file diff --git a/tests/init-global/warn/mutable-read5.check b/tests/init-global/warn/mutable-read5.check new file mode 100644 index 000000000000..ffbf1c71fc2c --- /dev/null +++ b/tests/init-global/warn/mutable-read5.check @@ -0,0 +1,11 @@ +-- Warning: tests/init-global/warn/mutable-read5.scala:4:38 ------------------------------------------------------------ +4 | def name(s: String): Name = Name(0, chrs.length) // warn + | ^^^^ + |Reading mutable state of object Names during initialization of object StdNames. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object StdNames: [ mutable-read5.scala:6 ] + |│ ^ + |├── val AnyRef: Names.Name = Names.name("AnyRef") [ mutable-read5.scala:7 ] + |│ ^^^^^^^^^^^^^^^^^^^^ + |└── def name(s: String): Name = Name(0, chrs.length) // warn [ mutable-read5.scala:4 ] + | ^^^^ diff --git a/tests/init-global/neg/mutable-read5.scala b/tests/init-global/warn/mutable-read5.scala old mode 100755 new mode 100644 similarity index 81% rename from tests/init-global/neg/mutable-read5.scala rename to tests/init-global/warn/mutable-read5.scala index c166295bf9fa..10977cc9cc5c --- a/tests/init-global/neg/mutable-read5.scala +++ b/tests/init-global/warn/mutable-read5.scala @@ -1,7 +1,7 @@ object Names: class Name(val start: Int, val length: Int) var chrs: Array[Char] = new Array[Char](0x20000) - def name(s: String): Name = Name(0, chrs.length) // error + def name(s: String): Name = Name(0, chrs.length) // warn object StdNames: val AnyRef: Names.Name = Names.name("AnyRef") diff --git a/tests/init-global/warn/mutable-read6.check b/tests/init-global/warn/mutable-read6.check new file mode 100644 index 000000000000..92d2f58c3ecc --- /dev/null +++ b/tests/init-global/warn/mutable-read6.check @@ -0,0 +1,11 @@ +-- Warning: tests/init-global/warn/mutable-read6.scala:7:35 ------------------------------------------------------------ +7 | final def source: SourceFile = _source // warn + | ^^^^^^^ + |Reading mutable state of object Contexts during initialization of object Implicits. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object Implicits: [ mutable-read6.scala:12 ] + |│ ^ + |├── val NoMatchingFailure: SearchFailure = SearchFailure(1, NoContext.source) [ mutable-read6.scala:15 ] + |│ ^^^^^^^^^^^^^^^^ + |└── final def source: SourceFile = _source // warn [ mutable-read6.scala:7 ] + | ^^^^^^^ diff --git a/tests/init-global/neg/mutable-read6.scala b/tests/init-global/warn/mutable-read6.scala old mode 100755 new mode 100644 similarity index 87% rename from tests/init-global/neg/mutable-read6.scala rename to tests/init-global/warn/mutable-read6.scala index 8b00eeaf4216..013f7c998221 --- a/tests/init-global/neg/mutable-read6.scala +++ b/tests/init-global/warn/mutable-read6.scala @@ -4,7 +4,7 @@ object Contexts: val NoContext: Context = new Context class Context: private var _source: SourceFile = null - final def source: SourceFile = _source // error + final def source: SourceFile = _source // warn def setSource(source: SourceFile) = { this._source = source } diff --git a/tests/init-global/warn/mutable-read7.check b/tests/init-global/warn/mutable-read7.check new file mode 100644 index 000000000000..244ed1519cdf --- /dev/null +++ b/tests/init-global/warn/mutable-read7.check @@ -0,0 +1,15 @@ +-- Warning: tests/init-global/warn/mutable-read7.scala:7:17 ------------------------------------------------------------ +7 | if (Positioned.debug) { // warn + | ^^^^^^^^^^^^^^^^ + |Reading mutable state of object Positioned during initialization of object Trees. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object Trees: [ mutable-read7.scala:11 ] + |│ ^ + |├── val emptyTree = new Tree [ mutable-read7.scala:13 ] + |│ ^^^^^^^^ + |├── class Tree extends Positioned [ mutable-read7.scala:12 ] + |│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |├── abstract class Positioned: [ mutable-read7.scala:6 ] + |│ ^ + |└── if (Positioned.debug) { // warn [ mutable-read7.scala:7 ] + | ^^^^^^^^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-read7.scala b/tests/init-global/warn/mutable-read7.scala old mode 100755 new mode 100644 similarity index 86% rename from tests/init-global/neg/mutable-read7.scala rename to tests/init-global/warn/mutable-read7.scala index ad9d154d74f5..952628d8e09c --- a/tests/init-global/neg/mutable-read7.scala +++ b/tests/init-global/warn/mutable-read7.scala @@ -4,7 +4,7 @@ object Positioned: var nextId: Int = 0 abstract class Positioned: - if (Positioned.debug) { // error + if (Positioned.debug) { // warn println("do debugging") } diff --git a/tests/init-global/warn/mutable-read8.check b/tests/init-global/warn/mutable-read8.check new file mode 100644 index 000000000000..4527a2e5e5d8 --- /dev/null +++ b/tests/init-global/warn/mutable-read8.check @@ -0,0 +1,13 @@ +-- Warning: tests/init-global/warn/mutable-read8.scala:6:12 ------------------------------------------------------------ +6 | if (Stats.monitored) println("record stats") // warn + | ^^^^^^^^^^^^^^^ + |Reading mutable state of object Stats during initialization of object NoCompleter. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object NoCompleter extends LazyType [ mutable-read8.scala:11 ] + |│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |├── class LazyType extends UncachedGroundType [ mutable-read8.scala:9 ] + |│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |├── class UncachedGroundType { [ mutable-read8.scala:5 ] + |│ ^ + |└── if (Stats.monitored) println("record stats") // warn [ mutable-read8.scala:6 ] + | ^^^^^^^^^^^^^^^ diff --git a/tests/init-global/neg/mutable-read8.scala b/tests/init-global/warn/mutable-read8.scala old mode 100755 new mode 100644 similarity index 73% rename from tests/init-global/neg/mutable-read8.scala rename to tests/init-global/warn/mutable-read8.scala index e830fa65be73..1481cdb0f83c --- a/tests/init-global/neg/mutable-read8.scala +++ b/tests/init-global/warn/mutable-read8.scala @@ -3,7 +3,7 @@ object Stats { } class UncachedGroundType { - if (Stats.monitored) println("record stats") // error + if (Stats.monitored) println("record stats") // warn } class LazyType extends UncachedGroundType diff --git a/tests/init-global/warn/partial-ordering.check b/tests/init-global/warn/partial-ordering.check new file mode 100644 index 000000000000..1f8ace07f6c3 --- /dev/null +++ b/tests/init-global/warn/partial-ordering.check @@ -0,0 +1,12 @@ +-- Warning: tests/init-global/warn/partial-ordering.scala:1:7 ---------------------------------------------------------- +1 |object Names: // warn + | ^ + | Cyclic initialization: object Names -> object MethodName -> object Names. Calling trace: + | ├── object Names: // warn [ partial-ordering.scala:1 ] + | │ ^ + | ├── val ctorName: MethodName = MethodName.apply(ctorString) [ partial-ordering.scala:3 ] + | │ ^^^^^^^^^^ + | ├── object MethodName: [ partial-ordering.scala:6 ] + | │ ^ + | └── val ctor: MethodName = new MethodName(Names.ctorString) [ partial-ordering.scala:7 ] + | ^^^^^ diff --git a/tests/init-global/neg/partial-ordering.scala b/tests/init-global/warn/partial-ordering.scala old mode 100755 new mode 100644 similarity index 85% rename from tests/init-global/neg/partial-ordering.scala rename to tests/init-global/warn/partial-ordering.scala index 1bc1b251fb72..1c932014bba1 --- a/tests/init-global/neg/partial-ordering.scala +++ b/tests/init-global/warn/partial-ordering.scala @@ -1,4 +1,4 @@ -object Names: // error +object Names: // warn val ctorString = "<init>" val ctorName: MethodName = MethodName.apply(ctorString) diff --git a/tests/init-global/neg/patmat-unapplySeq.check b/tests/init-global/warn/patmat-unapplySeq.check similarity index 68% rename from tests/init-global/neg/patmat-unapplySeq.check rename to tests/init-global/warn/patmat-unapplySeq.check index 8f7a1f64631b..e46de1d60910 100644 --- a/tests/init-global/neg/patmat-unapplySeq.check +++ b/tests/init-global/warn/patmat-unapplySeq.check @@ -1,5 +1,5 @@ --- Error: tests/init-global/neg/patmat-unapplySeq.scala:8:32 ----------------------------------------------------------- -8 | def apply(i: Int): Box = array(i) // error +-- Warning: tests/init-global/warn/patmat-unapplySeq.scala:8:32 -------------------------------------------------------- +8 | def apply(i: Int): Box = array(i) // warn | ^^^^^^^^ |Reading mutable state of object A during initialization of object B. |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: @@ -7,5 +7,5 @@ |│ ^ |├── case A(b) => [ patmat-unapplySeq.scala:17 ] |│ ^^^^ - |└── def apply(i: Int): Box = array(i) // error [ patmat-unapplySeq.scala:8 ] + |└── def apply(i: Int): Box = array(i) // warn [ patmat-unapplySeq.scala:8 ] | ^^^^^^^^ diff --git a/tests/init-global/neg/patmat-unapplySeq.scala b/tests/init-global/warn/patmat-unapplySeq.scala similarity index 84% rename from tests/init-global/neg/patmat-unapplySeq.scala rename to tests/init-global/warn/patmat-unapplySeq.scala index 81c853a6e19f..4c87846c8430 100644 --- a/tests/init-global/neg/patmat-unapplySeq.scala +++ b/tests/init-global/warn/patmat-unapplySeq.scala @@ -5,7 +5,7 @@ object A: array(0) = new Box(10) def length: Int = array.length - def apply(i: Int): Box = array(i) // error + def apply(i: Int): Box = array(i) // warn def drop(n: Int): Seq[Box] = array.toSeq def toSeq: Seq[Box] = array.toSeq diff --git a/tests/init-global/warn/patmat-unapplySeq2.check b/tests/init-global/warn/patmat-unapplySeq2.check new file mode 100644 index 000000000000..5b5c89122f67 --- /dev/null +++ b/tests/init-global/warn/patmat-unapplySeq2.check @@ -0,0 +1,11 @@ +-- Warning: tests/init-global/warn/patmat-unapplySeq2.scala:8:32 ------------------------------------------------------- +8 | def apply(i: Int): Box = array(i) // warn + | ^^^^^^^^ + |Reading mutable state of object A during initialization of object B. + |Reading mutable state of other static objects is forbidden as it breaks initialization-time irrelevance. Calling trace: + |├── object B: [ patmat-unapplySeq2.scala:15 ] + |│ ^ + |├── case A(b*) => [ patmat-unapplySeq2.scala:17 ] + |│ ^^^^^ + |└── def apply(i: Int): Box = array(i) // warn [ patmat-unapplySeq2.scala:8 ] + | ^^^^^^^^ diff --git a/tests/init-global/neg/patmat-unapplySeq2.scala b/tests/init-global/warn/patmat-unapplySeq2.scala similarity index 84% rename from tests/init-global/neg/patmat-unapplySeq2.scala rename to tests/init-global/warn/patmat-unapplySeq2.scala index adab9495db49..7ebf435b5508 100644 --- a/tests/init-global/neg/patmat-unapplySeq2.scala +++ b/tests/init-global/warn/patmat-unapplySeq2.scala @@ -5,7 +5,7 @@ object A: array(0) = new Box(10) def length: Int = array.length - def apply(i: Int): Box = array(i) // error + def apply(i: Int): Box = array(i) // warn def drop(n: Int): Seq[Box] = array.toSeq def toSeq: Seq[Box] = array.toSeq diff --git a/tests/init-global/warn/patmat.check b/tests/init-global/warn/patmat.check new file mode 100644 index 000000000000..603aacdc451c --- /dev/null +++ b/tests/init-global/warn/patmat.check @@ -0,0 +1,26 @@ +-- Warning: tests/init-global/warn/patmat.scala:1:7 -------------------------------------------------------------------- +1 |object A: // warn + | ^ + | Cyclic initialization: object A -> object B -> object A. Calling trace: + | ├── object A: // warn [ patmat.scala:1 ] + | │ ^ + | ├── case Some(x) => println(x * 2 + B.a.size) [ patmat.scala:4 ] + | │ ^ + | ├── object B: [ patmat.scala:7 ] + | │ ^ + | └── if A.a.isEmpty then println(xs.size) [ patmat.scala:12 ] + | ^ +-- Warning: tests/init-global/warn/patmat.scala:29:9 ------------------------------------------------------------------- +29 | object Inner: // warn + | ^ + | Cyclic initialization: object Inner -> object C -> object Inner. Calling trace: + | ├── object Inner: // warn [ patmat.scala:29 ] + | │ ^ + | ├── case Box(f) => f() [ patmat.scala:35 ] + | │ ^^^ + | ├── val foo: () => Int = () => C.a [ patmat.scala:32 ] + | │ ^ + | ├── object C: [ patmat.scala:18 ] + | │ ^ + | └── val a: Int = Inner.b [ patmat.scala:27 ] + | ^^^^^ diff --git a/tests/init-global/neg/patmat.scala b/tests/init-global/warn/patmat.scala similarity index 89% rename from tests/init-global/neg/patmat.scala rename to tests/init-global/warn/patmat.scala index 126e66e7cf7b..6ac51f948464 100644 --- a/tests/init-global/neg/patmat.scala +++ b/tests/init-global/warn/patmat.scala @@ -1,4 +1,4 @@ -object A: // error +object A: // warn val a: Option[Int] = Some(3) a match case Some(x) => println(x * 2 + B.a.size) @@ -26,7 +26,7 @@ object C: val a: Int = Inner.b - object Inner: // error + object Inner: // warn val b: Int = 10 val foo: () => Int = () => C.a diff --git a/tests/init-global/warn/return.check b/tests/init-global/warn/return.check new file mode 100644 index 000000000000..9f84dae62554 --- /dev/null +++ b/tests/init-global/warn/return.check @@ -0,0 +1,10 @@ +-- Warning: tests/init-global/warn/return.scala:4:31 ------------------------------------------------------------------- +4 | return (a: Int) => a + B.n // warn + | ^^^ + | Access uninitialized field value n. Calling trace: + | ├── object B: [ return.scala:8 ] + | │ ^ + | ├── val n = A.foo(-10)(20) [ return.scala:9 ] + | │ ^^^^^^^^^^^^^^ + | └── return (a: Int) => a + B.n // warn [ return.scala:4 ] + | ^^^ diff --git a/tests/init-global/neg/return.scala b/tests/init-global/warn/return.scala old mode 100755 new mode 100644 similarity index 71% rename from tests/init-global/neg/return.scala rename to tests/init-global/warn/return.scala index 5cbf6915fc0e..46f4a6cb4b10 --- a/tests/init-global/neg/return.scala +++ b/tests/init-global/warn/return.scala @@ -1,7 +1,7 @@ object A: def foo(x: Int): Int => Int = if x <= 0 then - return (a: Int) => a + B.n // error + return (a: Int) => a + B.n // warn (a: Int) => a * a + x diff --git a/tests/init-global/warn/return2.check b/tests/init-global/warn/return2.check new file mode 100644 index 000000000000..58f43f383e5d --- /dev/null +++ b/tests/init-global/warn/return2.check @@ -0,0 +1,14 @@ +-- Warning: tests/init-global/warn/return2.scala:3:30 ------------------------------------------------------------------ +3 | val f = (a: Int) => a + B.n // warn + | ^^^ + | Access uninitialized field value n. Calling trace: + | ├── object B: [ return2.scala:12 ] + | │ ^ + | ├── val n = A.foo(-10)(20) [ return2.scala:13 ] + | │ ^^^^^^^^^^^^^^ + | └── val f = (a: Int) => a + B.n // warn [ return2.scala:3 ] + | ^^^ +-- Warning: tests/init-global/warn/return2.scala:6:18 ------------------------------------------------------------------ +6 | val g = () => return f // warn + | ^^^^^^^^ + | Non local returns are no longer supported; use `boundary` and `boundary.break` in `scala.util` instead diff --git a/tests/init-global/neg/return2.scala b/tests/init-global/warn/return2.scala old mode 100755 new mode 100644 similarity index 65% rename from tests/init-global/neg/return2.scala rename to tests/init-global/warn/return2.scala index 6a4dec50c2dd..7c9bdc8dbadb --- a/tests/init-global/neg/return2.scala +++ b/tests/init-global/warn/return2.scala @@ -1,9 +1,9 @@ object A: def foo(x: Int): Int => Int = - val f = (a: Int) => a + B.n // error + val f = (a: Int) => a + B.n // warn var i = 0 - val g = () => return f + val g = () => return f // warn if x <= 0 then g() diff --git a/tests/init-global/warn/t5366.check b/tests/init-global/warn/t5366.check new file mode 100644 index 000000000000..31091a8b7460 --- /dev/null +++ b/tests/init-global/warn/t5366.check @@ -0,0 +1,20 @@ +-- Warning: tests/init-global/warn/t5366.scala:3:12 -------------------------------------------------------------------- +3 |case object ObjA extends IdAndMsg(1) // warn + | ^ + | Cyclic initialization: object ObjA -> object IdAndMsg -> object ObjA. Calling trace: + | ├── case object ObjA extends IdAndMsg(1) // warn [ t5366.scala:3 ] + | │ ^ + | ├── object IdAndMsg { // warn [ t5366.scala:6 ] + | │ ^ + | └── val values = List(ObjA , ObjB) [ t5366.scala:7 ] + | ^^^^ +-- Warning: tests/init-global/warn/t5366.scala:6:7 --------------------------------------------------------------------- +6 |object IdAndMsg { // warn + | ^ + | Cyclic initialization: object IdAndMsg -> object ObjB -> object IdAndMsg. Calling trace: + | ├── object IdAndMsg { // warn [ t5366.scala:6 ] + | │ ^ + | ├── val values = List(ObjA , ObjB) [ t5366.scala:7 ] + | │ ^^^^ + | └── case object ObjB extends IdAndMsg(2) [ t5366.scala:4 ] + | ^ diff --git a/tests/init-global/neg/t5366.scala b/tests/init-global/warn/t5366.scala similarity index 69% rename from tests/init-global/neg/t5366.scala rename to tests/init-global/warn/t5366.scala index 854bdfe0544b..be333cbaf183 100644 --- a/tests/init-global/neg/t5366.scala +++ b/tests/init-global/warn/t5366.scala @@ -1,9 +1,9 @@ class IdAndMsg(val id: Int, val msg: String = "") -case object ObjA extends IdAndMsg(1) // error +case object ObjA extends IdAndMsg(1) // warn case object ObjB extends IdAndMsg(2) -object IdAndMsg { // error +object IdAndMsg { // warn val values = List(ObjA , ObjB) } diff --git a/tests/init-global/warn/t9115.check b/tests/init-global/warn/t9115.check new file mode 100644 index 000000000000..7d85026eb970 --- /dev/null +++ b/tests/init-global/warn/t9115.check @@ -0,0 +1,20 @@ +-- Warning: tests/init-global/warn/t9115.scala:4:14 -------------------------------------------------------------------- +4 | case object D1 extends Z(aaa) // warn + | ^ + | Cyclic initialization: object D1 -> object D -> object D1. Calling trace: + | ├── case object D1 extends Z(aaa) // warn [ t9115.scala:4 ] + | │ ^^^ + | ├── object D { // warn [ t9115.scala:1 ] + | │ ^ + | └── println(D1) [ t9115.scala:6 ] + | ^^ +-- Warning: tests/init-global/warn/t9115.scala:1:7 --------------------------------------------------------------------- +1 |object D { // warn + | ^ + | Cyclic initialization: object D -> object D2 -> object D. Calling trace: + | ├── object D { // warn [ t9115.scala:1 ] + | │ ^ + | ├── println(D2) [ t9115.scala:7 ] + | │ ^^ + | └── case object D2 extends Z(aaa) // 'null' when calling D.D2 first time [ t9115.scala:5 ] + | ^^^ diff --git a/tests/init-global/neg/t9115.scala b/tests/init-global/warn/t9115.scala similarity index 61% rename from tests/init-global/neg/t9115.scala rename to tests/init-global/warn/t9115.scala index a3020c6939a8..a5062c1aa10b 100644 --- a/tests/init-global/neg/t9115.scala +++ b/tests/init-global/warn/t9115.scala @@ -1,7 +1,7 @@ -object D { // error +object D { // warn def aaa = 1 //that’s the reason class Z (depends: Any) - case object D1 extends Z(aaa) // 'null' when calling D.D1 first time // error + case object D1 extends Z(aaa) // warn case object D2 extends Z(aaa) // 'null' when calling D.D2 first time println(D1) println(D2) diff --git a/tests/init-global/warn/t9261.check b/tests/init-global/warn/t9261.check new file mode 100644 index 000000000000..1e8b05d1ffa2 --- /dev/null +++ b/tests/init-global/warn/t9261.check @@ -0,0 +1,8 @@ +-- Warning: tests/init-global/warn/t9261.scala:2:12 -------------------------------------------------------------------- +2 |case object Buy extends OrderType(Sell) // warn + | ^ + | Cyclic initialization: object Buy -> object Sell -> object Buy. Calling trace: + | ├── case object Buy extends OrderType(Sell) // warn [ t9261.scala:2 ] + | │ ^^^^ + | └── case object Sell extends OrderType(Buy) [ t9261.scala:3 ] + | ^^^ diff --git a/tests/init-global/neg/t9261.scala b/tests/init-global/warn/t9261.scala similarity index 63% rename from tests/init-global/neg/t9261.scala rename to tests/init-global/warn/t9261.scala index 1e23bedb9b6a..fcb2f3c62901 100644 --- a/tests/init-global/neg/t9261.scala +++ b/tests/init-global/warn/t9261.scala @@ -1,3 +1,3 @@ sealed abstract class OrderType(val reverse: OrderType) -case object Buy extends OrderType(Sell) // error +case object Buy extends OrderType(Sell) // warn case object Sell extends OrderType(Buy) diff --git a/tests/init-global/warn/t9312.check b/tests/init-global/warn/t9312.check new file mode 100644 index 000000000000..2a2aed6d9a40 --- /dev/null +++ b/tests/init-global/warn/t9312.check @@ -0,0 +1,28 @@ +-- Warning: tests/init-global/warn/t9312.scala:18:11 ------------------------------------------------------------------- +18 | object Child1 extends Child // warn + | ^ + | Cyclic initialization: object Child1 -> object Parent -> object Child1. Calling trace: + | ├── object Child1 extends Child // warn [ t9312.scala:18 ] + | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ├── trait Child { [ t9312.scala:12 ] + | │ ^ + | ├── val parent = Parent [ t9312.scala:14 ] + | │ ^^^^^^ + | ├── object Parent { // warn [ t9312.scala:11 ] + | │ ^ + | └── final val children = Set(Child1, Child2) [ t9312.scala:21 ] + | ^^^^^^ +-- Warning: tests/init-global/warn/t9312.scala:11:9 -------------------------------------------------------------------- +11 | object Parent { // warn + | ^ + | Cyclic initialization: object Parent -> object Child2 -> object Parent. Calling trace: + | ├── object Parent { // warn [ t9312.scala:11 ] + | │ ^ + | ├── final val children = Set(Child1, Child2) [ t9312.scala:21 ] + | │ ^^^^^^ + | ├── object Child2 extends Child [ t9312.scala:19 ] + | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ├── trait Child { [ t9312.scala:12 ] + | │ ^ + | └── val parent = Parent [ t9312.scala:14 ] + | ^^^^^^ diff --git a/tests/init-global/neg/t9312.scala b/tests/init-global/warn/t9312.scala similarity index 83% rename from tests/init-global/neg/t9312.scala rename to tests/init-global/warn/t9312.scala index d88093a2f67a..68282ff9e3e6 100644 --- a/tests/init-global/neg/t9312.scala +++ b/tests/init-global/warn/t9312.scala @@ -8,14 +8,14 @@ object DeadLockTest { } - object Parent { // error + object Parent { // warn trait Child { Thread.sleep(2000) // ensure concurrent behavior val parent = Parent def siblings = parent.children - this } - object Child1 extends Child // error + object Child1 extends Child // warn object Child2 extends Child final val children = Set(Child1, Child2) diff --git a/tests/init-global/warn/t9360.check b/tests/init-global/warn/t9360.check new file mode 100644 index 000000000000..2d77b8c1055a --- /dev/null +++ b/tests/init-global/warn/t9360.check @@ -0,0 +1,20 @@ +-- Warning: tests/init-global/warn/t9360.scala:8:9 --------------------------------------------------------------------- +8 | object AObj extends BaseClass(s) // warn + | ^ + | Cyclic initialization: object AObj -> object Obj -> object AObj. Calling trace: + | ├── object AObj extends BaseClass(s) // warn [ t9360.scala:8 ] + | │ ^ + | ├── object Obj { // warn [ t9360.scala:5 ] + | │ ^ + | └── val list = List(AObj, BObj) [ t9360.scala:12 ] + | ^^^^ +-- Warning: tests/init-global/warn/t9360.scala:5:7 --------------------------------------------------------------------- +5 |object Obj { // warn + | ^ + | Cyclic initialization: object Obj -> object BObj -> object Obj. Calling trace: + | ├── object Obj { // warn [ t9360.scala:5 ] + | │ ^ + | ├── val list = List(AObj, BObj) [ t9360.scala:12 ] + | │ ^^^^ + | └── object BObj extends BaseClass(s) [ t9360.scala:10 ] + | ^ diff --git a/tests/init-global/neg/t9360.scala b/tests/init-global/warn/t9360.scala similarity index 76% rename from tests/init-global/neg/t9360.scala rename to tests/init-global/warn/t9360.scala index 2ec0c740d739..3f5464637457 100644 --- a/tests/init-global/neg/t9360.scala +++ b/tests/init-global/warn/t9360.scala @@ -2,10 +2,10 @@ class BaseClass(s: String) { def print: Unit = () } -object Obj { // error +object Obj { // warn val s: String = "hello" - object AObj extends BaseClass(s) // error + object AObj extends BaseClass(s) // warn object BObj extends BaseClass(s) diff --git a/tests/init-global/warn/unapply-implicit-arg.check b/tests/init-global/warn/unapply-implicit-arg.check new file mode 100644 index 000000000000..37458a878319 --- /dev/null +++ b/tests/init-global/warn/unapply-implicit-arg.check @@ -0,0 +1,8 @@ +-- Warning: tests/init-global/warn/unapply-implicit-arg.scala:11:16 ---------------------------------------------------- +11 | val i2: Int = i2 match // warn + | ^^ + | Access uninitialized field value i2. Calling trace: + | ├── object Bar { [ unapply-implicit-arg.scala:1 ] + | │ ^ + | └── val i2: Int = i2 match // warn [ unapply-implicit-arg.scala:11 ] + | ^^ diff --git a/tests/init-global/neg/unapply-implicit-arg.scala b/tests/init-global/warn/unapply-implicit-arg.scala similarity index 88% rename from tests/init-global/neg/unapply-implicit-arg.scala rename to tests/init-global/warn/unapply-implicit-arg.scala index bf41fbbf9412..89c9fe9e2d04 100644 --- a/tests/init-global/neg/unapply-implicit-arg.scala +++ b/tests/init-global/warn/unapply-implicit-arg.scala @@ -8,7 +8,7 @@ object Bar { given Foo = new Foo val i1: Int = 0 - val i2: Int = i2 match // error + val i2: Int = i2 match // warn case Bar(i) => i case _ => 0 } \ No newline at end of file diff --git a/tests/init-global/warn/unapply-implicit-arg2.check b/tests/init-global/warn/unapply-implicit-arg2.check new file mode 100644 index 000000000000..f04473c64a17 --- /dev/null +++ b/tests/init-global/warn/unapply-implicit-arg2.check @@ -0,0 +1,12 @@ +-- Warning: tests/init-global/warn/unapply-implicit-arg2.scala:7:51 ---------------------------------------------------- +7 | if i == 0 then Some(f1.m1(i1)) else Some(f1.m2(i2)) // warn + | ^^ + | Access uninitialized field value i2. Calling trace: + | ├── object Bar { [ unapply-implicit-arg2.scala:1 ] + | │ ^ + | ├── case Bar(i) => i [ unapply-implicit-arg2.scala:12 ] + | │ ^^^^^^ + | ├── def unapply(using f1: Foo)(i: Int): Option[Int] = [ unapply-implicit-arg2.scala:6 ] + | │ ^ + | └── if i == 0 then Some(f1.m1(i1)) else Some(f1.m2(i2)) // warn [ unapply-implicit-arg2.scala:7 ] + | ^^ diff --git a/tests/init-global/neg/unapply-implicit-arg2.scala b/tests/init-global/warn/unapply-implicit-arg2.scala similarity index 78% rename from tests/init-global/neg/unapply-implicit-arg2.scala rename to tests/init-global/warn/unapply-implicit-arg2.scala index c0a16faac377..bec427d4489d 100644 --- a/tests/init-global/neg/unapply-implicit-arg2.scala +++ b/tests/init-global/warn/unapply-implicit-arg2.scala @@ -4,7 +4,7 @@ object Bar { def m2(i: Int) = i+2 } def unapply(using f1: Foo)(i: Int): Option[Int] = - if i == 0 then Some(f1.m1(i1)) else Some(f1.m2(i2)) // error + if i == 0 then Some(f1.m1(i1)) else Some(f1.m2(i2)) // warn given Foo = new Foo val i1: Int = 0 diff --git a/tests/init-global/warn/unapply-implicit-arg3.check b/tests/init-global/warn/unapply-implicit-arg3.check new file mode 100644 index 000000000000..18503ac0670b --- /dev/null +++ b/tests/init-global/warn/unapply-implicit-arg3.check @@ -0,0 +1,14 @@ +-- Warning: tests/init-global/warn/unapply-implicit-arg3.scala:4:25 ---------------------------------------------------- +4 | def m2(i: Int) = i + i2 // warn + | ^^ + | Access uninitialized field value i2. Calling trace: + | ├── object Bar { [ unapply-implicit-arg3.scala:1 ] + | │ ^ + | ├── case Bar(i) => i [ unapply-implicit-arg3.scala:12 ] + | │ ^^^^^^ + | ├── def unapply(using f1: Foo)(i: Int): Option[Int] = [ unapply-implicit-arg3.scala:6 ] + | │ ^ + | ├── if i == 0 then Some(f1.m1(i)) else Some(f1.m2(i)) [ unapply-implicit-arg3.scala:7 ] + | │ ^^^^^^^^ + | └── def m2(i: Int) = i + i2 // warn [ unapply-implicit-arg3.scala:4 ] + | ^^ diff --git a/tests/init-global/neg/unapply-implicit-arg3.scala b/tests/init-global/warn/unapply-implicit-arg3.scala similarity index 87% rename from tests/init-global/neg/unapply-implicit-arg3.scala rename to tests/init-global/warn/unapply-implicit-arg3.scala index efa348f6cfdb..ae7a7a8315da 100644 --- a/tests/init-global/neg/unapply-implicit-arg3.scala +++ b/tests/init-global/warn/unapply-implicit-arg3.scala @@ -1,7 +1,7 @@ object Bar { class Foo { def m1(i: Int) = i + i1 - def m2(i: Int) = i + i2 // error + def m2(i: Int) = i + i2 // warn } def unapply(using f1: Foo)(i: Int): Option[Int] = if i == 0 then Some(f1.m1(i)) else Some(f1.m2(i)) diff --git a/tests/init-global/warn/unapplySeq-implicit-arg.check b/tests/init-global/warn/unapplySeq-implicit-arg.check new file mode 100644 index 000000000000..ec08187f058f --- /dev/null +++ b/tests/init-global/warn/unapplySeq-implicit-arg.check @@ -0,0 +1,8 @@ +-- Warning: tests/init-global/warn/unapplySeq-implicit-arg.scala:11:20 ------------------------------------------------- +11 | val i2: Int = Seq(i2) match // warn + | ^^ + | Access uninitialized field value i2. Calling trace: + | ├── object Bar { [ unapplySeq-implicit-arg.scala:1 ] + | │ ^ + | └── val i2: Int = Seq(i2) match // warn [ unapplySeq-implicit-arg.scala:11 ] + | ^^ diff --git a/tests/init-global/neg/unapplySeq-implicit-arg.scala b/tests/init-global/warn/unapplySeq-implicit-arg.scala similarity index 89% rename from tests/init-global/neg/unapplySeq-implicit-arg.scala rename to tests/init-global/warn/unapplySeq-implicit-arg.scala index e58635a3090f..1b06fadca63f 100644 --- a/tests/init-global/neg/unapplySeq-implicit-arg.scala +++ b/tests/init-global/warn/unapplySeq-implicit-arg.scala @@ -8,7 +8,7 @@ object Bar { given Foo = new Foo val i1: Int = 0 - val i2: Int = Seq(i2) match // error + val i2: Int = Seq(i2) match // warn case Bar(i) => i case _ => 0 } diff --git a/tests/init-global/warn/unapplySeq-implicit-arg2.check b/tests/init-global/warn/unapplySeq-implicit-arg2.check new file mode 100644 index 000000000000..e75b66495d4b --- /dev/null +++ b/tests/init-global/warn/unapplySeq-implicit-arg2.check @@ -0,0 +1,12 @@ +-- Warning: tests/init-global/warn/unapplySeq-implicit-arg2.scala:4:9 -------------------------------------------------- +4 | Some(i1 +: seqi) // warn + | ^^ + |Access uninitialized field value i1. Calling trace: + |├── object Bar { [ unapplySeq-implicit-arg2.scala:1 ] + |│ ^ + |├── case Bar(i) => i [ unapplySeq-implicit-arg2.scala:7 ] + |│ ^^^^^^ + |├── def unapplySeq(using f1: Foo)(using f2: Foo)(seqi: Seq[Int])(using Foo): Option[Seq[Int]] = [ unapplySeq-implicit-arg2.scala:3 ] + |│ ^ + |└── Some(i1 +: seqi) // warn [ unapplySeq-implicit-arg2.scala:4 ] + | ^^ diff --git a/tests/init-global/neg/unapplySeq-implicit-arg2.scala b/tests/init-global/warn/unapplySeq-implicit-arg2.scala similarity index 87% rename from tests/init-global/neg/unapplySeq-implicit-arg2.scala rename to tests/init-global/warn/unapplySeq-implicit-arg2.scala index 35f5105b84d2..adac49ade28d 100644 --- a/tests/init-global/neg/unapplySeq-implicit-arg2.scala +++ b/tests/init-global/warn/unapplySeq-implicit-arg2.scala @@ -1,7 +1,7 @@ object Bar { class Foo def unapplySeq(using f1: Foo)(using f2: Foo)(seqi: Seq[Int])(using Foo): Option[Seq[Int]] = - Some(i1 +: seqi) // error + Some(i1 +: seqi) // warn given Foo = new Foo val i1: Int = Seq(0) match { case Bar(i) => i diff --git a/tests/init-global/warn/unapplySeq-implicit-arg3.check b/tests/init-global/warn/unapplySeq-implicit-arg3.check new file mode 100644 index 000000000000..7674298a3665 --- /dev/null +++ b/tests/init-global/warn/unapplySeq-implicit-arg3.check @@ -0,0 +1,14 @@ +-- Warning: tests/init-global/warn/unapplySeq-implicit-arg3.scala:3:27 ------------------------------------------------- +3 | def m(seq: Seq[Int]) = i1 +: seq // warn + | ^^ + |Access uninitialized field value i1. Calling trace: + |├── object Bar { [ unapplySeq-implicit-arg3.scala:1 ] + |│ ^ + |├── case Bar(i, _) => i [ unapplySeq-implicit-arg3.scala:9 ] + |│ ^^^^^^^^^ + |├── def unapplySeq(using f1: Foo)(seqi: Seq[Int])(using Foo): Option[Seq[Int]] = [ unapplySeq-implicit-arg3.scala:5 ] + |│ ^ + |├── Some(f1.m(seqi)) [ unapplySeq-implicit-arg3.scala:6 ] + |│ ^^^^^^^^^^ + |└── def m(seq: Seq[Int]) = i1 +: seq // warn [ unapplySeq-implicit-arg3.scala:3 ] + | ^^ diff --git a/tests/init-global/neg/unapplySeq-implicit-arg3.scala b/tests/init-global/warn/unapplySeq-implicit-arg3.scala similarity index 83% rename from tests/init-global/neg/unapplySeq-implicit-arg3.scala rename to tests/init-global/warn/unapplySeq-implicit-arg3.scala index 2b5cdd327e57..ab576ed78149 100644 --- a/tests/init-global/neg/unapplySeq-implicit-arg3.scala +++ b/tests/init-global/warn/unapplySeq-implicit-arg3.scala @@ -1,6 +1,6 @@ object Bar { class Foo { - def m(seq: Seq[Int]) = i1 +: seq // error + def m(seq: Seq[Int]) = i1 +: seq // warn } def unapplySeq(using f1: Foo)(seqi: Seq[Int])(using Foo): Option[Seq[Int]] = Some(f1.m(seqi)) diff --git a/tests/init/neg/early-promote2.scala b/tests/init/neg/early-promote2.scala deleted file mode 100644 index 514aed36a8ed..000000000000 --- a/tests/init/neg/early-promote2.scala +++ /dev/null @@ -1,6 +0,0 @@ -class M { - println(this) // error - foo() - private val a = 5 // error - def foo() = a -} diff --git a/tests/init/neg/simple1.scala b/tests/init/neg/simple1.scala deleted file mode 100644 index 93fba24008b9..000000000000 --- a/tests/init/neg/simple1.scala +++ /dev/null @@ -1,4 +0,0 @@ -class Foo { - val len = name.size - val name: String = "Jack" // error -} \ No newline at end of file diff --git a/tests/init/neg/soundness4.scala b/tests/init/neg/soundness4.scala deleted file mode 100644 index 308856b5e870..000000000000 --- a/tests/init/neg/soundness4.scala +++ /dev/null @@ -1,3 +0,0 @@ -class Foo { - val a : Foo = this.a.a // error -} \ No newline at end of file diff --git a/tests/init/pos/i9795.scala b/tests/init/pos/i9795.scala index 33c13b2eb592..0968dfeb2589 100644 --- a/tests/init/pos/i9795.scala +++ b/tests/init/pos/i9795.scala @@ -2,6 +2,6 @@ class A: // Safe initialization check only allows capturing `this` either through primary constructor or synthetic `apply` // `Some` case class comes from Scala 2 stdlib, which is not visible, hence the warning // For reference: - // https://github.com/lampepfl/dotty/pull/12711 - // https://github.com/lampepfl/dotty/pull/14283 + // https://github.com/scala/scala3/pull/12711 + // https://github.com/scala/scala3/pull/14283 val some = Some(this) diff --git a/tests/init/pos/patternMatcher.scala b/tests/init/pos/patternMatcher.scala index 425c48b71260..99b2acb16df5 100644 --- a/tests/init/pos/patternMatcher.scala +++ b/tests/init/pos/patternMatcher.scala @@ -1,8 +1,6 @@ import scala.collection.mutable class Translater: - val count = new mutable.HashMap[Int, Int] { - override def default(key: Int) = 0 - } + val count = new mutable.HashMap[Int, Int].withDefaultValue(0) count.get(10) val n = 10 diff --git a/tests/init/neg/AbstractFile.scala b/tests/init/warn/AbstractFile.scala similarity index 64% rename from tests/init/neg/AbstractFile.scala rename to tests/init/warn/AbstractFile.scala index f4f38982608a..bb8abc6e8322 100644 --- a/tests/init/neg/AbstractFile.scala +++ b/tests/init/warn/AbstractFile.scala @@ -4,6 +4,6 @@ abstract class AbstractFile { } class RemoteFile(url: String) extends AbstractFile { - val localFile: String = s"${url.##}.tmp" // error: usage of `localFile` before it's initialized + val localFile: String = s"${url.##}.tmp" // warn: usage of `localFile` before it's initialized def name: String = localFile } diff --git a/tests/init/neg/alias.scala b/tests/init/warn/alias.scala similarity index 63% rename from tests/init/neg/alias.scala rename to tests/init/warn/alias.scala index 79367b36d0c5..8e9cb56b75c0 100644 --- a/tests/init/neg/alias.scala +++ b/tests/init/warn/alias.scala @@ -1,5 +1,5 @@ class Foo { val self = this val x = self.n - val n = 10 // error + val n = 10 // warn } \ No newline at end of file diff --git a/tests/init/neg/apply.scala b/tests/init/warn/apply.scala similarity index 85% rename from tests/init/neg/apply.scala rename to tests/init/warn/apply.scala index 2847115cc73c..fffa4c59968f 100644 --- a/tests/init/neg/apply.scala +++ b/tests/init/warn/apply.scala @@ -6,7 +6,7 @@ object A: class B: val a = A(this) - val a2 = A.foo(this) // error + val a2 = A.foo(this) // warn val a3 = A.bar(this) // test receiver is ThisRef @@ -20,7 +20,7 @@ object O: class B: val a = A(this) - val a2 = A.foo(this) // error + val a2 = A.foo(this) // warn val a3 = A.bar(this) val b = new B @@ -38,7 +38,7 @@ class M(n: N): class B: val a = A(this) - val a2 = A.foo(this) // error + val a2 = A.foo(this) // warn val a3 = A.bar(this) end M diff --git a/tests/init/neg/apply2.scala b/tests/init/warn/apply2.scala old mode 100755 new mode 100644 similarity index 75% rename from tests/init/neg/apply2.scala rename to tests/init/warn/apply2.scala index ea312ac6e8c7..efb083cfc863 --- a/tests/init/neg/apply2.scala +++ b/tests/init/warn/apply2.scala @@ -3,7 +3,7 @@ class O: println(n) class B: - val a = A(this) // error + val a = A(this) // warn val b = new B val n = 10 diff --git a/tests/init/neg/as-instance-of-cold-field-access.scala b/tests/init/warn/as-instance-of-cold-field-access.scala similarity index 78% rename from tests/init/neg/as-instance-of-cold-field-access.scala rename to tests/init/warn/as-instance-of-cold-field-access.scala index c8de99e96d0e..caef6f42f623 100644 --- a/tests/init/neg/as-instance-of-cold-field-access.scala +++ b/tests/init/warn/as-instance-of-cold-field-access.scala @@ -1,7 +1,7 @@ final class MyAsInstanceOfClass(o: MyAsInstanceOfClass) { val other: MyAsInstanceOfClass = { if (o.asInstanceOf[MyAsInstanceOfClass].oRef ne null) o - else new MyAsInstanceOfClass(this) // error + else new MyAsInstanceOfClass(this) // warn } val oRef = o } diff --git a/tests/init/neg/by-name-error.scala b/tests/init/warn/by-name-error.scala similarity index 79% rename from tests/init/neg/by-name-error.scala rename to tests/init/warn/by-name-error.scala index 960bbe9bf7e9..8d3a690c7cfd 100644 --- a/tests/init/neg/by-name-error.scala +++ b/tests/init/warn/by-name-error.scala @@ -8,6 +8,6 @@ object Foo { } class A { - val foo = implicitly[Foo] // error + val foo = implicitly[Foo] // warn assert(foo eq foo.next) } \ No newline at end of file diff --git a/tests/init/neg/closureLeak.scala b/tests/init/warn/closureLeak.scala similarity index 83% rename from tests/init/neg/closureLeak.scala rename to tests/init/warn/closureLeak.scala index ae7db5124028..3e4e1f88102b 100644 --- a/tests/init/neg/closureLeak.scala +++ b/tests/init/warn/closureLeak.scala @@ -8,6 +8,6 @@ class Outer { } val l: List[A] = List(new A(5), new A(10)) - l.foreach(a => a.addX(this)) // error + l.foreach(a => a.addX(this)) // warn val p = 10 } diff --git a/tests/init/neg/cold-insert-hot-array.scala b/tests/init/warn/cold-insert-hot-array.scala similarity index 84% rename from tests/init/neg/cold-insert-hot-array.scala rename to tests/init/warn/cold-insert-hot-array.scala index a11d92b2a265..a6c4b4aaebfd 100644 --- a/tests/init/neg/cold-insert-hot-array.scala +++ b/tests/init/warn/cold-insert-hot-array.scala @@ -3,7 +3,7 @@ object A: class B { var a = new Array[B](2) - A.foo(this, a) // error + A.foo(this, a) // warn println(a(0).i) val i = 99 } diff --git a/tests/init/neg/cycle-structure.scala b/tests/init/warn/cycle-structure.scala similarity index 64% rename from tests/init/neg/cycle-structure.scala rename to tests/init/warn/cycle-structure.scala index 1a02a31188b1..f3eb7560f414 100644 --- a/tests/init/neg/cycle-structure.scala +++ b/tests/init/warn/cycle-structure.scala @@ -1,11 +1,11 @@ case class A(b: B) { val x1 = b.x - val x = B(this) // error + val x = B(this) // warn val y = x.a } case class B(a: A) { val x1 = a.x - val x = A(this) // error + val x = A(this) // warn val h = x.b } diff --git a/tests/init/neg/cycle.scala b/tests/init/warn/cycle.scala similarity index 59% rename from tests/init/neg/cycle.scala rename to tests/init/warn/cycle.scala index 7d871795f0a2..f3733df03da4 100644 --- a/tests/init/neg/cycle.scala +++ b/tests/init/warn/cycle.scala @@ -1,11 +1,11 @@ class A(x: B) { println(x.b) - val a = new B(this) // error + val a = new B(this) // warn val d = a.b } class B(x: A) { println(x.a) - val b = new A(this) // error + val b = new A(this) // warn val d = b.a } \ No newline at end of file diff --git a/tests/init/neg/default-this.scala b/tests/init/warn/default-this.scala similarity index 89% rename from tests/init/neg/default-this.scala rename to tests/init/warn/default-this.scala index 1b0173fc134f..26b669bcbd40 100644 --- a/tests/init/neg/default-this.scala +++ b/tests/init/warn/default-this.scala @@ -6,7 +6,7 @@ class A { class B extends A { def updateThenCompare(c: Int): Boolean = { x = c - compare() // error + compare() // warn } val result = updateThenCompare(5) } diff --git a/tests/init/neg/early-promote.scala b/tests/init/warn/early-promote.scala similarity index 84% rename from tests/init/neg/early-promote.scala rename to tests/init/warn/early-promote.scala index fd226df347fb..1cd608d3f63b 100644 --- a/tests/init/neg/early-promote.scala +++ b/tests/init/warn/early-promote.scala @@ -24,7 +24,7 @@ class A { // checking A def c = new C } val b = new B() - println(b) // error: the checker simply issue warnings for objects that contain inner classes + println(b) // warn: the checker simply issue warnings for objects that contain inner classes val af = 42 } diff --git a/tests/init/warn/early-promote2.scala b/tests/init/warn/early-promote2.scala new file mode 100644 index 000000000000..8326aa851e21 --- /dev/null +++ b/tests/init/warn/early-promote2.scala @@ -0,0 +1,6 @@ +class M { + println(this) // warn + foo() + private val a = 5 // warn + def foo() = a +} diff --git a/tests/init/neg/early-promote3.scala b/tests/init/warn/early-promote3.scala similarity index 77% rename from tests/init/neg/early-promote3.scala rename to tests/init/warn/early-promote3.scala index ecb5bbedca69..a81b261d78ba 100644 --- a/tests/init/neg/early-promote3.scala +++ b/tests/init/warn/early-promote3.scala @@ -6,6 +6,6 @@ abstract class A { } class M extends A { - def bar() = promote(this) // error + def bar() = promote(this) // warn def promote(m: M) = m.foo() } diff --git a/tests/init/neg/early-promote4.scala b/tests/init/warn/early-promote4.scala similarity index 87% rename from tests/init/neg/early-promote4.scala rename to tests/init/warn/early-promote4.scala index 487a75c5516f..9d215b308200 100644 --- a/tests/init/neg/early-promote4.scala +++ b/tests/init/warn/early-promote4.scala @@ -16,5 +16,5 @@ class Outer { class Dummy { val m: Int = n + 4 - val n: Int = 10 // error + val n: Int = 10 // warn } diff --git a/tests/init/neg/early-promote5.scala b/tests/init/warn/early-promote5.scala similarity index 80% rename from tests/init/neg/early-promote5.scala rename to tests/init/warn/early-promote5.scala index 3f850b623ea3..bbcc63527fdf 100644 --- a/tests/init/neg/early-promote5.scala +++ b/tests/init/warn/early-promote5.scala @@ -14,11 +14,11 @@ class Outer { class Container { val o = new Outer - val m = new o.M(this) // error + val m = new o.M(this) // warn val s = "hello" } class Dummy { val m: Int = n + 4 - val n: Int = 10 // error + val n: Int = 10 // warn } diff --git a/tests/init/neg/escape1.scala b/tests/init/warn/escape1.scala similarity index 71% rename from tests/init/neg/escape1.scala rename to tests/init/warn/escape1.scala index 588f0933cfc3..ff0cb4ea3816 100644 --- a/tests/init/neg/escape1.scala +++ b/tests/init/warn/escape1.scala @@ -1,5 +1,5 @@ class Foo { - val a = Foo.bar(this) // error + val a = Foo.bar(this) // warn val b = "hello" } diff --git a/tests/init/neg/features-high-order.scala b/tests/init/warn/features-high-order.scala similarity index 81% rename from tests/init/neg/features-high-order.scala rename to tests/init/warn/features-high-order.scala index 60c15545cc14..6f758aeb6785 100644 --- a/tests/init/neg/features-high-order.scala +++ b/tests/init/warn/features-high-order.scala @@ -4,6 +4,6 @@ abstract class Parent { } class Child extends Parent { val a = f() - val b = "hello" // error + val b = "hello" // warn def message: String = b } diff --git a/tests/init/neg/features-linearization.scala b/tests/init/warn/features-linearization.scala similarity index 82% rename from tests/init/neg/features-linearization.scala rename to tests/init/warn/features-linearization.scala index 77d6a231d79a..d3c7b7b0db47 100644 --- a/tests/init/neg/features-linearization.scala +++ b/tests/init/warn/features-linearization.scala @@ -1,5 +1,5 @@ trait TA { - val x = "world" // error + val x = "world" // warn } trait TB { diff --git a/tests/init/neg/features-trees.scala b/tests/init/warn/features-trees.scala similarity index 76% rename from tests/init/neg/features-trees.scala rename to tests/init/warn/features-trees.scala index 867e6636bb12..32026785b3e5 100644 --- a/tests/init/neg/features-trees.scala +++ b/tests/init/warn/features-trees.scala @@ -2,5 +2,5 @@ class Trees { class ValDef { counter += 1 } class EmptyValDef extends ValDef val theEmptyValDef = new EmptyValDef - private var counter = 0 // error + private var counter = 0 // warn } diff --git a/tests/init/neg/final-fields.scala b/tests/init/warn/final-fields.scala similarity index 72% rename from tests/init/neg/final-fields.scala rename to tests/init/warn/final-fields.scala index 7154673058b7..878a1c44c49f 100644 --- a/tests/init/neg/final-fields.scala +++ b/tests/init/warn/final-fields.scala @@ -29,10 +29,10 @@ class Test1 extends U { } class Test extends T { - override final val f1 = /*super.f1*/ 1 + f2 // error - override final val f2 = 2 // error - override final val f3 = {println(3); 3} // error - override val f4 = f3 + 1 // error + override final val f1 = /*super.f1*/ 1 + f2 // warn + override final val f2 = 2 // warn + override final val f3 = {println(3); 3} // warn + override val f4 = f3 + 1 // warn def g: 3 = { println("g"); 3 } final val x = g + 1 diff --git a/tests/init/neg/flow2.scala b/tests/init/warn/flow2.scala similarity index 73% rename from tests/init/neg/flow2.scala rename to tests/init/warn/flow2.scala index a0c5f89601ee..3bb4fa110e50 100644 --- a/tests/init/neg/flow2.scala +++ b/tests/init/warn/flow2.scala @@ -1,6 +1,6 @@ class Foo { val len = list.size - val list = List(4, 6) // error + val list = List(4, 6) // warn lazy val len2 = list2.size // ok val list2 = List(4, 6) diff --git a/tests/init/neg/function-loop.scala b/tests/init/warn/function-loop.scala similarity index 78% rename from tests/init/neg/function-loop.scala rename to tests/init/warn/function-loop.scala index 12048860c3a6..981e8f8215c5 100644 --- a/tests/init/neg/function-loop.scala +++ b/tests/init/warn/function-loop.scala @@ -2,5 +2,5 @@ class Foo { val f: Int => Foo = (x: Int) => if x > 0 then f(x) else this f(10).n - val n = 10 // error + val n = 10 // warn } \ No newline at end of file diff --git a/tests/init/neg/function1.scala b/tests/init/warn/function1.scala similarity index 60% rename from tests/init/neg/function1.scala rename to tests/init/warn/function1.scala index 15427f3de750..29a139b39bd2 100644 --- a/tests/init/neg/function1.scala +++ b/tests/init/warn/function1.scala @@ -4,9 +4,9 @@ class Foo { val fun2: Int => Int = n => 1 + n + list.size fun2(5) - List(5, 9).map(n => 2 + n + list.size) // error + List(5, 9).map(n => 2 + n + list.size) // warn - final val list = List(1, 2, 3) // error + final val list = List(1, 2, 3) // warn List(5, 9).map(n => 3 + n + list.size) } \ No newline at end of file diff --git a/tests/init/neg/function10.scala b/tests/init/warn/function10.scala similarity index 53% rename from tests/init/neg/function10.scala rename to tests/init/warn/function10.scala index 3d8a72aaa1ea..22260bb5d622 100644 --- a/tests/init/neg/function10.scala +++ b/tests/init/warn/function10.scala @@ -1,5 +1,5 @@ class Base { self => - (0 to 10).foreach { i => // error + (0 to 10).foreach { i => // warn println(a) } diff --git a/tests/init/neg/function11.scala b/tests/init/warn/function11.scala similarity index 89% rename from tests/init/neg/function11.scala rename to tests/init/warn/function11.scala index 278192d003aa..a50f7937b562 100644 --- a/tests/init/neg/function11.scala +++ b/tests/init/warn/function11.scala @@ -1,7 +1,7 @@ final class Capture { private var m: Boolean = false - (0 to 10).foreach { i => // error + (0 to 10).foreach { i => // warn f() } diff --git a/tests/init/neg/function2.scala b/tests/init/warn/function2.scala similarity index 70% rename from tests/init/neg/function2.scala rename to tests/init/warn/function2.scala index 0a0f44e2744e..045eb8f4289e 100644 --- a/tests/init/neg/function2.scala +++ b/tests/init/warn/function2.scala @@ -2,5 +2,5 @@ final class Foo { def fun: Int => Int = n => n + x.size fun(5) - val x = "hello" // error + val x = "hello" // warn } \ No newline at end of file diff --git a/tests/init/neg/hybrid1.scala b/tests/init/warn/hybrid1.scala similarity index 87% rename from tests/init/neg/hybrid1.scala rename to tests/init/warn/hybrid1.scala index 94c7a43bfbcd..f1a4665954c9 100644 --- a/tests/init/neg/hybrid1.scala +++ b/tests/init/warn/hybrid1.scala @@ -17,5 +17,5 @@ class Y { new C - val n = 10 // error + val n = 10 // warn } diff --git a/tests/init/neg/hybrid2.scala b/tests/init/warn/hybrid2.scala similarity index 84% rename from tests/init/neg/hybrid2.scala rename to tests/init/warn/hybrid2.scala index a9f8246fd58d..6d901d810a64 100644 --- a/tests/init/neg/hybrid2.scala +++ b/tests/init/warn/hybrid2.scala @@ -15,5 +15,5 @@ class Y { val x = new X x.b.g - val n = 10 // error + val n = 10 // warn } diff --git a/tests/init/neg/hybrid4.scala b/tests/init/warn/hybrid4.scala similarity index 75% rename from tests/init/neg/hybrid4.scala rename to tests/init/warn/hybrid4.scala index 6243fbf2d5f4..8237d0e8244a 100644 --- a/tests/init/neg/hybrid4.scala +++ b/tests/init/warn/hybrid4.scala @@ -8,5 +8,5 @@ class Foo { } val bar: Bar = new Bar - val list = List(1, 2, 3) // error + val list = List(1, 2, 3) // warn } diff --git a/tests/init/neg/hybrid5.scala b/tests/init/warn/hybrid5.scala similarity index 86% rename from tests/init/neg/hybrid5.scala rename to tests/init/warn/hybrid5.scala index 54c781b8835d..4f7f5baad771 100644 --- a/tests/init/neg/hybrid5.scala +++ b/tests/init/warn/hybrid5.scala @@ -15,5 +15,5 @@ class Foo { def g = new Foo.this.Inner } - val list = List(1, 2, 3) // error + val list = List(1, 2, 3) // warn } diff --git a/tests/init/neg/hybrid6.scala b/tests/init/warn/hybrid6.scala similarity index 81% rename from tests/init/neg/hybrid6.scala rename to tests/init/warn/hybrid6.scala index bbecc16942e5..58cbaa76979f 100644 --- a/tests/init/neg/hybrid6.scala +++ b/tests/init/warn/hybrid6.scala @@ -11,5 +11,5 @@ class Foo { def g = list } - val list = List(1, 2, 3) // error + val list = List(1, 2, 3) // warn } diff --git a/tests/init/neg/i10549b.scala b/tests/init/warn/i10549b.scala similarity index 81% rename from tests/init/neg/i10549b.scala rename to tests/init/warn/i10549b.scala index 7353844b3927..b0dd305c7e27 100644 --- a/tests/init/neg/i10549b.scala +++ b/tests/init/warn/i10549b.scala @@ -4,6 +4,6 @@ class Wrap { abstract class E[+T] { def foo: T } object E { final val A: E[Nothing] = new E { def foo = ref } - val ref = qux(A) // error + val ref = qux(A) // warn } } diff --git a/tests/init/neg/i11572.scala b/tests/init/warn/i11572.scala similarity index 90% rename from tests/init/neg/i11572.scala rename to tests/init/warn/i11572.scala index 59fa3c1fbc43..2a32a8bdd540 100644 --- a/tests/init/neg/i11572.scala +++ b/tests/init/warn/i11572.scala @@ -5,7 +5,7 @@ class A { trait Bounded { type T >: Cov[Int] <: Cov[String] } - val t: Bounded = new Bounded { // error + val t: Bounded = new Bounded { // warn // Note: using this instead of t produces an error (as expected) override type T >: t.T <: t.T } diff --git a/tests/init/neg/i12544.scala b/tests/init/warn/i12544.scala similarity index 93% rename from tests/init/neg/i12544.scala rename to tests/init/warn/i12544.scala index 695e57e1d42a..283e0d62203b 100644 --- a/tests/init/neg/i12544.scala +++ b/tests/init/warn/i12544.scala @@ -15,7 +15,7 @@ class Outer: class B() { def foo() = n + 1 } def g(b: B): Int = b.foo() - g(new B()) // error + g(new B()) // warn val n: Int = 10 @main def main(): Unit = { diff --git a/tests/init/neg/i15363.scala b/tests/init/warn/i15363.scala similarity index 78% rename from tests/init/neg/i15363.scala rename to tests/init/warn/i15363.scala index 01a2bdfcf530..87ca08ea916e 100644 --- a/tests/init/neg/i15363.scala +++ b/tests/init/warn/i15363.scala @@ -1,6 +1,6 @@ class A: // should report one error here - val b = new B(this) // error + val b = new B(this) // warn val m = 10 val n = 20 diff --git a/tests/init/neg/i15459.scala b/tests/init/warn/i15459.scala similarity index 81% rename from tests/init/neg/i15459.scala rename to tests/init/warn/i15459.scala index 4d54f31f7af8..72779ef0c7c1 100644 --- a/tests/init/neg/i15459.scala +++ b/tests/init/warn/i15459.scala @@ -1,6 +1,6 @@ class Sup: val a = 10 - println(this) // error + println(this) // warn class Sub extends Sup: val b = 20 diff --git a/tests/init/neg/i4031.scala b/tests/init/warn/i4031.scala similarity index 78% rename from tests/init/neg/i4031.scala rename to tests/init/warn/i4031.scala index ed3f18ac931a..6cb49fcfd93c 100644 --- a/tests/init/neg/i4031.scala +++ b/tests/init/warn/i4031.scala @@ -1,7 +1,7 @@ class App { trait A { type L >: Any} def upcast(a: A, x: Any): a.L = x - val p: A { type L <: Nothing } = p // error + val p: A { type L <: Nothing } = p // warn def coerce(x: Any): Int = upcast(p, x) def main(args: Array[String]): Unit = { diff --git a/tests/init/neg/i4042.scala b/tests/init/warn/i4042.scala similarity index 87% rename from tests/init/neg/i4042.scala rename to tests/init/warn/i4042.scala index 58c884a5690d..284f97a352c9 100644 --- a/tests/init/neg/i4042.scala +++ b/tests/init/warn/i4042.scala @@ -5,7 +5,7 @@ object App { class T[A <: X](val a: A)(val value: a.R) - object O { val x : Y & X = x } // error + object O { val x : Y & X = x } // warn val a = new T[Y & X](O.x)(u) a.value diff --git a/tests/init/neg/i50.scala b/tests/init/warn/i50.scala similarity index 64% rename from tests/init/neg/i50.scala rename to tests/init/warn/i50.scala index 9131fb263f48..7c860bc007fa 100644 --- a/tests/init/neg/i50.scala +++ b/tests/init/warn/i50.scala @@ -1,5 +1,5 @@ class C[T] { val a: T = method def method = b - val b: T = a // error + val b: T = a // warn } \ No newline at end of file diff --git a/tests/init/neg/i5854.scala b/tests/init/warn/i5854.scala similarity index 63% rename from tests/init/neg/i5854.scala rename to tests/init/warn/i5854.scala index 05fa1033dd2c..60060394bdcd 100644 --- a/tests/init/neg/i5854.scala +++ b/tests/init/warn/i5854.scala @@ -1,5 +1,5 @@ class B { val a: String = (((1: Any): b.A): Nothing): String - val b: { type A >: Any <: Nothing } = loop() // error + val b: { type A >: Any <: Nothing } = loop() // warn def loop(): Nothing = loop() } diff --git a/tests/init/neg/inherit-non-hot.scala b/tests/init/warn/inherit-non-hot.scala similarity index 86% rename from tests/init/neg/inherit-non-hot.scala rename to tests/init/warn/inherit-non-hot.scala index 44be67351630..28520ea9c621 100644 --- a/tests/init/neg/inherit-non-hot.scala +++ b/tests/init/warn/inherit-non-hot.scala @@ -3,7 +3,7 @@ object Foo { abstract class A { var b: B = null def toB: B = - if b == null then b = new B(this) // error + if b == null then b = new B(this) // warn b } diff --git a/tests/init/neg/inlined-method.scala b/tests/init/warn/inlined-method.scala similarity index 70% rename from tests/init/neg/inlined-method.scala rename to tests/init/warn/inlined-method.scala index 4af473837f0f..e6ea86ba33c9 100644 --- a/tests/init/neg/inlined-method.scala +++ b/tests/init/warn/inlined-method.scala @@ -5,4 +5,4 @@ class InlineError { object Assertion: transparent inline def failAssert(inline message: => Any): Unit = - scala.runtime.Scala3RunTime.assertFailed(message) // error \ No newline at end of file + scala.runtime.Scala3RunTime.assertFailed(message) // warn \ No newline at end of file diff --git a/tests/init/neg/inner-case.scala b/tests/init/warn/inner-case.scala similarity index 82% rename from tests/init/neg/inner-case.scala rename to tests/init/warn/inner-case.scala index 20a9b1d2684f..317d77376aa9 100644 --- a/tests/init/neg/inner-case.scala +++ b/tests/init/warn/inner-case.scala @@ -4,7 +4,7 @@ class Foo { } val a = Inner(5) // ok - println(a) // error + println(a) // warn var count = 0 println(a) // ok diff --git a/tests/init/neg/inner-first.scala b/tests/init/warn/inner-first.scala similarity index 69% rename from tests/init/neg/inner-first.scala rename to tests/init/warn/inner-first.scala index cd7b28a30b62..be3c7d824dc5 100644 --- a/tests/init/neg/inner-first.scala +++ b/tests/init/warn/inner-first.scala @@ -1,6 +1,6 @@ class A: class B: - println(this) // error + println(this) // warn val n = 10 def foo() = println(m) new B diff --git a/tests/init/neg/inner-loop.scala b/tests/init/warn/inner-loop.scala similarity index 88% rename from tests/init/neg/inner-loop.scala rename to tests/init/warn/inner-loop.scala index c6d5c615580c..8b63eb9507dc 100644 --- a/tests/init/neg/inner-loop.scala +++ b/tests/init/warn/inner-loop.scala @@ -3,7 +3,7 @@ class Outer { outer => val x = 5 + outer.n } val inner = new Inner - val n = 6 // error + val n = 6 // warn } class Outer2 { outer => @@ -28,7 +28,7 @@ class Test { // If we change policy to check more eagerly, // the check has to avoid loop here. - println(outer) // error + println(outer) // warn val m = 10 } \ No newline at end of file diff --git a/tests/init/neg/inner-new.scala b/tests/init/warn/inner-new.scala similarity index 80% rename from tests/init/neg/inner-new.scala rename to tests/init/warn/inner-new.scala index d09dc5193dbf..2ecaf5e544e1 100644 --- a/tests/init/neg/inner-new.scala +++ b/tests/init/warn/inner-new.scala @@ -4,7 +4,7 @@ class Foo { } val a = new Inner // ok - println(a) // error + println(a) // warn var count = 0 println(a) // ok diff --git a/tests/init/neg/inner-pat_iuli.scala b/tests/init/warn/inner-pat_iuli.scala similarity index 92% rename from tests/init/neg/inner-pat_iuli.scala rename to tests/init/warn/inner-pat_iuli.scala index e5010cca98ec..bd84fee43d97 100644 --- a/tests/init/neg/inner-pat_iuli.scala +++ b/tests/init/warn/inner-pat_iuli.scala @@ -20,5 +20,5 @@ trait Blox { self: MyCodes => class MyCodes extends AnyRef with Ops with Blox { val a = b - val b: Int = 10 // error + val b: Int = 10 // warn } diff --git a/tests/init/neg/inner1.scala b/tests/init/warn/inner1.scala similarity index 80% rename from tests/init/neg/inner1.scala rename to tests/init/warn/inner1.scala index d39c3ba2ac77..9220eda882cf 100644 --- a/tests/init/neg/inner1.scala +++ b/tests/init/warn/inner1.scala @@ -1,7 +1,7 @@ class Foo { new this.Inner - val list = List(1, 2, 3) // error, as Inner access `this.list` + val list = List(1, 2, 3) // warn, as Inner access `this.list` val inner: Inner = new this.Inner // ok, `list` is instantiated lib.escape(inner) // ok, can promote inner early diff --git a/tests/init/neg/inner11.scala b/tests/init/warn/inner11.scala similarity index 93% rename from tests/init/neg/inner11.scala rename to tests/init/warn/inner11.scala index 04098be8a3fd..2ea6d25f5d6f 100644 --- a/tests/init/neg/inner11.scala +++ b/tests/init/warn/inner11.scala @@ -12,7 +12,7 @@ object NameKinds { class ClassifiedNameKind(tag: Int, val infoString: String) extends NameKind(tag) { type ThisInfo = Info val info: Info = new Info - println(info.kind) // error + println(info.kind) // warn val n = 10 } } diff --git a/tests/init/neg/inner15.scala b/tests/init/warn/inner15.scala similarity index 84% rename from tests/init/neg/inner15.scala rename to tests/init/warn/inner15.scala index 59d1daac404f..7c01cd8275d7 100644 --- a/tests/init/neg/inner15.scala +++ b/tests/init/warn/inner15.scala @@ -15,5 +15,5 @@ class B extends A { new Inner1 new Inner2 - override val x = "world" // error + override val x = "world" // warn } \ No newline at end of file diff --git a/tests/init/neg/inner16.scala b/tests/init/warn/inner16.scala similarity index 87% rename from tests/init/neg/inner16.scala rename to tests/init/warn/inner16.scala index 61271396a074..c49cba8a88be 100644 --- a/tests/init/neg/inner16.scala +++ b/tests/init/warn/inner16.scala @@ -13,5 +13,5 @@ class A { val inner = new Inner val b = new O.B - val y = 10 // error + val y = 10 // warn } \ No newline at end of file diff --git a/tests/init/neg/inner17.scala b/tests/init/warn/inner17.scala similarity index 78% rename from tests/init/neg/inner17.scala rename to tests/init/warn/inner17.scala index 756278cd5130..4daad38ea36b 100644 --- a/tests/init/neg/inner17.scala +++ b/tests/init/warn/inner17.scala @@ -9,5 +9,5 @@ class A { } class C extends A { - override val f: Int = 20 // error + override val f: Int = 20 // warn } \ No newline at end of file diff --git a/tests/init/neg/inner19.scala b/tests/init/warn/inner19.scala similarity index 79% rename from tests/init/neg/inner19.scala rename to tests/init/warn/inner19.scala index 2e502eddc24c..91cf406dbc6a 100644 --- a/tests/init/neg/inner19.scala +++ b/tests/init/warn/inner19.scala @@ -15,5 +15,5 @@ class A { class B extends A { println((new O.B).f) O.C(4) - override val n = 50 // error because line 16 + override val n = 50 // warn because line 16 } \ No newline at end of file diff --git a/tests/init/neg/inner20.scala b/tests/init/warn/inner20.scala similarity index 84% rename from tests/init/neg/inner20.scala rename to tests/init/warn/inner20.scala index 1553e09eeeb0..2a868f8b88f5 100644 --- a/tests/init/neg/inner20.scala +++ b/tests/init/warn/inner20.scala @@ -14,5 +14,5 @@ class A { class B extends A { val o = new O println((new o.B).f) - override val n = 50 // error + override val n = 50 // warn } \ No newline at end of file diff --git a/tests/init/neg/inner21.scala b/tests/init/warn/inner21.scala similarity index 71% rename from tests/init/neg/inner21.scala rename to tests/init/warn/inner21.scala index c2277163acc3..232de8fbd0cc 100644 --- a/tests/init/neg/inner21.scala +++ b/tests/init/warn/inner21.scala @@ -8,7 +8,7 @@ class X { A.foo A.bar - val name = "jack" // error + val name = "jack" // warn } @@ -22,5 +22,5 @@ class Y { (new A).foo (new A).bar - val name = "jack" // error + val name = "jack" // warn } \ No newline at end of file diff --git a/tests/init/neg/inner22.scala b/tests/init/warn/inner22.scala similarity index 92% rename from tests/init/neg/inner22.scala rename to tests/init/warn/inner22.scala index aa5a381f2d49..055a9d9bed7d 100644 --- a/tests/init/neg/inner22.scala +++ b/tests/init/warn/inner22.scala @@ -28,5 +28,5 @@ class D { new C - val x = 10 // error + val x = 10 // warn } \ No newline at end of file diff --git a/tests/init/neg/inner23.scala b/tests/init/warn/inner23.scala similarity index 77% rename from tests/init/neg/inner23.scala rename to tests/init/warn/inner23.scala index 5d373c649ce2..a5985a8d805c 100644 --- a/tests/init/neg/inner23.scala +++ b/tests/init/warn/inner23.scala @@ -9,5 +9,5 @@ class Trees { } val theEmptyValDef = new EmptyValDef - val name = "hello" // error + val name = "hello" // warn } diff --git a/tests/init/neg/inner24.scala b/tests/init/warn/inner24.scala similarity index 84% rename from tests/init/neg/inner24.scala rename to tests/init/warn/inner24.scala index f8a60c1bb311..3c28546b10cc 100644 --- a/tests/init/neg/inner24.scala +++ b/tests/init/warn/inner24.scala @@ -14,5 +14,5 @@ class Bar extends Foo { val b = new B override def foo(x: Int) = x + id - val id = 100 // error + val id = 100 // warn } \ No newline at end of file diff --git a/tests/init/neg/inner25.scala b/tests/init/warn/inner25.scala similarity index 91% rename from tests/init/neg/inner25.scala rename to tests/init/warn/inner25.scala index 8cf99539b849..a9538dee6462 100644 --- a/tests/init/neg/inner25.scala +++ b/tests/init/warn/inner25.scala @@ -8,7 +8,7 @@ class A[K, V] { self => } } - println(new O) // error + println(new O) // warn val a = 10 } \ No newline at end of file diff --git a/tests/init/neg/inner29.scala b/tests/init/warn/inner29.scala similarity index 83% rename from tests/init/neg/inner29.scala rename to tests/init/warn/inner29.scala index 740352db1e4e..03350a5266b8 100644 --- a/tests/init/neg/inner29.scala +++ b/tests/init/warn/inner29.scala @@ -15,7 +15,7 @@ class C extends B(5) { override def f: Int = x } - val a = new E // error: init too late + val a = new E // warn: init too late val x = 10 } \ No newline at end of file diff --git a/tests/init/neg/inner30.scala b/tests/init/warn/inner30.scala similarity index 92% rename from tests/init/neg/inner30.scala rename to tests/init/warn/inner30.scala index 87d8888437da..d9b1eec3d6b1 100644 --- a/tests/init/neg/inner30.scala +++ b/tests/init/warn/inner30.scala @@ -17,5 +17,5 @@ class Scanners { } val m: Int = n * 2 - val n = 10 // error + val n = 10 // warn } \ No newline at end of file diff --git a/tests/init/neg/inner4.scala b/tests/init/warn/inner4.scala similarity index 77% rename from tests/init/neg/inner4.scala rename to tests/init/warn/inner4.scala index 5fc4d2b9e053..66a39da03909 100644 --- a/tests/init/neg/inner4.scala +++ b/tests/init/warn/inner4.scala @@ -6,5 +6,5 @@ class Foo(val foo1: Foo) { new this.Inner new foo1.Inner - val name = "hello" // error + val name = "hello" // warn } diff --git a/tests/init/neg/inner5.scala b/tests/init/warn/inner5.scala similarity index 76% rename from tests/init/neg/inner5.scala rename to tests/init/warn/inner5.scala index 20f4aa1bdaeb..f91573e98cb6 100644 --- a/tests/init/neg/inner5.scala +++ b/tests/init/warn/inner5.scala @@ -4,7 +4,7 @@ class Foo { } new B - val a = 3 // error + val a = 3 // warn def foo(x: Int) = a + x } \ No newline at end of file diff --git a/tests/init/neg/inner6.scala b/tests/init/warn/inner6.scala similarity index 91% rename from tests/init/neg/inner6.scala rename to tests/init/warn/inner6.scala index 42b68fe2d8ea..7f0436dc6924 100644 --- a/tests/init/neg/inner6.scala +++ b/tests/init/warn/inner6.scala @@ -18,6 +18,6 @@ class Child extends Parent { new InnerA new InnerB - val x = 10 // error + val x = 10 // warn override def foo: Int = x * x } diff --git a/tests/init/neg/inner7.scala b/tests/init/warn/inner7.scala similarity index 81% rename from tests/init/neg/inner7.scala rename to tests/init/warn/inner7.scala index bdac38cc31d8..5e0df53f0888 100644 --- a/tests/init/neg/inner7.scala +++ b/tests/init/warn/inner7.scala @@ -11,6 +11,6 @@ class Child extends Parent { class InnerA extends Inner1 new InnerA - override val list = List(4, 5) // error + override val list = List(4, 5) // warn override def foo: Int = list.size } diff --git a/tests/init/neg/inner9.scala b/tests/init/warn/inner9.scala similarity index 79% rename from tests/init/neg/inner9.scala rename to tests/init/warn/inner9.scala index b572c8cb49d3..64e83ead0b07 100644 --- a/tests/init/neg/inner9.scala +++ b/tests/init/warn/inner9.scala @@ -1,5 +1,5 @@ class Outer: - val flags = new Flags // error + val flags = new Flags // warn class Flags { class Inner { @@ -9,7 +9,7 @@ class Outer: new flags.Inner val a = this.b + 3 - val b = 5 // error + val b = 5 // warn } class Flags2 { diff --git a/tests/init/neg/insert-cold-subtype-to-array.scala b/tests/init/warn/insert-cold-subtype-to-array.scala similarity index 84% rename from tests/init/neg/insert-cold-subtype-to-array.scala rename to tests/init/warn/insert-cold-subtype-to-array.scala index 82eee1935a95..6f4bf9bca73e 100644 --- a/tests/init/neg/insert-cold-subtype-to-array.scala +++ b/tests/init/warn/insert-cold-subtype-to-array.scala @@ -3,6 +3,6 @@ object A: class B: var a = new Array[B](2) - A.foo(this, a) // error + A.foo(this, a) // warn println(a(0).i) val i = 99 \ No newline at end of file diff --git a/tests/init/neg/java1.scala b/tests/init/warn/java1.scala similarity index 91% rename from tests/init/neg/java1.scala rename to tests/init/warn/java1.scala index 1eff09cb6ff1..36044413d2ea 100644 --- a/tests/init/neg/java1.scala +++ b/tests/init/warn/java1.scala @@ -8,4 +8,4 @@ class A extends Spliterator.OfDouble: def tryAdvance(x$0: java.util.function.DoubleConsumer): Boolean = false val m = n + 1 - val n = 10 // error + val n = 10 // warn diff --git a/tests/init/neg/lazy.scala b/tests/init/warn/lazy.scala similarity index 69% rename from tests/init/neg/lazy.scala rename to tests/init/warn/lazy.scala index 0f3047bc0d1b..a895714b0f9a 100644 --- a/tests/init/neg/lazy.scala +++ b/tests/init/warn/lazy.scala @@ -1,11 +1,11 @@ class Foo { val len = list.size - val list = List(4, 6) // error + val list = List(4, 6) // warn lazy val len2 = list2.size // ok val list2 = List(4, 6) lazy val len3 = name.size val len4 = len3 + 4 - val name = "hello" // error + val name = "hello" // warn } diff --git a/tests/init/neg/lazylist2.scala b/tests/init/warn/lazylist2.scala similarity index 89% rename from tests/init/neg/lazylist2.scala rename to tests/init/warn/lazylist2.scala index 18072676fa4c..618364f49a98 100644 --- a/tests/init/neg/lazylist2.scala +++ b/tests/init/warn/lazylist2.scala @@ -26,7 +26,7 @@ final class Test1 { a.head // ok b.head // ok - val x: LazyList[Int] = 5 #:: y // error + val x: LazyList[Int] = 5 #:: y // warn val y: LazyList[Int] = 10 #:: x } @@ -37,7 +37,7 @@ final class Test2 { } final class Test3 { - val a: LazyList[Int] = n #:: (a: @unchecked) // error + val a: LazyList[Int] = n #:: (a: @unchecked) // warn a.head val n: Int = 20 } \ No newline at end of file diff --git a/tests/init/neg/leak-warm.scala b/tests/init/warn/leak-warm.scala similarity index 91% rename from tests/init/neg/leak-warm.scala rename to tests/init/warn/leak-warm.scala index 9bfbe2e4f285..5278b67e7eac 100644 --- a/tests/init/neg/leak-warm.scala +++ b/tests/init/warn/leak-warm.scala @@ -16,5 +16,5 @@ class leakWarm { val c = new C(1, 2) val d = new D(3, 4) val l: List[A] = List(c, d) - val l2 = l.map(_.m()) // error + val l2 = l.map(_.m()) // warn } diff --git a/tests/init/neg/local-class.scala b/tests/init/warn/local-class.scala similarity index 84% rename from tests/init/neg/local-class.scala rename to tests/init/warn/local-class.scala index 20e77912dce8..14f203a738c3 100644 --- a/tests/init/neg/local-class.scala +++ b/tests/init/warn/local-class.scala @@ -12,5 +12,5 @@ class Outer { foo - val n = 10 // error + val n = 10 // warn } diff --git a/tests/init/neg/override1.scala b/tests/init/warn/override1.scala similarity index 84% rename from tests/init/neg/override1.scala rename to tests/init/warn/override1.scala index c9c9fed3ecd8..b247470c19d5 100644 --- a/tests/init/neg/override1.scala +++ b/tests/init/warn/override1.scala @@ -15,6 +15,6 @@ class Qux(x: Int) extends Bar { } class Yun extends Bar { - override val x: Int = 10 // error + override val x: Int = 10 // warn def foo(n: Int) = x + n } diff --git a/tests/init/neg/override10.scala b/tests/init/warn/override10.scala similarity index 75% rename from tests/init/neg/override10.scala rename to tests/init/warn/override10.scala index 6b8b0e7101db..0c49d7c63113 100644 --- a/tests/init/neg/override10.scala +++ b/tests/init/warn/override10.scala @@ -5,5 +5,5 @@ trait Foo { class Bar extends Foo { f() - val message = "hello" // error + val message = "hello" // warn } \ No newline at end of file diff --git a/tests/init/neg/override14.scala b/tests/init/warn/override14.scala similarity index 76% rename from tests/init/neg/override14.scala rename to tests/init/warn/override14.scala index 451a12087103..0d773e61f9b2 100644 --- a/tests/init/neg/override14.scala +++ b/tests/init/warn/override14.scala @@ -1,5 +1,5 @@ abstract class A { - val x = f(this) // error + val x = f(this) // warn val y = 10 def f(a: A): Int diff --git a/tests/init/neg/override15.scala b/tests/init/warn/override15.scala similarity index 81% rename from tests/init/neg/override15.scala rename to tests/init/warn/override15.scala index 0f22430cf6a6..ca3e32abb35e 100644 --- a/tests/init/neg/override15.scala +++ b/tests/init/warn/override15.scala @@ -1,6 +1,6 @@ abstract class A { val g = (n: Int) => n + y - val x: Int = f(g) // error + val x: Int = f(g) // warn val y: Int = 10 def f(m: Int => Int): Int diff --git a/tests/init/neg/override17.scala b/tests/init/warn/override17.scala similarity index 76% rename from tests/init/neg/override17.scala rename to tests/init/warn/override17.scala index 72bd8db9a246..cbeaaed37bea 100644 --- a/tests/init/neg/override17.scala +++ b/tests/init/warn/override17.scala @@ -3,7 +3,7 @@ class A { self : B => } trait B { - val x = 10 // error + val x = 10 // warn } class C extends A with B diff --git a/tests/init/neg/override18.scala b/tests/init/warn/override18.scala similarity index 88% rename from tests/init/neg/override18.scala rename to tests/init/warn/override18.scala index 61edaf6d8c8f..3c2ca3e7af5d 100644 --- a/tests/init/neg/override18.scala +++ b/tests/init/warn/override18.scala @@ -10,7 +10,7 @@ class B extends A { class C extends A { val x = f - val y = x // error + val y = x // warn def f: Int = y } diff --git a/tests/init/neg/override19.scala b/tests/init/warn/override19.scala similarity index 79% rename from tests/init/neg/override19.scala rename to tests/init/warn/override19.scala index 8e1f6a832323..61d17bb93597 100644 --- a/tests/init/neg/override19.scala +++ b/tests/init/warn/override19.scala @@ -5,6 +5,6 @@ abstract class A extends Product { case class B(x: Int, y: String) extends A case class C(x: Int) extends A { - val y = 10 // error + val y = 10 // warn def productArity: Int = y } \ No newline at end of file diff --git a/tests/init/neg/override2.scala b/tests/init/warn/override2.scala similarity index 89% rename from tests/init/neg/override2.scala rename to tests/init/warn/override2.scala index f9964f60ad29..3adae93c23c9 100644 --- a/tests/init/neg/override2.scala +++ b/tests/init/warn/override2.scala @@ -8,7 +8,7 @@ trait Foo { } class Bar extends Foo { - val y = "hello" // error + val y = "hello" // warn foo(5) bar(10) diff --git a/tests/init/neg/override20.scala b/tests/init/warn/override20.scala similarity index 75% rename from tests/init/neg/override20.scala rename to tests/init/warn/override20.scala index 65ece64c6020..4f1f7b452f75 100644 --- a/tests/init/neg/override20.scala +++ b/tests/init/warn/override20.scala @@ -2,7 +2,7 @@ class A { self : B => val y = f } -trait B(x: Int) { // error +trait B(x: Int) { // warn def f: Int = x } diff --git a/tests/init/neg/override21.scala b/tests/init/warn/override21.scala similarity index 86% rename from tests/init/neg/override21.scala rename to tests/init/warn/override21.scala index 332ce702a9fc..84c319949cb7 100644 --- a/tests/init/neg/override21.scala +++ b/tests/init/warn/override21.scala @@ -10,7 +10,7 @@ class Child extends Parent { this.z val m = this.x - val y = "hello" // error + val y = "hello" // warn def bar = y.size } \ No newline at end of file diff --git a/tests/init/neg/override22.scala b/tests/init/warn/override22.scala similarity index 87% rename from tests/init/neg/override22.scala rename to tests/init/warn/override22.scala index 7de6f03aa837..f7fc1b312e4e 100644 --- a/tests/init/neg/override22.scala +++ b/tests/init/warn/override22.scala @@ -9,7 +9,7 @@ class Child extends Parent { val y = "hello" this.foo - val m = this.x // error + val m = this.x // warn this.z def bar = m.size + 6 diff --git a/tests/init/neg/override23.scala b/tests/init/warn/override23.scala similarity index 87% rename from tests/init/neg/override23.scala rename to tests/init/warn/override23.scala index 3ada767bfafc..2af45c953ae5 100644 --- a/tests/init/neg/override23.scala +++ b/tests/init/warn/override23.scala @@ -10,7 +10,7 @@ class Child(o: String) extends Parent(o) { this.foo this.z - val y = "hello" // error + val y = "hello" // warn def bar = y.size } \ No newline at end of file diff --git a/tests/init/neg/override24.scala b/tests/init/warn/override24.scala similarity index 91% rename from tests/init/neg/override24.scala rename to tests/init/warn/override24.scala index 9adfac27bb02..feaa07396755 100644 --- a/tests/init/neg/override24.scala +++ b/tests/init/warn/override24.scala @@ -15,7 +15,7 @@ class Bar extends Foo { foo(4) - val name = "bar" // error + val name = "bar" // warn foo(4) } \ No newline at end of file diff --git a/tests/init/neg/override25.scala b/tests/init/warn/override25.scala similarity index 85% rename from tests/init/neg/override25.scala rename to tests/init/warn/override25.scala index 9554b4296a9f..e5d5d7f8e34f 100644 --- a/tests/init/neg/override25.scala +++ b/tests/init/warn/override25.scala @@ -1,4 +1,4 @@ -trait Foo(x: Int) { // error +trait Foo(x: Int) { // warn def name: String = "hello" def f: Int = x diff --git a/tests/init/neg/override26.scala b/tests/init/warn/override26.scala similarity index 85% rename from tests/init/neg/override26.scala rename to tests/init/warn/override26.scala index 37e83898bfcc..98a30477ee74 100644 --- a/tests/init/neg/override26.scala +++ b/tests/init/warn/override26.scala @@ -11,6 +11,6 @@ trait Bar { this: Foo => } class Qux extends Foo with Bar { - val x = "hello" // error + val x = "hello" // warn def title = x } diff --git a/tests/init/neg/override27.scala b/tests/init/warn/override27.scala similarity index 73% rename from tests/init/neg/override27.scala rename to tests/init/warn/override27.scala index 4b3a79ac233b..ae9ffe6ad63f 100644 --- a/tests/init/neg/override27.scala +++ b/tests/init/warn/override27.scala @@ -1,6 +1,6 @@ abstract class Base { def f: Int - val a = f // error + val a = f // warn } class Derived extends Base { @@ -10,7 +10,7 @@ class Derived extends Base { } class Derived2 extends Base { - val b = 30 // error + val b = 30 // warn def f = g def g: Int = b + a diff --git a/tests/init/neg/override28.scala b/tests/init/warn/override28.scala similarity index 72% rename from tests/init/neg/override28.scala rename to tests/init/warn/override28.scala index 8e77f8acb3ba..60ba0bff6c76 100644 --- a/tests/init/neg/override28.scala +++ b/tests/init/warn/override28.scala @@ -6,5 +6,5 @@ abstract class Base(val x: Int) { class C(x: Int) extends Base(x) { - val d = f // error + val d = f // warn } \ No newline at end of file diff --git a/tests/init/neg/override29.scala b/tests/init/warn/override29.scala similarity index 78% rename from tests/init/neg/override29.scala rename to tests/init/warn/override29.scala index e0070eb10218..5c640e2fcc0e 100644 --- a/tests/init/neg/override29.scala +++ b/tests/init/warn/override29.scala @@ -1,5 +1,5 @@ trait A { - var a = 20 // error + var a = 20 // warn def f: Int = a } diff --git a/tests/init/neg/override3.scala b/tests/init/warn/override3.scala similarity index 91% rename from tests/init/neg/override3.scala rename to tests/init/warn/override3.scala index 51759320e1b5..74fae84a547a 100644 --- a/tests/init/neg/override3.scala +++ b/tests/init/warn/override3.scala @@ -13,7 +13,7 @@ class Bar1 extends Foo { } class Qux extends Bar1 { - val u = "hello" // error + val u = "hello" // warn override def foo(n: Int) = u + "world" } diff --git a/tests/init/neg/override30.scala b/tests/init/warn/override30.scala similarity index 79% rename from tests/init/neg/override30.scala rename to tests/init/warn/override30.scala index adb4c2e00d2b..1677574130d4 100644 --- a/tests/init/neg/override30.scala +++ b/tests/init/warn/override30.scala @@ -10,6 +10,6 @@ class Bar extends Foo { } class Qux extends Bar { - val a = 30 // error + val a = 30 // warn override def f = a } \ No newline at end of file diff --git a/tests/init/neg/override31.scala b/tests/init/warn/override31.scala similarity index 84% rename from tests/init/neg/override31.scala rename to tests/init/warn/override31.scala index d902f4a6dc54..baffab3ad08e 100644 --- a/tests/init/neg/override31.scala +++ b/tests/init/warn/override31.scala @@ -11,5 +11,5 @@ class Bar extends Foo { class Qux extends Bar { init override def f = a - private val a = 30 // error + private val a = 30 // warn } \ No newline at end of file diff --git a/tests/init/neg/override32.scala b/tests/init/warn/override32.scala similarity index 80% rename from tests/init/neg/override32.scala rename to tests/init/warn/override32.scala index 09970a9bd392..b9a4e7eae178 100644 --- a/tests/init/neg/override32.scala +++ b/tests/init/warn/override32.scala @@ -6,7 +6,7 @@ trait Foo { } trait Bar { - final val m: String = "hello" // error + final val m: String = "hello" // warn def foo(n: Int) = m } diff --git a/tests/init/neg/override33.scala b/tests/init/warn/override33.scala similarity index 85% rename from tests/init/neg/override33.scala rename to tests/init/warn/override33.scala index b093dc570f04..04d27be6777c 100644 --- a/tests/init/neg/override33.scala +++ b/tests/init/warn/override33.scala @@ -8,7 +8,7 @@ abstract class Foo { } trait Bar { - val name: String = "Foo" // error + val name: String = "Foo" // warn def title: String = name } diff --git a/tests/init/neg/override34.scala b/tests/init/warn/override34.scala similarity index 79% rename from tests/init/neg/override34.scala rename to tests/init/warn/override34.scala index 6cf3e3cf4b4d..e4a21e861eb2 100644 --- a/tests/init/neg/override34.scala +++ b/tests/init/warn/override34.scala @@ -5,7 +5,7 @@ abstract class Foo { } trait Bar { - val name: String = "Foo" // error + val name: String = "Foo" // warn } class Qux extends Foo with Bar { diff --git a/tests/init/neg/override35.scala b/tests/init/warn/override35.scala similarity index 77% rename from tests/init/neg/override35.scala rename to tests/init/warn/override35.scala index 958ed1ff9d2f..1769f7b3a361 100644 --- a/tests/init/neg/override35.scala +++ b/tests/init/warn/override35.scala @@ -10,6 +10,6 @@ trait Bar { } class Qux extends Foo with Bar { - private val x = 30 // error + private val x = 30 // warn override def f = x } \ No newline at end of file diff --git a/tests/init/neg/override36.scala b/tests/init/warn/override36.scala similarity index 87% rename from tests/init/neg/override36.scala rename to tests/init/warn/override36.scala index 6df0891d5b27..2fedf7ff6bcb 100644 --- a/tests/init/neg/override36.scala +++ b/tests/init/warn/override36.scala @@ -14,5 +14,5 @@ class Bar extends Foo { class Qux extends Bar { init override def h = a - private val a = 30 // error + private val a = 30 // warn } \ No newline at end of file diff --git a/tests/init/neg/override38.scala b/tests/init/warn/override38.scala similarity index 77% rename from tests/init/neg/override38.scala rename to tests/init/warn/override38.scala index dd47b0438980..feb962cd5029 100644 --- a/tests/init/neg/override38.scala +++ b/tests/init/warn/override38.scala @@ -1,7 +1,7 @@ abstract class A { def f: Int - (1 to 10).foreach { i => // error + (1 to 10).foreach { i => // warn f } diff --git a/tests/init/neg/override39.scala b/tests/init/warn/override39.scala similarity index 82% rename from tests/init/neg/override39.scala rename to tests/init/warn/override39.scala index 723e71554da2..34f25cee2022 100644 --- a/tests/init/neg/override39.scala +++ b/tests/init/warn/override39.scala @@ -6,6 +6,6 @@ abstract class Parent extends Product { } case class Child(x: Int) extends Parent { - val m = 10 // error + val m = 10 // warn def productArity: Int = m } \ No newline at end of file diff --git a/tests/init/neg/override4.scala b/tests/init/warn/override4.scala similarity index 82% rename from tests/init/neg/override4.scala rename to tests/init/warn/override4.scala index 1489e1c2508b..1a63d2b3b59b 100644 --- a/tests/init/neg/override4.scala +++ b/tests/init/warn/override4.scala @@ -12,7 +12,7 @@ class Bar extends Foo { } class Bar2 extends Bar { - val mymap: mutable.Map[Int, String] = mutable.Map.empty // error + val mymap: mutable.Map[Int, String] = mutable.Map.empty // warn override def enter(k: Int, v: String) = { mymap(k) = v diff --git a/tests/init/neg/override40.scala b/tests/init/warn/override40.scala similarity index 80% rename from tests/init/neg/override40.scala rename to tests/init/warn/override40.scala index 2f081a9de30b..305210158d54 100644 --- a/tests/init/neg/override40.scala +++ b/tests/init/warn/override40.scala @@ -6,5 +6,5 @@ abstract class A { class B extends A { this.getClass f - val a = 20 // error + val a = 20 // warn } \ No newline at end of file diff --git a/tests/init/neg/override41.scala b/tests/init/warn/override41.scala similarity index 82% rename from tests/init/neg/override41.scala rename to tests/init/warn/override41.scala index bfd5bc18f3d6..6cb58ae326aa 100644 --- a/tests/init/neg/override41.scala +++ b/tests/init/warn/override41.scala @@ -11,5 +11,5 @@ class Child extends Parent { def show = println(name) - val name = "child" // error + val name = "child" // warn } \ No newline at end of file diff --git a/tests/init/neg/override42.scala b/tests/init/warn/override42.scala similarity index 81% rename from tests/init/neg/override42.scala rename to tests/init/warn/override42.scala index b4a53b977852..39a4d5097215 100644 --- a/tests/init/neg/override42.scala +++ b/tests/init/warn/override42.scala @@ -12,5 +12,5 @@ class Bar { def show = println(name) - val name = "child" // error + val name = "child" // warn } diff --git a/tests/init/neg/override43.scala b/tests/init/warn/override43.scala similarity index 83% rename from tests/init/neg/override43.scala rename to tests/init/warn/override43.scala index 2d55742c3ecd..ab8ec95133d6 100644 --- a/tests/init/neg/override43.scala +++ b/tests/init/warn/override43.scala @@ -8,6 +8,6 @@ final class Child extends Parent { def g() = foo() g() + b - val b = 10 // error + val b = 10 // warn g() } \ No newline at end of file diff --git a/tests/init/neg/override44.scala b/tests/init/warn/override44.scala similarity index 83% rename from tests/init/neg/override44.scala rename to tests/init/warn/override44.scala index ed7a0ae30b7a..50e7691d6fee 100644 --- a/tests/init/neg/override44.scala +++ b/tests/init/warn/override44.scala @@ -8,6 +8,6 @@ class Child extends Parent { def g() = foo() g() + b - val b = 10 // error + val b = 10 // warn g() } \ No newline at end of file diff --git a/tests/init/neg/override45.scala b/tests/init/warn/override45.scala similarity index 81% rename from tests/init/neg/override45.scala rename to tests/init/warn/override45.scala index dbf767239e6b..7eb0ba2f8cca 100644 --- a/tests/init/neg/override45.scala +++ b/tests/init/warn/override45.scala @@ -8,5 +8,5 @@ class Child extends Parent { val x = a val y = b override def f: Int = z - val z = 30 // error + val z = 30 // warn } \ No newline at end of file diff --git a/tests/init/neg/override46.scala b/tests/init/warn/override46.scala similarity index 75% rename from tests/init/neg/override46.scala rename to tests/init/warn/override46.scala index 397ec85a6984..f10d4516439c 100644 --- a/tests/init/neg/override46.scala +++ b/tests/init/warn/override46.scala @@ -1,5 +1,5 @@ trait TA { - val x = "world" // error + val x = "world" // warn } trait TB { this: TA => diff --git a/tests/init/neg/override5.scala b/tests/init/warn/override5.scala similarity index 78% rename from tests/init/neg/override5.scala rename to tests/init/warn/override5.scala index 061a41dc3fc2..fe9e3bfbde70 100644 --- a/tests/init/neg/override5.scala +++ b/tests/init/warn/override5.scala @@ -5,7 +5,7 @@ trait Foo { } class Bar extends Foo { - val name = "Jack" // error + val name = "Jack" // warn } @@ -16,7 +16,7 @@ trait Zen { } class Tao extends Zen { - val name = "Jack" // error + val name = "Jack" // warn } diff --git a/tests/init/neg/override6.scala b/tests/init/warn/override6.scala similarity index 70% rename from tests/init/neg/override6.scala rename to tests/init/warn/override6.scala index 0c04ea91300d..e8103d999151 100644 --- a/tests/init/neg/override6.scala +++ b/tests/init/warn/override6.scala @@ -4,5 +4,5 @@ trait Foo { } class Bar extends Foo { - val name = "Jack" // error + val name = "Jack" // warn } \ No newline at end of file diff --git a/tests/init/neg/override7.scala b/tests/init/warn/override7.scala similarity index 87% rename from tests/init/neg/override7.scala rename to tests/init/warn/override7.scala index 0a36f02b2790..41fbcd00be69 100644 --- a/tests/init/neg/override7.scala +++ b/tests/init/warn/override7.scala @@ -7,7 +7,7 @@ trait Foo { } class Bar(val name: String) extends Foo { - val title = "Mr." // error + val title = "Mr." // warn def getName = name // ok: name is a Param field diff --git a/tests/init/neg/override8.scala b/tests/init/warn/override8.scala similarity index 93% rename from tests/init/neg/override8.scala rename to tests/init/warn/override8.scala index 526fd5a7f3a3..272143011efc 100644 --- a/tests/init/neg/override8.scala +++ b/tests/init/warn/override8.scala @@ -6,7 +6,7 @@ trait Foo { } trait Bar { - val m = "hello" // error + val m = "hello" // warn def foo(n: Int) = m diff --git a/tests/init/neg/override9.scala b/tests/init/warn/override9.scala similarity index 64% rename from tests/init/neg/override9.scala rename to tests/init/warn/override9.scala index 1b4d32b3e5a3..12dbfde19ec3 100644 --- a/tests/init/neg/override9.scala +++ b/tests/init/warn/override9.scala @@ -1,6 +1,6 @@ trait Foo { def name: String - val message = "hello, " + name // error + val message = "hello, " + name // warn } class Bar extends Foo { diff --git a/tests/init/neg/polyfun.scala b/tests/init/warn/polyfun.scala similarity index 72% rename from tests/init/neg/polyfun.scala rename to tests/init/warn/polyfun.scala index a3a3ecc76814..5ac11721c061 100644 --- a/tests/init/neg/polyfun.scala +++ b/tests/init/warn/polyfun.scala @@ -4,5 +4,5 @@ class Test { println(n) arg } - val n = m.apply(arg = 23) // error + val n = m.apply(arg = 23) // warn } diff --git a/tests/init/neg/private.scala b/tests/init/warn/private.scala similarity index 84% rename from tests/init/neg/private.scala rename to tests/init/warn/private.scala index 658860ab577c..215f0db3deee 100644 --- a/tests/init/neg/private.scala +++ b/tests/init/warn/private.scala @@ -6,7 +6,7 @@ class A(a: Int) { class B extends A(3) { foo() println(a) - val a = 3 // error + val a = 3 // warn } class C extends A(3) { diff --git a/tests/init/neg/promote-warm.scala b/tests/init/warn/promote-warm.scala similarity index 84% rename from tests/init/neg/promote-warm.scala rename to tests/init/warn/promote-warm.scala index c9f9268f1fbd..c776d37a924e 100644 --- a/tests/init/neg/promote-warm.scala +++ b/tests/init/warn/promote-warm.scala @@ -6,7 +6,7 @@ class PromoteWarm: a.foo() val a = new A - val b = new B(a) // error + val b = new B(a) // warn val n = 10 def foo() = println(n) diff --git a/tests/init/neg/promote.scala b/tests/init/warn/promote.scala similarity index 82% rename from tests/init/neg/promote.scala rename to tests/init/warn/promote.scala index 70e951d78f6f..a97122d57a62 100644 --- a/tests/init/neg/promote.scala +++ b/tests/init/warn/promote.scala @@ -4,6 +4,6 @@ class Wrap { abstract class E[+T] { def foo: T } object E { final val A: E[Nothing] = new E { def foo = ref } - val ref = qux(A) // error + val ref = qux(A) // warn } } \ No newline at end of file diff --git a/tests/init/neg/promotion-loop.scala b/tests/init/warn/promotion-loop.scala similarity index 86% rename from tests/init/neg/promotion-loop.scala rename to tests/init/warn/promotion-loop.scala index 7f6856c34cae..c94422daca76 100644 --- a/tests/init/neg/promotion-loop.scala +++ b/tests/init/warn/promotion-loop.scala @@ -13,7 +13,7 @@ class Test { test => } val b = new B - println(b) // error + println(b) // warn val n = 10 } \ No newline at end of file diff --git a/tests/init/neg/promotion-segment.scala b/tests/init/warn/promotion-segment.scala similarity index 85% rename from tests/init/neg/promotion-segment.scala rename to tests/init/warn/promotion-segment.scala index 56968ce79c56..542ee23623f1 100644 --- a/tests/init/neg/promotion-segment.scala +++ b/tests/init/warn/promotion-segment.scala @@ -8,5 +8,5 @@ class Outer: def bar(c: C) = c.foo() - bar(new C) // error + bar(new C) // warn val m = 10 diff --git a/tests/init/neg/promotion-segment2.scala b/tests/init/warn/promotion-segment2.scala similarity index 87% rename from tests/init/neg/promotion-segment2.scala rename to tests/init/warn/promotion-segment2.scala index d3ba8dedf0ce..39cd7129950f 100644 --- a/tests/init/neg/promotion-segment2.scala +++ b/tests/init/warn/promotion-segment2.scala @@ -8,5 +8,5 @@ class Outer: def bar(c: C) = c.foo() - bar(new C) // error + bar(new C) // warn val m = 10 diff --git a/tests/init/neg/promotion-segment3.scala b/tests/init/warn/promotion-segment3.scala similarity index 82% rename from tests/init/neg/promotion-segment3.scala rename to tests/init/warn/promotion-segment3.scala index 9e62291953d3..5dab2224743b 100644 --- a/tests/init/neg/promotion-segment3.scala +++ b/tests/init/warn/promotion-segment3.scala @@ -6,6 +6,6 @@ class A: def bar(b: B) = new b.C().foo() - bar(new B) // error + bar(new B) // warn val m = 10 diff --git a/tests/init/neg/secondary-ctor.scala b/tests/init/warn/secondary-ctor.scala similarity index 87% rename from tests/init/neg/secondary-ctor.scala rename to tests/init/warn/secondary-ctor.scala index d96e149529d0..92a77b11b57a 100644 --- a/tests/init/neg/secondary-ctor.scala +++ b/tests/init/warn/secondary-ctor.scala @@ -15,5 +15,5 @@ class C(b: B) extends A(b) { class D { val b = new B(this) - val c = new C(b, 5) // error + val c = new C(b, 5) // warn } diff --git a/tests/init/neg/secondary-ctor2.scala b/tests/init/warn/secondary-ctor2.scala similarity index 91% rename from tests/init/neg/secondary-ctor2.scala rename to tests/init/warn/secondary-ctor2.scala index 462ff2dbcfaa..5518bbf974e7 100644 --- a/tests/init/neg/secondary-ctor2.scala +++ b/tests/init/warn/secondary-ctor2.scala @@ -21,5 +21,5 @@ class C(b: B) extends A(b) { class D { val b = new B(this) - val c = new C(b, 5) // error + val c = new C(b, 5) // warn } diff --git a/tests/init/neg/secondary-ctor3.scala b/tests/init/warn/secondary-ctor3.scala similarity index 94% rename from tests/init/neg/secondary-ctor3.scala rename to tests/init/warn/secondary-ctor3.scala index 3bbfc413e262..ed01c6fcbe30 100644 --- a/tests/init/neg/secondary-ctor3.scala +++ b/tests/init/warn/secondary-ctor3.scala @@ -35,5 +35,5 @@ def foo() = class D { val b = new B(this) - val c = new C(b, 5) // error + val c = new C(b, 5) // warn } diff --git a/tests/init/neg/secondary-ctor4.check b/tests/init/warn/secondary-ctor4.check similarity index 84% rename from tests/init/neg/secondary-ctor4.check rename to tests/init/warn/secondary-ctor4.check index 2c89cfe9f289..3909af5ac336 100644 --- a/tests/init/neg/secondary-ctor4.check +++ b/tests/init/warn/secondary-ctor4.check @@ -1,10 +1,10 @@ --- Error: tests/init/neg/secondary-ctor4.scala:54:14 ------------------------------------------------------------------- -54 | val c = new C(b, 5) // error +-- Warning: tests/init/warn/secondary-ctor4.scala:54:14 ---------------------------------------------------------------- +54 | val c = new C(b, 5) // warn | ^^^^^^^^^^^ | Problematic object instantiation: arg 1 is not transitively initialized (Hot). Calling trace: | ├── class D { [ secondary-ctor4.scala:52 ] | │ ^ - | └── val c = new C(b, 5) // error [ secondary-ctor4.scala:54 ] + | └── val c = new C(b, 5) // warn [ secondary-ctor4.scala:54 ] | ^^^^^^^^^^^ | | It leads to the following error during object initialization: @@ -21,15 +21,15 @@ | │ ^ | └── println(b.n) [ secondary-ctor4.scala:23 ] | ^^^ --- Error: tests/init/neg/secondary-ctor4.scala:42:4 -------------------------------------------------------------------- -42 | new A(new B(new D)) // error +-- Warning: tests/init/warn/secondary-ctor4.scala:42:4 ----------------------------------------------------------------- +42 | new A(new B(new D)) // warn | ^^^^^^^^^^^^^^^^^^^ |Problematic object instantiation: the outer M.this and arg 1 are not transitively initialized (Hot). Calling trace: |├── class N(d: D) extends M(d) { [ secondary-ctor4.scala:59 ] |│ ^ |├── def this(d: D) = { [ secondary-ctor4.scala:7 ] |│ ^ - |└── new A(new B(new D)) // error [ secondary-ctor4.scala:42 ] + |└── new A(new B(new D)) // warn [ secondary-ctor4.scala:42 ] | ^^^^^^^^^^^^^^^^^^^ | |It leads to the following error during object initialization: diff --git a/tests/init/neg/secondary-ctor4.scala b/tests/init/warn/secondary-ctor4.scala similarity index 90% rename from tests/init/neg/secondary-ctor4.scala rename to tests/init/warn/secondary-ctor4.scala index e80630002638..9c53034ee597 100644 --- a/tests/init/neg/secondary-ctor4.scala +++ b/tests/init/warn/secondary-ctor4.scala @@ -10,7 +10,7 @@ class M(x: Int) { class L1(x: Int) { val n: Int = 5 } class A(b: B, x: Int) { - println(d.n) + println(d.n) class L2(x: Int) { val n: Int = 5 } @@ -39,7 +39,7 @@ class M(x: Int) { val n: Int = 10 } - new A(new B(new D)) // error + new A(new B(new D)) // warn trait T { val m: Int = 10 @@ -51,7 +51,7 @@ class M(x: Int) { class D { val b = new B(this) - val c = new C(b, 5) // error + val c = new C(b, 5) // warn } } } diff --git a/tests/init/warn/simple1.scala b/tests/init/warn/simple1.scala new file mode 100644 index 000000000000..9f8ce2f5c487 --- /dev/null +++ b/tests/init/warn/simple1.scala @@ -0,0 +1,4 @@ +class Foo { + val len = name.size + val name: String = "Jack" // warn +} \ No newline at end of file diff --git a/tests/init/neg/simple2.scala b/tests/init/warn/simple2.scala similarity index 86% rename from tests/init/neg/simple2.scala rename to tests/init/warn/simple2.scala index 70a7f8407c6b..63fa64d5a113 100644 --- a/tests/init/neg/simple2.scala +++ b/tests/init/warn/simple2.scala @@ -4,7 +4,7 @@ class Box(x: Int) { List(3, 4, 5).map(_ * 2) - private var a = "hello" // error + private var a = "hello" // warn def f(m: Int) = m + a.size } diff --git a/tests/init/neg/simple3.scala b/tests/init/warn/simple3.scala similarity index 64% rename from tests/init/neg/simple3.scala rename to tests/init/warn/simple3.scala index 70de74b35bd4..245f982a807b 100644 --- a/tests/init/neg/simple3.scala +++ b/tests/init/warn/simple3.scala @@ -1,5 +1,5 @@ class Foo { val list = List(4, 6) val n = len + 5 - val len = list.size // error + val len = list.size // warn } diff --git a/tests/init/neg/simple5.scala b/tests/init/warn/simple5.scala similarity index 68% rename from tests/init/neg/simple5.scala rename to tests/init/warn/simple5.scala index 9c9d7d053830..bd9506076d26 100644 --- a/tests/init/neg/simple5.scala +++ b/tests/init/warn/simple5.scala @@ -6,7 +6,7 @@ class Foo { b - val name = "Jack" // error + val name = "Jack" // warn } class Bar { @@ -17,5 +17,5 @@ class Bar { b - val name = "Jack" // error + val name = "Jack" // warn } \ No newline at end of file diff --git a/tests/init/neg/soundness1.scala b/tests/init/warn/soundness1.scala similarity index 81% rename from tests/init/neg/soundness1.scala rename to tests/init/warn/soundness1.scala index d528b374f004..4d71c3e52747 100644 --- a/tests/init/neg/soundness1.scala +++ b/tests/init/warn/soundness1.scala @@ -20,10 +20,10 @@ object Test2: object Test3: class A(b: B) { println(b.a2) - val b2 = new B(this) // error + val b2 = new B(this) // warn } class B(a: A) { println(a.b2) - val a2 = new A(this) // error + val a2 = new A(this) // warn } diff --git a/tests/init/neg/soundness2.scala b/tests/init/warn/soundness2.scala similarity index 50% rename from tests/init/neg/soundness2.scala rename to tests/init/warn/soundness2.scala index 3d2821377111..6015ea46c3d7 100644 --- a/tests/init/neg/soundness2.scala +++ b/tests/init/warn/soundness2.scala @@ -1,4 +1,4 @@ class C(c: C) { val d = c.c2 - val c2 = new C(this) // error + val c2 = new C(this) // warn } diff --git a/tests/init/warn/soundness4.scala b/tests/init/warn/soundness4.scala new file mode 100644 index 000000000000..24060f2be083 --- /dev/null +++ b/tests/init/warn/soundness4.scala @@ -0,0 +1,3 @@ +class Foo { + val a : Foo = this.a.a // warn +} \ No newline at end of file diff --git a/tests/init/neg/soundness6.scala b/tests/init/warn/soundness6.scala similarity index 58% rename from tests/init/neg/soundness6.scala rename to tests/init/warn/soundness6.scala index 09d55dba292c..2893c3a4e301 100644 --- a/tests/init/neg/soundness6.scala +++ b/tests/init/warn/soundness6.scala @@ -1,5 +1,5 @@ class C(c: C) { println(c.n) - val c2 = new C(this) // error + val c2 = new C(this) // warn val n = 10 } diff --git a/tests/init/neg/structural.scala b/tests/init/warn/structural.scala similarity index 86% rename from tests/init/neg/structural.scala rename to tests/init/warn/structural.scala index 27b37a04bef7..bf20529a8007 100644 --- a/tests/init/neg/structural.scala +++ b/tests/init/warn/structural.scala @@ -8,5 +8,5 @@ class Test { n + x } - val n = m(23) // error + val n = m(23) // warn } diff --git a/tests/init/neg/super-resolution.scala b/tests/init/warn/super-resolution.scala similarity index 82% rename from tests/init/neg/super-resolution.scala rename to tests/init/warn/super-resolution.scala index d2674bc597e1..6fa295ed5187 100644 --- a/tests/init/neg/super-resolution.scala +++ b/tests/init/warn/super-resolution.scala @@ -16,8 +16,8 @@ trait N extends A with B: class C extends A with M with N: foo() - val a = 10 // error - val b = 20 // error - val m = 30 // error + val a = 10 // warn + val b = 20 // warn + val m = 30 // warn val n = 40 diff --git a/tests/init/neg/super-resolution2.scala b/tests/init/warn/super-resolution2.scala similarity index 84% rename from tests/init/neg/super-resolution2.scala rename to tests/init/warn/super-resolution2.scala index 283fb25a467d..5009e2f3aa64 100644 --- a/tests/init/neg/super-resolution2.scala +++ b/tests/init/warn/super-resolution2.scala @@ -15,6 +15,6 @@ class N extends A with B: new Inner - val m = 30 // error - val n = 40 // error + val m = 30 // warn + val n = 40 // warn val a = 50 diff --git a/tests/init/neg/super-resolution3.scala b/tests/init/warn/super-resolution3.scala similarity index 81% rename from tests/init/neg/super-resolution3.scala rename to tests/init/warn/super-resolution3.scala index 4d510ef22e61..e1b7a2ba3541 100644 --- a/tests/init/neg/super-resolution3.scala +++ b/tests/init/warn/super-resolution3.scala @@ -21,7 +21,7 @@ trait N extends A with B: class C extends A with M with N: new Inner() - val a = 10 // error - val b = 20 // error - val m = 30 // error - val n = 40 // error + val a = 10 // warn + val b = 20 // warn + val m = 30 // warn + val n = 40 // warn diff --git a/tests/init/neg/super.scala b/tests/init/warn/super.scala similarity index 87% rename from tests/init/neg/super.scala rename to tests/init/warn/super.scala index 5a8e72cce65f..9b0b88136f20 100644 --- a/tests/init/neg/super.scala +++ b/tests/init/warn/super.scala @@ -20,11 +20,11 @@ class Bar extends A, B, C: override def foo() = n * n - val n = 10 // error + val n = 10 // warn class Qux extends A, B, C: super.foo() override def foo() = n * n - val n = 10 // error + val n = 10 // warn diff --git a/tests/init/neg/t3273.scala b/tests/init/warn/t3273.scala similarity index 90% rename from tests/init/neg/t3273.scala rename to tests/init/warn/t3273.scala index af1df70c471e..c4b79a4dbfcc 100644 --- a/tests/init/neg/t3273.scala +++ b/tests/init/warn/t3273.scala @@ -1,8 +1,8 @@ import scala.language.implicitConversions class Test { - val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error - val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error + val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // warn + val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // warn def main(args: Array[String]): Unit = { val x1 = (num1 take 10).toList diff --git a/tests/init/neg/trait1.scala b/tests/init/warn/trait1.scala similarity index 79% rename from tests/init/neg/trait1.scala rename to tests/init/warn/trait1.scala index 48eae248fee7..d5c30569c4ee 100644 --- a/tests/init/neg/trait1.scala +++ b/tests/init/warn/trait1.scala @@ -3,7 +3,7 @@ abstract class A(x: Int) { foo() } -trait B(val y: Int) // error +trait B(val y: Int) // warn class C extends A(10) with B(20) { def foo(): Unit = println(y) diff --git a/tests/init/neg/trait2.scala b/tests/init/warn/trait2.scala similarity index 83% rename from tests/init/neg/trait2.scala rename to tests/init/warn/trait2.scala index 6011c259b73f..1b5bfded5730 100644 --- a/tests/init/neg/trait2.scala +++ b/tests/init/warn/trait2.scala @@ -3,7 +3,7 @@ abstract class A(x: Int) { foo() } -trait B(val y: Int) // error +trait B(val y: Int) // warn class D { class C extends A(10) with B(20) { diff --git a/tests/init/neg/trees.scala b/tests/init/warn/trees.scala similarity index 78% rename from tests/init/neg/trees.scala rename to tests/init/warn/trees.scala index 836f02e9c551..96ae170075c5 100644 --- a/tests/init/neg/trees.scala +++ b/tests/init/warn/trees.scala @@ -3,5 +3,5 @@ class Trees { class ValDef { counter += 1 } class EmptyValDef extends ValDef val theEmptyValDef = new EmptyValDef - private var counter = 0 // error + private var counter = 0 // warn } diff --git a/tests/init/neg/unsound1.scala b/tests/init/warn/unsound1.scala similarity index 80% rename from tests/init/neg/unsound1.scala rename to tests/init/warn/unsound1.scala index 3854504c8478..b017d1cd9f37 100644 --- a/tests/init/neg/unsound1.scala +++ b/tests/init/warn/unsound1.scala @@ -1,5 +1,5 @@ class A(m: Int) { - if (m > 0) println(foo(m - 1).a2.n) // error + if (m > 0) println(foo(m - 1).a2.n) // warn def foo(n: Int): B = if (n % 2 == 0) new B(new A(n - 1), foo(n - 1).a1) diff --git a/tests/init/neg/unsound2.scala b/tests/init/warn/unsound2.scala similarity index 88% rename from tests/init/neg/unsound2.scala rename to tests/init/warn/unsound2.scala index 5ae0c624c32e..d8b017f2c7db 100644 --- a/tests/init/neg/unsound2.scala +++ b/tests/init/warn/unsound2.scala @@ -2,7 +2,7 @@ case class A(x: Int) { def foo(y: Int): B = if (y > 10) then B(bar(y - 1), foo(y - 1).getN) else B(bar(y), 10) def bar(y: Int): A = if (y > 10) then A(y - 1) else this class B(a: A, b: Int) { - def getN: Int = a.n // error + def getN: Int = a.n // warn def getB: Int = b } println(foo(x).getB) diff --git a/tests/init/neg/unsound3.scala b/tests/init/warn/unsound3.scala similarity index 72% rename from tests/init/neg/unsound3.scala rename to tests/init/warn/unsound3.scala index 9ede5c7f97d0..021505cb9931 100644 --- a/tests/init/neg/unsound3.scala +++ b/tests/init/warn/unsound3.scala @@ -7,7 +7,7 @@ class C { def foo(): B = { x += 1 val newB = new B(this) - if (x < 12) then foo().getC().b else newB // error + if (x < 12) then foo().getC().b else newB // warn } val b = foo() } \ No newline at end of file diff --git a/tests/init/neg/unsound4.scala b/tests/init/warn/unsound4.scala similarity index 70% rename from tests/init/neg/unsound4.scala rename to tests/init/warn/unsound4.scala index 8a6e26fe8a6b..2b1a69723342 100644 --- a/tests/init/neg/unsound4.scala +++ b/tests/init/warn/unsound4.scala @@ -1,4 +1,4 @@ class A { def foo(x: Int): A = if (x < 5) then this else foo(x - 1).aAgain - val aAgain = foo(5) // error + val aAgain = foo(5) // warn } \ No newline at end of file diff --git a/tests/neg-custom-args/captures/byname.check b/tests/neg-custom-args/captures/byname.check index 61b83fc24688..226bee2cd0e5 100644 --- a/tests/neg-custom-args/captures/byname.check +++ b/tests/neg-custom-args/captures/byname.check @@ -1,12 +1,24 @@ --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:10:6 ---------------------------------------- -10 | h(f2()) // error - | ^^^^ - | Found: (x$0: Int) ->{cap1} Int - | Required: (x$0: Int) ->{cap2} Int - | - | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/byname.scala:19:5 ------------------------------------------------------------- 19 | h(g()) // error | ^^^ | reference (cap2 : Cap^) is not included in the allowed capture set {cap1} | of an enclosing function literal with expected type () ?->{cap1} I +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:4:2 ----------------------------------------- + 4 | def f() = if cap1 == cap1 then g else g // error + | ^ + | Found: (x$0: Int) ->{cap2} Int + | Required: (x$0: Int) -> Int + | + | Note that the expected type Int => Int + | is the previously inferred result type of method test + | which is also the type seen in separately compiled sources. + | The new inferred type (x$0: Int) ->{cap2} Int + | must conform to this type. + 5 | def g(x: Int) = if cap2 == cap2 then 1 else x + 6 | def g2(x: Int) = if cap1 == cap1 then 1 else x + 7 | def f2() = if cap1 == cap1 then g2 else g2 + 8 | def h(ff: => Int ->{cap2} Int) = ff + 9 | h(f()) +10 | h(f2()) + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/byname.scala b/tests/neg-custom-args/captures/byname.scala index ac13174eb4f4..279122f54735 100644 --- a/tests/neg-custom-args/captures/byname.scala +++ b/tests/neg-custom-args/captures/byname.scala @@ -1,13 +1,13 @@ @annotation.capability class Cap def test(cap1: Cap, cap2: Cap) = - def f() = if cap1 == cap1 then g else g + def f() = if cap1 == cap1 then g else g // error def g(x: Int) = if cap2 == cap2 then 1 else x def g2(x: Int) = if cap1 == cap1 then 1 else x def f2() = if cap1 == cap1 then g2 else g2 def h(ff: => Int ->{cap2} Int) = ff - h(f()) // ok - h(f2()) // error + h(f()) + h(f2()) class I diff --git a/tests/neg-custom-args/captures/cc-selftype-unsound.scala b/tests/neg-custom-args/captures/cc-selftype-unsound.scala new file mode 100644 index 000000000000..5aaaf5e8b8ca --- /dev/null +++ b/tests/neg-custom-args/captures/cc-selftype-unsound.scala @@ -0,0 +1,15 @@ +import language.experimental.captureChecking +trait Logger +case class Boxed[T](unbox: T) + +// a horrible function, but it typechecks +def magic(l: Logger^): Logger = + class Foo: + def foo: Boxed[Logger^{this}] = + // for the following line to typecheck + // the capture checker assumes {l} <: {this} + Boxed[Logger^{this}](l) // error + val x = new Foo + val y = x.foo.unbox // y: Logger^{x} + val z: Logger = y // now the capability becomes pure + z diff --git a/tests/neg-custom-args/captures/cc-this4.check b/tests/neg-custom-args/captures/cc-this4.check index 52c06f5bbc30..d650d905f9b5 100644 --- a/tests/neg-custom-args/captures/cc-this4.check +++ b/tests/neg-custom-args/captures/cc-this4.check @@ -1,6 +1,7 @@ --- Error: tests/neg-custom-args/captures/cc-this4.scala:1:11 ----------------------------------------------------------- -1 |open class C: // error - | ^ - | class C needs an explicitly declared self type since its - | inferred self type C^{} - | is not visible in other compilation units that define subclasses. +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-this4.scala:2:13 -------------------------------------- +2 | val x: C = this // error + | ^^^^ + | Found: (C.this : C^) + | Required: C + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-this4.scala b/tests/neg-custom-args/captures/cc-this4.scala index 7580067bfa62..aa2d53a55642 100644 --- a/tests/neg-custom-args/captures/cc-this4.scala +++ b/tests/neg-custom-args/captures/cc-this4.scala @@ -1,5 +1,5 @@ -open class C: // error - val x: C = this +open class C: + val x: C = this // error open class D: this: D => diff --git a/tests/neg-custom-args/captures/usingLogFile.check b/tests/neg-custom-args/captures/usingLogFile.check index 476bf99ef0ef..ef0c5d1e77c9 100644 --- a/tests/neg-custom-args/captures/usingLogFile.check +++ b/tests/neg-custom-args/captures/usingLogFile.check @@ -10,7 +10,3 @@ 44 | val later = usingFile("out", f => (y: Int) => xs.foreach(x => f.write(x + y))) // error | ^^^^^^^^^ | local reference f leaks into outer capture set of type parameter T of method usingFile --- Error: tests/neg-custom-args/captures/usingLogFile.scala:52:16 ------------------------------------------------------ -52 | val later = usingFile("logfile", // error !!! but should be ok, since we can widen `l` to `file` instead of to `cap` - | ^^^^^^^^^ - | local reference l leaks into outer capture set of type parameter T of method usingFile diff --git a/tests/neg-custom-args/captures/usingLogFile.scala b/tests/neg-custom-args/captures/usingLogFile.scala index e5dc271975b0..67e6f841e7ce 100644 --- a/tests/neg-custom-args/captures/usingLogFile.scala +++ b/tests/neg-custom-args/captures/usingLogFile.scala @@ -49,6 +49,6 @@ object Test3: op(logger) def test = - val later = usingFile("logfile", // error !!! but should be ok, since we can widen `l` to `file` instead of to `cap` + val later = usingFile("logfile", // now ok usingLogger(_, l => () => l.log("test"))) later() diff --git a/tests/neg-custom-args/sourcepath2/hi/A.check b/tests/neg-custom-args/sourcepath2/hi/A.check index 61d4798a34e7..6267edaac603 100644 --- a/tests/neg-custom-args/sourcepath2/hi/A.check +++ b/tests/neg-custom-args/sourcepath2/hi/A.check @@ -1,6 +1,7 @@ --- Error: tests/neg-custom-args/sourcepath2/hi/A.scala:3:6 ------------------------------------------------------------- -3 |class Hello { // error +-- Warning: tests/neg-custom-args/sourcepath2/hi/A.scala:3:6 ----------------------------------------------------------- +3 |class Hello { // warn | ^ | class Hello is in the wrong directory. | It was declared to be in package <empty> | But it is found in directory hi +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg-custom-args/sourcepath2/hi/A.scala b/tests/neg-custom-args/sourcepath2/hi/A.scala index c332f2494e15..051ed021d8ba 100644 --- a/tests/neg-custom-args/sourcepath2/hi/A.scala +++ b/tests/neg-custom-args/sourcepath2/hi/A.scala @@ -1,5 +1,6 @@ // Missing `package hi` -class Hello { // error +class Hello { // warn val x: Int = 1 } +// nopos-error: werror diff --git a/tests/neg-deep-subtype/3324b.scala b/tests/neg-deep-subtype/3324b.scala deleted file mode 100644 index df0cc5432eff..000000000000 --- a/tests/neg-deep-subtype/3324b.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -class C[T] { - val x: Any = ??? - if (x.isInstanceOf[List[String]]) // error: unchecked - if (x.isInstanceOf[T]) // error: unchecked - x match { - case x: List[String] => // error: unchecked - case x: T => // error: unchecked - } -} diff --git a/tests/neg-deep-subtype/3324f.scala b/tests/neg-deep-subtype/3324f.scala deleted file mode 100644 index 445da5cb25a0..000000000000 --- a/tests/neg-deep-subtype/3324f.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -trait C[T] -class D[T] - -class Test { - def foo[T](x: C[T]) = x match { - case _: D[T] => // error - case _: C[Int] => // error - } -} \ No newline at end of file diff --git a/tests/neg-deep-subtype/i3324.scala b/tests/neg-deep-subtype/i3324.scala deleted file mode 100644 index 9b1060836430..000000000000 --- a/tests/neg-deep-subtype/i3324.scala +++ /dev/null @@ -1,6 +0,0 @@ -//> using options -Xfatal-warnings - -class Foo { - def foo(x: Any): Boolean = - x.isInstanceOf[List[String]] // error -} diff --git a/tests/neg-macros/i14772.check b/tests/neg-macros/i14772.check index 42f78b76754c..94b4a3445b01 100644 --- a/tests/neg-macros/i14772.check +++ b/tests/neg-macros/i14772.check @@ -1,6 +1,11 @@ --- [E044] Cyclic Error: tests/neg-macros/i14772.scala:7:7 -------------------------------------------------------------- -7 | foo(a) // error +-- [E044] Cyclic Error: tests/neg-macros/i14772.scala:8:7 -------------------------------------------------------------- +8 | foo(a) // error | ^ | Overloaded or recursive method impl needs return type | + | The error occurred while trying to compute the signature of method $anonfun + | which required to compute the signature of method impl + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. + | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-macros/i14772.scala b/tests/neg-macros/i14772.scala index a0cb3c5e857e..6437f5e87769 100644 --- a/tests/neg-macros/i14772.scala +++ b/tests/neg-macros/i14772.scala @@ -1,3 +1,4 @@ +//> using options -explain-cyclic import scala.quoted.* object A { diff --git a/tests/neg-macros/i16582.check b/tests/neg-macros/i16582.check index c06fe0d9829f..548a4491ed24 100644 --- a/tests/neg-macros/i16582.check +++ b/tests/neg-macros/i16582.check @@ -1,10 +1,16 @@ --- Error: tests/neg-macros/i16582/Test_2.scala:5:27 -------------------------------------------------------------------- -5 | val o2 = ownerDoesNotWork(2) // error +-- Error: tests/neg-macros/i16582/Test_2.scala:6:27 -------------------------------------------------------------------- +6 | val o2 = ownerDoesNotWork(2) // error | ^^^^^^^^^^^^^^^^^^^ | Exception occurred while executing macro expansion. | dotty.tools.dotc.core.CyclicReference: Recursive value o2 needs type | + | The error occurred while trying to compute the signature of method test + | which required to compute the signature of value o2 + | which required to compute the signature of value o2 + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. + | | See full stack trace using -Ydebug |--------------------------------------------------------------------------------------------------------------------- |Inline stack trace diff --git a/tests/neg-macros/i16582/Test_2.scala b/tests/neg-macros/i16582/Test_2.scala index 7cfd65febd00..3b87f18f75c2 100644 --- a/tests/neg-macros/i16582/Test_2.scala +++ b/tests/neg-macros/i16582/Test_2.scala @@ -1,3 +1,4 @@ +//> using options -explain-cyclic def test= val o1 = ownerWorks(1) println(o1) diff --git a/tests/neg-macros/i18677-a.check b/tests/neg-macros/i18677-a.check new file mode 100644 index 000000000000..976ff7bddda2 --- /dev/null +++ b/tests/neg-macros/i18677-a.check @@ -0,0 +1,22 @@ + +-- Error: tests/neg-macros/i18677-a/Test_2.scala:4:6 ------------------------------------------------------------------- +3 |@extendFoo +4 |class AFoo // error + |^ + |Malformed tree was found while expanding macro with -Xcheck-macros. + |The tree does not conform to the compiler's tree invariants. + | + |Macro was: + |@scala.annotation.internal.SourceFile("tests/neg-macros/i18677-a/Test_2.scala") @extendFoo class AFoo() + | + |The macro returned: + |@scala.annotation.internal.SourceFile("tests/neg-macros/i18677-a/Test_2.scala") @extendFoo class AFoo() extends Foo + | + |Error: + |assertion failed: Parents of class symbol differs from the parents in the tree for class AFoo + | + |Parents in symbol: [class Object] + |Parents in tree: [trait Foo] + | + | + |stacktrace available when compiling with `-Ydebug` diff --git a/tests/neg-macros/i18677-a/Macro_1.scala b/tests/neg-macros/i18677-a/Macro_1.scala new file mode 100644 index 000000000000..f624d2d15782 --- /dev/null +++ b/tests/neg-macros/i18677-a/Macro_1.scala @@ -0,0 +1,18 @@ +//> using -expermiental + +import annotation.MacroAnnotation +import quoted.* + +trait Foo + +class extendFoo extends MacroAnnotation : + override def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + import quotes.reflect.* + tree match + case ClassDef(name, ctr, p, self, body) => + val parents = List(TypeTree.of[Foo]) + val newTree = ClassDef.copy(tree)(name, ctr, parents, self, body) + newTree :: Nil + case _ => + report.error("@extendFoo can only annotate class definitions") + tree :: Nil \ No newline at end of file diff --git a/tests/neg-macros/i18677-a/Test_2.scala b/tests/neg-macros/i18677-a/Test_2.scala new file mode 100644 index 000000000000..486d7e09a4bc --- /dev/null +++ b/tests/neg-macros/i18677-a/Test_2.scala @@ -0,0 +1,4 @@ +//> using -expermiental + +@extendFoo +class AFoo // error \ No newline at end of file diff --git a/tests/neg-macros/i18677-b.check b/tests/neg-macros/i18677-b.check new file mode 100644 index 000000000000..b6d817a53706 --- /dev/null +++ b/tests/neg-macros/i18677-b.check @@ -0,0 +1,22 @@ + +-- Error: tests/neg-macros/i18677-b/Test_2.scala:4:6 ------------------------------------------------------------------- +3 |@extendFoo +4 |class AFoo // error + |^ + |Malformed tree was found while expanding macro with -Xcheck-macros. + |The tree does not conform to the compiler's tree invariants. + | + |Macro was: + |@scala.annotation.internal.SourceFile("tests/neg-macros/i18677-b/Test_2.scala") @extendFoo class AFoo() + | + |The macro returned: + |@scala.annotation.internal.SourceFile("tests/neg-macros/i18677-b/Test_2.scala") @extendFoo class AFoo() extends Foo + | + |Error: + |assertion failed: Parents of class symbol differs from the parents in the tree for class AFoo + | + |Parents in symbol: [class Object] + |Parents in tree: [class Foo] + | + | + |stacktrace available when compiling with `-Ydebug` diff --git a/tests/neg-macros/i18677-b/Macro_1.scala b/tests/neg-macros/i18677-b/Macro_1.scala new file mode 100644 index 000000000000..b2ff946ad302 --- /dev/null +++ b/tests/neg-macros/i18677-b/Macro_1.scala @@ -0,0 +1,18 @@ +//> using -expermiental + +import annotation.MacroAnnotation +import quoted.* + +class Foo + +class extendFoo extends MacroAnnotation : + override def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + import quotes.reflect.* + tree match + case ClassDef(name, ctr, p, self, body) => + val parents = List(TypeTree.of[Foo]) + val newTree = ClassDef.copy(tree)(name, ctr, parents, self, body) + newTree :: Nil + case _ => + report.error("@extendFoo can only annotate class definitions") + tree :: Nil \ No newline at end of file diff --git a/tests/neg-macros/i18677-b/Test_2.scala b/tests/neg-macros/i18677-b/Test_2.scala new file mode 100644 index 000000000000..486d7e09a4bc --- /dev/null +++ b/tests/neg-macros/i18677-b/Test_2.scala @@ -0,0 +1,4 @@ +//> using -expermiental + +@extendFoo +class AFoo // error \ No newline at end of file diff --git a/tests/neg-macros/i19342.check b/tests/neg-macros/i19342.check new file mode 100644 index 000000000000..13644dc130c2 --- /dev/null +++ b/tests/neg-macros/i19342.check @@ -0,0 +1,6 @@ +-- Error: tests/neg-macros/i19342.scala:5:26 --------------------------------------------------------------------------- +5 | case '{ ((y: Int) => $f(y)).apply($z: Int) } => () // error + | ^ + | Type must be fully defined. + | Consider annotating the splice using a type ascription: + | ($f(y): XYZ). diff --git a/tests/neg-macros/i19342.scala b/tests/neg-macros/i19342.scala new file mode 100644 index 000000000000..afdcecf96941 --- /dev/null +++ b/tests/neg-macros/i19342.scala @@ -0,0 +1,7 @@ +import scala.quoted.* + +def scrutinizeHoas(expr: Expr[Int])(using Quotes): Unit = + expr match { + case '{ ((y: Int) => $f(y)).apply($z: Int) } => () // error + case _ => () + } diff --git a/tests/neg-macros/i19601/Macro.scala b/tests/neg-macros/i19601/Macro.scala new file mode 100644 index 000000000000..8d6d22005017 --- /dev/null +++ b/tests/neg-macros/i19601/Macro.scala @@ -0,0 +1,42 @@ +package prelude +import scala.quoted.* + +object Macros { + def validateInlineImpl[A: Type](assertionExpr: Expr[Assertion[A]], a: Expr[A])(using + Quotes + ): Expr[Unit] = { + import quotes.reflect.* + val crashRoot = assertionExpr.value + '{ () } + + } + given [A](using Type[A]): FromExpr[Assertion[A]] with { + def unapply(assertion: Expr[Assertion[A]])(using Quotes): Option[Assertion[A]] = { + import quotes.reflect.* + + assertion match { + case '{ Assertion.greaterThanOrEqualTo[A](${ LiteralUnlift(value) })($_) } => + Some(Assertion.greaterThanOrEqualTo(value)(orderingForValue(value))) + case _ => None + } + } + } + + object LiteralUnlift { + def unapply[A: Type](expr: Expr[A])(using Quotes): Option[A] = expr match { + case '{ ${ Expr(int) }: Int } => Some(int) + case '{ Int.MaxValue } => Some(Int.MaxValue.asInstanceOf[A]) + case '{ Int.MinValue } => Some(Int.MinValue.asInstanceOf[A]) + case '{ ${ Expr(string) }: String } => Some(string) + case '{ ${ Expr(double) }: Double } => Some(double) + case '{ ${ Expr(float) }: Float } => Some(float) + case '{ ${ Expr(long) }: Long } => Some(long) + case '{ ${ Expr(short) }: Short } => Some(short) + case '{ ${ Expr(byte) }: Byte } => Some(byte) + case '{ ${ Expr(char) }: Char } => Some(char) + case _ => None + } + } + + private def orderingForValue(any: Any)(using Quotes): Ordering[Any] = null.asInstanceOf[Ordering[Any]] +} diff --git a/tests/neg-macros/i19601/Test.scala b/tests/neg-macros/i19601/Test.scala new file mode 100644 index 000000000000..f10a06badaf7 --- /dev/null +++ b/tests/neg-macros/i19601/Test.scala @@ -0,0 +1,44 @@ +package prelude + +sealed trait Assertion[-A]: + def unary_! : Assertion[A] = ??? + def apply(a: A): Either[AssertionError, Unit] = ??? +object Assertion: + val anything: Assertion[Any] = ??? + def greaterThanOrEqualTo[A](value: A)(implicit ordering: Ordering[A]): Assertion[A] = ??? + +sealed trait AssertionError + +abstract class NewtypeCustom[A] { + type Type + protected inline def validateInline(inline value: A): Unit + + inline def apply(inline a1: A): Type = { + validateInline(a1) + a1.asInstanceOf[Type] + } +} +abstract class Newtype[A] extends NewtypeCustom[A] { + def assertion: Assertion[A] = Assertion.anything + protected inline def validateInline(inline value: A): Unit = ${ + Macros.validateInlineImpl[A]('assertion, 'value) + } +} + + +abstract class Subtype[A] extends Newtype[A] { + type Type <: A +} + + +package object newtypes { + type Natural = Natural.Type + object Natural extends Subtype[Int] { + + override inline def assertion = Assertion.greaterThanOrEqualTo(0) + + val one: Natural = Natural(1) // triggers macro + } +} + +// nopos-error: Cyclic macro dependencies in tests/pos-macros/i19601/Test.scala. Compilation stopped since no further progress can be made. diff --git a/tests/neg-macros/i9570.check b/tests/neg-macros/i9570.check new file mode 100644 index 000000000000..3c1f0f644318 --- /dev/null +++ b/tests/neg-macros/i9570.check @@ -0,0 +1,5 @@ +-- Warning: tests/neg-macros/i9570.scala:15:21 ------------------------------------------------------------------------- +15 | case '{HCons(_,$t)} => // warn (in .check file) + | ^ + | Use of `_` for lambda in quoted pattern. Use explicit lambda instead or use `$_` to match any term. +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg-macros/i9570.scala b/tests/neg-macros/i9570.scala index 9242fd2e9bbd..f1bae86fc17a 100644 --- a/tests/neg-macros/i9570.scala +++ b/tests/neg-macros/i9570.scala @@ -12,7 +12,7 @@ object Macros { private def sizeImpl(e: Expr[HList], n:Int)(using qctx:Quotes): Expr[Int] = { import quotes.reflect.* e match { - case '{HCons(_,$t)} => // error if run with fatal warinings in BootstrappedOnlyCompilationTests + case '{HCons(_,$t)} => // warn (in .check file) sizeImpl(t,n+1) case '{HNil} => Expr(n) } @@ -24,3 +24,5 @@ object Macros { } } + +// nopos-error No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg-macros/macro-deprecation.check b/tests/neg-macros/macro-deprecation.check new file mode 100644 index 000000000000..c3ba52b73c56 --- /dev/null +++ b/tests/neg-macros/macro-deprecation.check @@ -0,0 +1,5 @@ +-- Deprecation Warning: tests/neg-macros/macro-deprecation.scala:5:18 -------------------------------------------------- +5 |inline def f = ${ impl } // warn (in .check file) + | ^^^^ + | method impl is deprecated +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg-macros/macro-deprecation.scala b/tests/neg-macros/macro-deprecation.scala index ad1cdda001bb..7d44658bef90 100644 --- a/tests/neg-macros/macro-deprecation.scala +++ b/tests/neg-macros/macro-deprecation.scala @@ -2,5 +2,7 @@ import scala.quoted.* -inline def f = ${ impl } // error +inline def f = ${ impl } // warn (in .check file) @deprecated def impl(using Quotes) = '{1} + +// nopos-error No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg-macros/wrong-owner.check b/tests/neg-macros/wrong-owner.check index ccaca98e3948..ca8751d0fe1c 100644 --- a/tests/neg-macros/wrong-owner.check +++ b/tests/neg-macros/wrong-owner.check @@ -5,19 +5,18 @@ 5 |class Foo // error |^ |Malformed tree was found while expanding macro with -Xcheck-macros. - | |The tree does not conform to the compiler's tree invariants. - | | - | |Macro was: - | |@scala.annotation.internal.SourceFile("tests/neg-macros/wrong-owner/Test_2.scala") @wrongOwner @scala.annotation.experimental class Foo() - | | - | |The macro returned: - | |@scala.annotation.internal.SourceFile("tests/neg-macros/wrong-owner/Test_2.scala") @wrongOwner @scala.annotation.experimental class Foo() { + |The tree does not conform to the compiler's tree invariants. + | + |Macro was: + |@scala.annotation.internal.SourceFile("tests/neg-macros/wrong-owner/Test_2.scala") @wrongOwner @scala.annotation.experimental class Foo() + | + |The macro returned: + |@scala.annotation.internal.SourceFile("tests/neg-macros/wrong-owner/Test_2.scala") @wrongOwner @scala.annotation.experimental class Foo() { | override def toString(): java.lang.String = "Hello from macro" |} - | | - | |Error: - | |assertion failed: bad owner; method toString has owner class String, expected was class Foo + | + |Error: + |assertion failed: bad owner; method toString has owner class String, expected was class Foo |owner chain = method toString, class String, package java.lang, package java, package <root>, ctxOwners = class Foo, class Foo, package <empty>, package <empty>, package <empty>, package <root>, package <root>, package <root>, package <root>, package <root>, package <root>, <none>, <none>, <none>, <none>, <none> - | | + | |stacktrace available when compiling with `-Ydebug` - | | diff --git a/tests/neg-scalajs/enumeration-warnings.check b/tests/neg-scalajs/enumeration-warnings.check index b356a150daa5..d092d545b22b 100644 --- a/tests/neg-scalajs/enumeration-warnings.check +++ b/tests/neg-scalajs/enumeration-warnings.check @@ -1,60 +1,61 @@ --- Error: tests/neg-scalajs/enumeration-warnings.scala:6:4 ------------------------------------------------------------- -6 | Value // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:6:4 ----------------------------------------------------------- +6 | Value // warn | ^^^^^ | Could not transform call to scala.Enumeration.Value. | The resulting program is unlikely to function properly as this operation requires reflection. --- Error: tests/neg-scalajs/enumeration-warnings.scala:10:9 ------------------------------------------------------------ -10 | Value(4) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:10:9 ---------------------------------------------------------- +10 | Value(4) // warn | ^^^^^^^^ | Could not transform call to scala.Enumeration.Value. | The resulting program is unlikely to function properly as this operation requires reflection. --- Error: tests/neg-scalajs/enumeration-warnings.scala:15:15 ----------------------------------------------------------- -15 | val a = Value(null) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:15:15 --------------------------------------------------------- +15 | val a = Value(null) // warn | ^^^^^^^^^^^ | Passing null as name to scala.Enumeration.Value requires reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:16:15 ----------------------------------------------------------- -16 | val b = Value(10, null) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:16:15 --------------------------------------------------------- +16 | val b = Value(10, null) // warn | ^^^^^^^^^^^^^^^ | Passing null as name to scala.Enumeration.Value requires reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:20:10 ----------------------------------------------------------- -20 | val a = new Val // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:20:10 --------------------------------------------------------- +20 | val a = new Val // warn | ^^^^^^^ | Calls to the non-string constructors of scala.Enumeration.Val require reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:21:10 ----------------------------------------------------------- -21 | val b = new Val(10) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:21:10 --------------------------------------------------------- +21 | val b = new Val(10) // warn | ^^^^^^^^^^^ | Calls to the non-string constructors of scala.Enumeration.Val require reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:25:10 ----------------------------------------------------------- -25 | val a = new Val(null) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:25:10 --------------------------------------------------------- +25 | val a = new Val(null) // warn | ^^^^^^^^^^^^^ | Passing null as name to a constructor of scala.Enumeration.Val requires reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:26:10 ----------------------------------------------------------- -26 | val b = new Val(10, null) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:26:10 --------------------------------------------------------- +26 | val b = new Val(10, null) // warn | ^^^^^^^^^^^^^^^^^ | Passing null as name to a constructor of scala.Enumeration.Val requires reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:30:31 ----------------------------------------------------------- -30 | protected class Val1 extends Val // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:30:31 --------------------------------------------------------- +30 | protected class Val1 extends Val // warn | ^^^ | Calls to the non-string constructors of scala.Enumeration.Val require reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:31:31 ----------------------------------------------------------- -31 | protected class Val2 extends Val(1) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:31:31 --------------------------------------------------------- +31 | protected class Val2 extends Val(1) // warn | ^^^^^^ | Calls to the non-string constructors of scala.Enumeration.Val require reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:35:31 ----------------------------------------------------------- -35 | protected class Val1 extends Val(null) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:35:31 --------------------------------------------------------- +35 | protected class Val1 extends Val(null) // warn | ^^^^^^^^^ | Passing null as name to a constructor of scala.Enumeration.Val requires reflection at run-time. | The resulting program is unlikely to function properly. --- Error: tests/neg-scalajs/enumeration-warnings.scala:36:31 ----------------------------------------------------------- -36 | protected class Val2 extends Val(1, null) // error +-- Warning: tests/neg-scalajs/enumeration-warnings.scala:36:31 --------------------------------------------------------- +36 | protected class Val2 extends Val(1, null) // warn | ^^^^^^^^^^^^ | Passing null as name to a constructor of scala.Enumeration.Val requires reflection at run-time. | The resulting program is unlikely to function properly. +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg-scalajs/enumeration-warnings.scala b/tests/neg-scalajs/enumeration-warnings.scala index b48ffc9500e3..d05c044a32ab 100644 --- a/tests/neg-scalajs/enumeration-warnings.scala +++ b/tests/neg-scalajs/enumeration-warnings.scala @@ -3,35 +3,37 @@ class UnableToTransformValue extends Enumeration { val a = { println("oh, oh!") - Value // error + Value // warn } val b = { println("oh, oh!") - Value(4) // error + Value(4) // warn } } class ValueWithNullName extends Enumeration { - val a = Value(null) // error - val b = Value(10, null) // error + val a = Value(null) // warn + val b = Value(10, null) // warn } class NewValWithNoName extends Enumeration { - val a = new Val // error - val b = new Val(10) // error + val a = new Val // warn + val b = new Val(10) // warn } class NewValWithNullName extends Enumeration { - val a = new Val(null) // error - val b = new Val(10, null) // error + val a = new Val(null) // warn + val b = new Val(10, null) // warn } class ExtendsValWithNoName extends Enumeration { - protected class Val1 extends Val // error - protected class Val2 extends Val(1) // error + protected class Val1 extends Val // warn + protected class Val2 extends Val(1) // warn } class ExtendsValWithNullName extends Enumeration { - protected class Val1 extends Val(null) // error - protected class Val2 extends Val(1, null) // error + protected class Val1 extends Val(null) // warn + protected class Val2 extends Val(1, null) // warn } + +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg-scalajs/js-native-members.check b/tests/neg-scalajs/js-native-members.check index 11acee62af90..60990cbf3d97 100644 --- a/tests/neg-scalajs/js-native-members.check +++ b/tests/neg-scalajs/js-native-members.check @@ -1,31 +1,36 @@ -- Warning: tests/neg-scalajs/js-native-members.scala:24:16 ------------------------------------------------------------ 24 | private[this] def this(x: Int) = this() // ok | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. -- Warning: tests/neg-scalajs/js-native-members.scala:28:16 ------------------------------------------------------------ 28 | private[this] val a: Int = js.native // error | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. -- Warning: tests/neg-scalajs/js-native-members.scala:32:16 ------------------------------------------------------------ 32 | private[this] var d: Int = js.native // error | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. -- Warning: tests/neg-scalajs/js-native-members.scala:36:16 ------------------------------------------------------------ 36 | private[this] def g(): Int = js.native // error | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. -- Warning: tests/neg-scalajs/js-native-members.scala:49:25 ------------------------------------------------------------ 49 | class X3 private[this] () extends js.Object { // ok | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. -- [E003] Syntax Warning: tests/neg-scalajs/js-native-members.scala:58:44 ---------------------------------------------- diff --git a/tests/neg-scalajs/js-non-native-members-qualified-private.check b/tests/neg-scalajs/js-non-native-members-qualified-private.check index fb06b91f98f8..6befabb7a9c0 100644 --- a/tests/neg-scalajs/js-non-native-members-qualified-private.check +++ b/tests/neg-scalajs/js-non-native-members-qualified-private.check @@ -1,7 +1,8 @@ -- Warning: tests/neg-scalajs/js-non-native-members-qualified-private.scala:52:28 -------------------------------------- 52 | class B private[this] () extends js.Object // ok | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. -- Error: tests/neg-scalajs/js-non-native-members-qualified-private.scala:6:32 ----------------------------------------- diff --git a/tests/neg/14034b.scala b/tests/neg/14034b.scala deleted file mode 100644 index 84f9ab3579c8..000000000000 --- a/tests/neg/14034b.scala +++ /dev/null @@ -1,15 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -@deprecated trait Exp -@deprecated val exp = 1 - -def test1 = exp // error -def test2(a: Exp) = () // error - -type Foo0 = Exp // error -type Foo = Option[Exp] // error -type Bar = Option[exp.type] // error -type Baz = Exp | Int // error -type Quux = [X] =>> X match - case Exp => Int // error -type Quuz[A <: Exp] = Int // error diff --git a/tests/neg/17284.scala b/tests/neg/17284.scala deleted file mode 100644 index 8f588233245a..000000000000 --- a/tests/neg/17284.scala +++ /dev/null @@ -1,14 +0,0 @@ -//> using options -Werror -explain - -def test = - 451.synchronized {} // error - -def test2 = - val x: Integer = 451 - x.synchronized {} // error - -def test3 = - true.synchronized {} // error - -def test4 = - true.hashCode() // success diff --git a/tests/neg/18493.check b/tests/neg/18493.check deleted file mode 100644 index 79a2872e71e8..000000000000 --- a/tests/neg/18493.check +++ /dev/null @@ -1,8 +0,0 @@ --- [E030] Match case Unreachable Error: tests/neg/18493.scala:6:9 ------------------------------------------------------ -6 | case "abc" => // error - | ^^^^^ - | Unreachable case --- [E030] Match case Unreachable Error: tests/neg/18493.scala:12:9 ----------------------------------------------------- -12 | case "abc" => // error - | ^^^^^ - | Unreachable case diff --git a/tests/neg/adhoc-extension/B.scala b/tests/neg/adhoc-extension/B.scala index 2343a9bc0060..05a243077aaa 100644 --- a/tests/neg/adhoc-extension/B.scala +++ b/tests/neg/adhoc-extension/B.scala @@ -1,10 +1,11 @@ //> using options -source future -feature -Xfatal-warnings package adhoc -class B extends A // error: adhoc-extension (under -strict -feature -Xfatal-warnings) -class C extends A // error +class B extends A // warn: adhoc-extension (under -strict -feature -Xfatal-warnings) +class C extends A // warn object O { - val a = new A {} // error - object E extends A // error -} \ No newline at end of file + val a = new A {} // warn + object E extends A // warn +} +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/avoid-warn-deprecation.scala b/tests/neg/avoid-warn-deprecation.scala deleted file mode 100644 index 45baf7addb86..000000000000 --- a/tests/neg/avoid-warn-deprecation.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings -feature - -object A { - @deprecated("use bar instead of this one", "0.2.3") - def foo: Int = 3 -} - -object B { - A.foo -} -// nopos-error there was 1 deprecation warning; re-run with -deprecation for details diff --git a/tests/neg/capt-wf.scala b/tests/neg/capt-wf.scala index fbd334726e55..7521a0e26472 100644 --- a/tests/neg/capt-wf.scala +++ b/tests/neg/capt-wf.scala @@ -13,12 +13,12 @@ def test(c: Cap, other: String): Unit = val x3a: () -> String = s1 val s2 = () => if x1 == null then "" else "abc" val x4: C^{s2} = ??? // OK - val x5: C^{c, c} = ??? // error: redundant // error: redundant + val x5: C^{c, c} = ??? // warn: redundant // warn: redundant // val x6: C^{c}^{c} = ??? // would be syntax error - val x7: Cap^{c} = ??? // error: redundant + val x7: Cap^{c} = ??? // warn: redundant // val x8: C^{c}^{cap} = ??? // would be syntax error - val x9: C^{c, cap} = ??? // error: redundant - val x10: C^{cap, c} = ??? // error: redundant + val x9: C^{c, cap} = ??? // warn: redundant + val x10: C^{cap, c} = ??? // warn: redundant def even(n: Int): Boolean = if n == 0 then true else odd(n - 1) def odd(n: Int): Boolean = if n == 1 then true else even(n - 1) @@ -34,4 +34,5 @@ def test(c: Cap, other: String): Unit = if n == 0 then true else od(n - 1) val y3: String^{ev} = ??? // error cs is empty - () \ No newline at end of file + () +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/classtag-typetest/3_1-migration.scala b/tests/neg/classtag-typetest/3_1-migration.scala index 41e0537a6dc1..f387ccabf7c4 100644 --- a/tests/neg/classtag-typetest/3_1-migration.scala +++ b/tests/neg/classtag-typetest/3_1-migration.scala @@ -5,4 +5,5 @@ import scala.reflect.ClassTag def f3_1m[T: ClassTag](x: Any): Unit = x match - case _: T => // error + case _: T => // warn +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/classtag-typetest/3_1.scala b/tests/neg/classtag-typetest/3_1.scala index d9101ff2ae57..b6c8010364fc 100644 --- a/tests/neg/classtag-typetest/3_1.scala +++ b/tests/neg/classtag-typetest/3_1.scala @@ -5,4 +5,5 @@ import scala.reflect.ClassTag def f3_1[T: ClassTag](x: Any): Unit = x match - case _: T => // error + case _: T => // warn +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/cyclic.check b/tests/neg/cyclic.check new file mode 100644 index 000000000000..19eedac04f1c --- /dev/null +++ b/tests/neg/cyclic.check @@ -0,0 +1,14 @@ +-- [E044] Cyclic Error: tests/neg/cyclic.scala:6:12 -------------------------------------------------------------------- +6 | def i() = f() // error + | ^ + | Overloaded or recursive method f needs return type + | + | The error occurred while trying to compute the signature of method f + | which required to compute the signature of method g + | which required to compute the signature of method h + | which required to compute the signature of method i + | which required to compute the signature of method f + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/cyclic.scala b/tests/neg/cyclic.scala new file mode 100644 index 000000000000..e9ffbc164ea6 --- /dev/null +++ b/tests/neg/cyclic.scala @@ -0,0 +1,6 @@ +//> using options -explain-cyclic +object O: + def f() = g() + def g() = h() + def h() = i() + def i() = f() // error diff --git a/tests/neg/i10247.scala b/tests/neg/i10247.scala deleted file mode 100644 index fc6268720a6d..000000000000 --- a/tests/neg/i10247.scala +++ /dev/null @@ -1,28 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -def usered = Color.Red // error: value Red is deprecated - -object DeprecatedContainer { - @deprecated("no foo", "0.1") val foo = 23 -} - -enum Day { - - @deprecated("no more Mondays!", "0.1") case Monday - -} - -enum Color { - - @deprecated("no Red", "0.1") case Red - - @deprecated("no Generic", "0.1") case Generic(rgb: Int) - - def useFoo1 = DeprecatedContainer.foo // error // check that only enum cases are avoided - def useMonday = Day.Monday // error // check that enum cases are declared in this enum - -} - -object Color { - def useFoo2 = DeprecatedContainer.foo // error // check that only enum cases are avoided -} diff --git a/tests/neg/i10870.check b/tests/neg/i10870.check index 857eb128b19f..c8f9c500b95b 100644 --- a/tests/neg/i10870.check +++ b/tests/neg/i10870.check @@ -5,3 +5,5 @@ | Extension methods were tried, but the search failed with: | | Overloaded or recursive method x needs return type + | + | Run with -explain-cyclic for more details. diff --git a/tests/neg/i10930.scala b/tests/neg/i10930.scala deleted file mode 100644 index 5f8a0ca1ba76..000000000000 --- a/tests/neg/i10930.scala +++ /dev/null @@ -1,15 +0,0 @@ -//> using options -Xfatal-warnings - -import language.future -@main def Test = - type LeafElem[X] = X match - case String => Char - case Array[t] => LeafElem[t] - case Iterable[t] => LeafElem[t] - case AnyVal => X - - def leafElem[X](x: X): LeafElem[X] = x match - case x: String => x.charAt(0) // error - case x: Array[t] => leafElem(x(1)) // error - case x: Iterable[t] => leafElem(x.head) // error - case x: AnyVal => x // error diff --git a/tests/neg/i10994.scala b/tests/neg/i10994.scala deleted file mode 100644 index f5f237f22dd6..000000000000 --- a/tests/neg/i10994.scala +++ /dev/null @@ -1,4 +0,0 @@ -//> using options -Xfatal-warnings - -def foo = true match - case (b: Boolean): Boolean => () // error diff --git a/tests/neg/i11022.check b/tests/neg/i11022.check deleted file mode 100644 index 55bdb0526264..000000000000 --- a/tests/neg/i11022.check +++ /dev/null @@ -1,20 +0,0 @@ --- Error: tests/neg/i11022.scala:10:7 ---------------------------------------------------------------------------------- -10 |val a: CaseClass = CaseClass(42) // error: deprecated type // error: deprecated apply method - | ^^^^^^^^^ - | class CaseClass is deprecated: no CaseClass --- Error: tests/neg/i11022.scala:10:19 --------------------------------------------------------------------------------- -10 |val a: CaseClass = CaseClass(42) // error: deprecated type // error: deprecated apply method - | ^^^^^^^^^ - | class CaseClass is deprecated: no CaseClass --- Error: tests/neg/i11022.scala:11:7 ---------------------------------------------------------------------------------- -11 |val b: CaseClass = new CaseClass(42) // error: deprecated type // error: deprecated class - | ^^^^^^^^^ - | class CaseClass is deprecated: no CaseClass --- Error: tests/neg/i11022.scala:11:23 --------------------------------------------------------------------------------- -11 |val b: CaseClass = new CaseClass(42) // error: deprecated type // error: deprecated class - | ^^^^^^^^^ - | class CaseClass is deprecated: no CaseClass --- Error: tests/neg/i11022.scala:12:14 --------------------------------------------------------------------------------- -12 |val c: Unit = CaseClass(42).magic() // error: deprecated apply method - | ^^^^^^^^^ - | class CaseClass is deprecated: no CaseClass diff --git a/tests/neg/i11022.scala b/tests/neg/i11022.scala deleted file mode 100644 index 14bc600666f9..000000000000 --- a/tests/neg/i11022.scala +++ /dev/null @@ -1,13 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -@deprecated("no CaseClass") -case class CaseClass(rgb: Int): - def magic(): Unit = () - -object CaseClass: - def notDeprecated(): Unit = () - -val a: CaseClass = CaseClass(42) // error: deprecated type // error: deprecated apply method -val b: CaseClass = new CaseClass(42) // error: deprecated type // error: deprecated class -val c: Unit = CaseClass(42).magic() // error: deprecated apply method -val d: Unit = CaseClass.notDeprecated() // compiles diff --git a/tests/neg/i11118.scala b/tests/neg/i11118.scala index 23d9b2b604b6..a94bfce47640 100644 --- a/tests/neg/i11118.scala +++ b/tests/neg/i11118.scala @@ -1,2 +1,2 @@ -// https://github.com/lampepfl/dotty/issues/11118 +// https://github.com/scala/scala3/issues/11118 val (a,b) = (1,2,3) // error // warning diff --git a/tests/neg/i11225b.check b/tests/neg/i11225b.check new file mode 100644 index 000000000000..12ec80515e6f --- /dev/null +++ b/tests/neg/i11225b.check @@ -0,0 +1,6 @@ +-- Error: tests/neg/i11225b.scala:6:26 --------------------------------------------------------------------------------- +6 | private var cached: A = _ // error + | ^ + | `= _` has been deprecated; use `= uninitialized` instead. + | `uninitialized` can be imported with `scala.compiletime.uninitialized`. + | This construct can be rewritten automatically under -rewrite -source 3.4-migration. diff --git a/tests/neg/i11225b.scala b/tests/neg/i11225b.scala index a9dd1d3d2227..c2b94571e06c 100644 --- a/tests/neg/i11225b.scala +++ b/tests/neg/i11225b.scala @@ -1,4 +1,4 @@ -//> using options -source future -deprecation -Xfatal-warnings +//> using options -source future -deprecation import compiletime.uninitialized @@ -10,3 +10,4 @@ class Memo[A](x: => A): known = true cached = x cached + diff --git a/tests/neg/i11333.check b/tests/neg/i11333.check deleted file mode 100644 index ba5723488899..000000000000 --- a/tests/neg/i11333.check +++ /dev/null @@ -1,30 +0,0 @@ --- [E167] Lossy Conversion Error: tests/neg/i11333.scala:4:19 ---------------------------------------------------------- -4 | val f1: Float = 123456789 // error - | ^^^^^^^^^ - | Widening conversion from Int to Float loses precision. - | Write `.toFloat` instead. --- [E167] Lossy Conversion Error: tests/neg/i11333.scala:5:19 ---------------------------------------------------------- -5 | val d1: Double = 1234567890123456789L // error - | ^^^^^^^^^^^^^^^^^^^^ - | Widening conversion from Long to Double loses precision. - | Write `.toDouble` instead. --- [E167] Lossy Conversion Error: tests/neg/i11333.scala:6:19 ---------------------------------------------------------- -6 | val f2: Float = 123456789L // error - | ^^^^^^^^^^ - | Widening conversion from Long to Float loses precision. - | Write `.toFloat` instead. --- [E167] Lossy Conversion Error: tests/neg/i11333.scala:12:21 --------------------------------------------------------- -12 | val f1_b: Float = i1 // error - | ^^ - | Widening conversion from Int to Float loses precision. - | Write `.toFloat` instead. --- [E167] Lossy Conversion Error: tests/neg/i11333.scala:13:21 --------------------------------------------------------- -13 | val d1_b: Double = l1 // error - | ^^ - | Widening conversion from Long to Double loses precision. - | Write `.toDouble` instead. --- [E167] Lossy Conversion Error: tests/neg/i11333.scala:14:21 --------------------------------------------------------- -14 | val f2_b: Float = l2 // error - | ^^ - | Widening conversion from Long to Float loses precision. - | Write `.toFloat` instead. diff --git a/tests/neg/i11333.scala b/tests/neg/i11333.scala deleted file mode 100644 index bbdcceaf7e1e..000000000000 --- a/tests/neg/i11333.scala +++ /dev/null @@ -1,14 +0,0 @@ -//> using options -Xfatal-warnings - -class C: - val f1: Float = 123456789 // error - val d1: Double = 1234567890123456789L // error - val f2: Float = 123456789L // error - - inline val i1 = 123456789 - inline val l1 = 1234567890123456789L - inline val l2 = 123456789L - - val f1_b: Float = i1 // error - val d1_b: Double = l1 // error - val f2_b: Float = l2 // error diff --git a/tests/neg/i11963a.scala b/tests/neg/i11963a.scala deleted file mode 100644 index 0eb2f557624f..000000000000 --- a/tests/neg/i11963a.scala +++ /dev/null @@ -1,3 +0,0 @@ -//> using options -Xfatal-warnings - -open trait Foo // error diff --git a/tests/neg/i11963b.scala b/tests/neg/i11963b.scala deleted file mode 100644 index 76097b225896..000000000000 --- a/tests/neg/i11963b.scala +++ /dev/null @@ -1,3 +0,0 @@ -//> using options -Xfatal-warnings - -open abstract class Foo // error diff --git a/tests/neg/i11963c.scala b/tests/neg/i11963c.scala deleted file mode 100644 index f58f68c72368..000000000000 --- a/tests/neg/i11963c.scala +++ /dev/null @@ -1,8 +0,0 @@ -//> using options -Xfatal-warnings - -object Test { - def foo: Any = { - open class Bar // error - new Bar - } -} diff --git a/tests/neg/i11994.check b/tests/neg/i11994.check index 24d18257ed9f..76860af70a39 100644 --- a/tests/neg/i11994.check +++ b/tests/neg/i11994.check @@ -1,14 +1,26 @@ --- [E008] Not Found Error: tests/neg/i11994.scala:1:28 ----------------------------------------------------------------- -1 |implicit def foo[T <: Tuple.meow]: Unit = ??? // error +-- [E008] Not Found Error: tests/neg/i11994.scala:2:28 ----------------------------------------------------------------- +2 |implicit def foo[T <: Tuple.meow]: Unit = ??? // error | ^^^^^^^^^^ | type meow is not a member of object Tuple. | Extension methods were tried, but the search failed with: | | Cyclic reference involving method foo --- [E008] Not Found Error: tests/neg/i11994.scala:2:18 ----------------------------------------------------------------- -2 |given [T <: Tuple.meow]: Unit = ??? // error + | + | The error occurred while trying to compute the signature of method foo + | which required to compute the signature of type T + | which required to compute the signature of method foo + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E008] Not Found Error: tests/neg/i11994.scala:3:18 ----------------------------------------------------------------- +3 |given [T <: Tuple.meow]: Unit = ??? // error | ^^^^^^^^^^ | type meow is not a member of object Tuple. | Extension methods were tried, but the search failed with: | | Cyclic reference involving method given_Unit + | + | The error occurred while trying to compute the signature of given instance given_Unit + | which required to compute the signature of type T + | which required to compute the signature of given instance given_Unit + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. diff --git a/tests/neg/i11994.scala b/tests/neg/i11994.scala index 373de300dd42..70468535f3ab 100644 --- a/tests/neg/i11994.scala +++ b/tests/neg/i11994.scala @@ -1,2 +1,3 @@ +//> using options -explain-cyclic implicit def foo[T <: Tuple.meow]: Unit = ??? // error given [T <: Tuple.meow]: Unit = ??? // error diff --git a/tests/neg/i12188/Test.scala b/tests/neg/i12188/Test.scala index 66864438694e..511a4804e5be 100644 --- a/tests/neg/i12188/Test.scala +++ b/tests/neg/i12188/Test.scala @@ -7,5 +7,7 @@ case class PC2(b: Int) extends P def Test = MatchTest.test(PC2(10): P) def foo(x: P): Unit = - x match // error - case _: PC1 => \ No newline at end of file + x match // warn + case _: PC1 => + +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i12597.scala b/tests/neg/i12597.scala deleted file mode 100644 index b8859a0ae991..000000000000 --- a/tests/neg/i12597.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -@main def Test = - val a: IArray[Int] = IArray(2) - val b: IArray[Any] = a - val c = b.toArray // error: deprecated - c(0) = "" diff --git a/tests/neg/i13440.scala b/tests/neg/i13440.scala deleted file mode 100644 index 443215c621ef..000000000000 --- a/tests/neg/i13440.scala +++ /dev/null @@ -1,9 +0,0 @@ -//> using options -Xfatal-warnings - -import language.`3.0-migration` - -def given = 42 // error - -case class C(enum: List[Int] = Nil) { // error - val s = s"$enum" // error -} diff --git a/tests/neg/i13780-1.check b/tests/neg/i13780-1.check index 029ef3f3ac4b..07cc03b35dce 100644 --- a/tests/neg/i13780-1.check +++ b/tests/neg/i13780-1.check @@ -5,7 +5,7 @@ | Required: h | | where: VS is a type in method foo with bounds <: Tuple - | h is a type in method foo with bounds + | h is a type in method foo | t is a type in method foo with bounds <: Tuple | | diff --git a/tests/neg/i13946/BadPrinter.scala b/tests/neg/i13946/BadPrinter.scala index 46913d2c2805..f26ae97c1dfb 100644 --- a/tests/neg/i13946/BadPrinter.scala +++ b/tests/neg/i13946/BadPrinter.scala @@ -2,5 +2,6 @@ // in BadPrinter.scala import language.future -class BadPrinter extends Printer: // error +class BadPrinter extends Printer: // warn override def print(s: String): Unit = println("Bad!!!") +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i14386.scala b/tests/neg/i14386.scala index be0b2497ed5f..c6d7c0a4d01e 100644 --- a/tests/neg/i14386.scala +++ b/tests/neg/i14386.scala @@ -42,7 +42,8 @@ def braced() = s"""begin ${ val level = 10 - val msg = "hello, world" // error he lets me off with a warning - log(level, msg) // error + val msg = "hello, world" // warn he lets me off with a warning + log(level, msg) // warn } end""" +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i14705.scala b/tests/neg/i14705.scala deleted file mode 100644 index 9ffb4443416e..000000000000 --- a/tests/neg/i14705.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -val n = Nil -val b = n.head.isInstanceOf[String] // error - diff --git a/tests/neg/i15474b.check b/tests/neg/i15474b.check index 73ef720af7e3..ac894168d51e 100644 --- a/tests/neg/i15474b.check +++ b/tests/neg/i15474b.check @@ -1,5 +1,6 @@ --- Error: tests/neg/i15474b.scala:7:40 --------------------------------------------------------------------------------- -7 | def apply(from: String): Int = from.toInt // error: infinite loop in function body +-- Warning: tests/neg/i15474b.scala:7:40 ------------------------------------------------------------------------------- +7 | def apply(from: String): Int = from.toInt // warn: infinite loop in function body | ^^^^^^^^^^ | Infinite loop in function body | Test1.c.apply(from).toInt +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i15474b.scala b/tests/neg/i15474b.scala index 9d496c37ef00..0c04b9880e1c 100644 --- a/tests/neg/i15474b.scala +++ b/tests/neg/i15474b.scala @@ -4,5 +4,5 @@ import scala.language.implicitConversions object Test1: given c: Conversion[ String, Int ] with - def apply(from: String): Int = from.toInt // error: infinite loop in function body - + def apply(from: String): Int = from.toInt // warn: infinite loop in function body +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i15503h.scala b/tests/neg/i15503h.scala deleted file mode 100644 index cef1f6cf566f..000000000000 --- a/tests/neg/i15503h.scala +++ /dev/null @@ -1,20 +0,0 @@ -//> using options -Xfatal-warnings -Wunused:linted - -import collection.mutable.Set // error - -class A { - private val a = 1 // error - val b = 2 // OK - - private def c = 2 // error - def d(using x:Int): Int = b // ok - def e(x: Int) = 1 // OK - def f = - val x = 1 // error - def f = 2 // error - 3 - - def g(x: Int): Int = x match - case x:1 => 0 // OK - case _ => 1 -} \ No newline at end of file diff --git a/tests/neg/i15507.check b/tests/neg/i15507.check index 3786d559c306..e31d8966b940 100644 --- a/tests/neg/i15507.check +++ b/tests/neg/i15507.check @@ -1,40 +1,70 @@ --- Error: tests/neg/i15507.scala:2:40 ---------------------------------------------------------------------------------- -2 | type _NestedSet1[X] = Set[_NestedSet1[?]] // error +-- Error: tests/neg/i15507.scala:3:40 ---------------------------------------------------------------------------------- +3 | type _NestedSet1[X] = Set[_NestedSet1[?]] // error | ^ | no wildcard type allowed here --- Error: tests/neg/i15507.scala:3:41 ---------------------------------------------------------------------------------- -3 | type _NestedSet2[X] <: Set[_NestedSet2[?]] // error +-- Error: tests/neg/i15507.scala:4:41 ---------------------------------------------------------------------------------- +4 | type _NestedSet2[X] <: Set[_NestedSet2[?]] // error | ^ | no wildcard type allowed here --- [E140] Cyclic Error: tests/neg/i15507.scala:5:7 --------------------------------------------------------------------- -5 | type _NestedSet4[X] >: Set[_NestedSet4[X]] // error +-- [E140] Cyclic Error: tests/neg/i15507.scala:6:7 --------------------------------------------------------------------- +6 | type _NestedSet4[X] >: Set[_NestedSet4[X]] // error | ^ | illegal cyclic type reference: lower bound ... of type _NestedSet4 refers back to the type itself --- [E140] Cyclic Error: tests/neg/i15507.scala:6:7 --------------------------------------------------------------------- -6 | type _NestedSet5[X] = Set[_NestedSet5[X]] // error + | + | The error occurred while trying to compute the signature of type _NestedSet4 + | which required to explore type _NestedSet4 for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i15507.scala:7:7 --------------------------------------------------------------------- +7 | type _NestedSet5[X] = Set[_NestedSet5[X]] // error | ^ | illegal cyclic type reference: alias ... of type _NestedSet5 refers back to the type itself --- [E140] Cyclic Error: tests/neg/i15507.scala:7:7 --------------------------------------------------------------------- -7 | type _NestedSet6[X] = Set[_NestedSet6[Int]] // error + | + | The error occurred while trying to compute the signature of type _NestedSet5 + | which required to explore type _NestedSet5 for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i15507.scala:8:7 --------------------------------------------------------------------- +8 | type _NestedSet6[X] = Set[_NestedSet6[Int]] // error | ^ | illegal cyclic type reference: alias ... of type _NestedSet6 refers back to the type itself --- Error: tests/neg/i15507.scala:9:43 ---------------------------------------------------------------------------------- -9 | type _NestedList1[X] = List[_NestedList1[?]] // error - | ^ - | no wildcard type allowed here --- Error: tests/neg/i15507.scala:10:44 --------------------------------------------------------------------------------- -10 | type _NestedList2[X] <: List[_NestedList2[?]] // error + | + | The error occurred while trying to compute the signature of type _NestedSet6 + | which required to explore type _NestedSet6 for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- Error: tests/neg/i15507.scala:10:43 --------------------------------------------------------------------------------- +10 | type _NestedList1[X] = List[_NestedList1[?]] // error + | ^ + | no wildcard type allowed here +-- Error: tests/neg/i15507.scala:11:44 --------------------------------------------------------------------------------- +11 | type _NestedList2[X] <: List[_NestedList2[?]] // error | ^ | no wildcard type allowed here --- [E140] Cyclic Error: tests/neg/i15507.scala:12:7 -------------------------------------------------------------------- -12 | type _NestedList4[X] >: List[_NestedList4[X]] // error +-- [E140] Cyclic Error: tests/neg/i15507.scala:13:7 -------------------------------------------------------------------- +13 | type _NestedList4[X] >: List[_NestedList4[X]] // error | ^ | illegal cyclic type reference: lower bound ... of type _NestedList4 refers back to the type itself --- [E140] Cyclic Error: tests/neg/i15507.scala:13:7 -------------------------------------------------------------------- -13 | type _NestedList5[X] = List[_NestedList5[X]] // error + | + | The error occurred while trying to compute the signature of type _NestedList4 + | which required to explore type _NestedList4 for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i15507.scala:14:7 -------------------------------------------------------------------- +14 | type _NestedList5[X] = List[_NestedList5[X]] // error | ^ | illegal cyclic type reference: alias ... of type _NestedList5 refers back to the type itself --- [E140] Cyclic Error: tests/neg/i15507.scala:14:7 -------------------------------------------------------------------- -14 | type _NestedList6[X] = List[_NestedList6[Int]] // error + | + | The error occurred while trying to compute the signature of type _NestedList5 + | which required to explore type _NestedList5 for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i15507.scala:15:7 -------------------------------------------------------------------- +15 | type _NestedList6[X] = List[_NestedList6[Int]] // error | ^ | illegal cyclic type reference: alias ... of type _NestedList6 refers back to the type itself + | + | The error occurred while trying to compute the signature of type _NestedList6 + | which required to explore type _NestedList6 for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. diff --git a/tests/neg/i15507.scala b/tests/neg/i15507.scala index f65d216ba6a2..98815756df8a 100644 --- a/tests/neg/i15507.scala +++ b/tests/neg/i15507.scala @@ -1,3 +1,4 @@ +//> using options -explain-cyclic object TestNested: type _NestedSet1[X] = Set[_NestedSet1[?]] // error type _NestedSet2[X] <: Set[_NestedSet2[?]] // error diff --git a/tests/neg/i15784.check b/tests/neg/i15784.check new file mode 100644 index 000000000000..c1540b33d956 --- /dev/null +++ b/tests/neg/i15784.check @@ -0,0 +1,12 @@ +-- [E006] Not Found Error: tests/neg/i15784.scala:2:22 ----------------------------------------------------------------- +2 | case List(_, Rest @ `a`) => Rest // error + | ^^^ + | Not found: a + | + | longer explanation available when compiling with `-explain` +-- [E006] Not Found Error: tests/neg/i15784.scala:3:22 ----------------------------------------------------------------- +3 | case List(_, Rest @ A) => Rest // error + | ^ + | Not found: A + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i15784.scala b/tests/neg/i15784.scala new file mode 100644 index 000000000000..a58a27fb3cfa --- /dev/null +++ b/tests/neg/i15784.scala @@ -0,0 +1,4 @@ +def i15784 = List(42) match + case List(_, Rest @ `a`) => Rest // error + case List(_, Rest @ A) => Rest // error + case _ => ??? \ No newline at end of file diff --git a/tests/neg/i15785.scala b/tests/neg/i15785.scala new file mode 100644 index 000000000000..f79da7a16e66 --- /dev/null +++ b/tests/neg/i15785.scala @@ -0,0 +1,4 @@ +trait SAMFunction1[-T1, +R]: + def apply(x1: T1): R + +def fooSAM[T](foo: SAMFunction1[T, T] = (f: T) => f): Unit = () // error diff --git a/tests/neg/i16876/Test.scala b/tests/neg/i16876/Test.scala index 2dd6bfb34421..dd7c1c2418ae 100644 --- a/tests/neg/i16876/Test.scala +++ b/tests/neg/i16876/Test.scala @@ -4,8 +4,7 @@ object Foo { private def myMethod(a: Int, b: Int, c: Int) = adder // ok myMethod(1, 2, 3) - private def myMethodFailing(a: Int, b: Int, c: Int) = a + 0 // error // error + private def myMethodFailing(a: Int, b: Int, c: Int) = a + 0 // warn // warn myMethodFailing(1, 2, 3) } - - +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i17612b.check b/tests/neg/i17612b.check index 75e8b7312833..681b682b459d 100644 --- a/tests/neg/i17612b.check +++ b/tests/neg/i17612b.check @@ -1,32 +1,33 @@ --- Error: tests/neg/i17612b/i17612b.scala:21:15 ------------------------------------------------------------------------ -21 | class Derived(x : Int, x3: Int, y: Int, z2: Int) extends BaseB, BaseC(x3), Base(x, y + 1, z2): // error // error / for x, y translated to private[this] x field & shadowing var Base.x, Base.y +-- Warning: tests/neg/i17612b/i17612b.scala:21:15 ---------------------------------------------------------------------- +21 | class Derived(x : Int, x3: Int, y: Int, z2: Int) extends BaseB, BaseC(x3), Base(x, y + 1, z2): // warn // warn / for x, y translated to private[this] x field & shadowing var Base.x, Base.y | ^ | value x in class Derived shadows field x inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:21:33 ------------------------------------------------------------------------ -21 | class Derived(x : Int, x3: Int, y: Int, z2: Int) extends BaseB, BaseC(x3), Base(x, y + 1, z2): // error // error / for x, y translated to private[this] x field & shadowing var Base.x, Base.y +-- Warning: tests/neg/i17612b/i17612b.scala:21:33 ---------------------------------------------------------------------- +21 | class Derived(x : Int, x3: Int, y: Int, z2: Int) extends BaseB, BaseC(x3), Base(x, y + 1, z2): // warn // warn / for x, y translated to private[this] x field & shadowing var Base.x, Base.y | ^ | value y in class Derived shadows field y inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:23:2 ------------------------------------------------------------------------- -23 | private val shadowed2 = 2 + 2 // error (In Scala 2 we cannot do that got the warning) +-- Warning: tests/neg/i17612b/i17612b.scala:23:2 ----------------------------------------------------------------------- +23 | private val shadowed2 = 2 + 2 // warn (In Scala 2 we cannot do that got the warning) | ^ | value shadowed2 in class Derived shadows field shadowed2 inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:24:2 ------------------------------------------------------------------------- -24 | private[this] val shadowed3 = 3 + 3 // error +-- Warning: tests/neg/i17612b/i17612b.scala:24:2 ----------------------------------------------------------------------- +24 | private[this] val shadowed3 = 3 + 3 // warn | ^ | value shadowed3 in class Derived shadows field shadowed3 inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:26:2 ------------------------------------------------------------------------- -26 | private val shadowed5 = 5 + 5 // error +-- Warning: tests/neg/i17612b/i17612b.scala:26:2 ----------------------------------------------------------------------- +26 | private val shadowed5 = 5 + 5 // warn | ^ | value shadowed5 in class Derived shadows field shadowed5 inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:41:20 ------------------------------------------------------------------------ -41 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // error // error // error +-- Warning: tests/neg/i17612b/i17612b.scala:41:20 ---------------------------------------------------------------------- +41 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // warn // warn // warn | ^ | value x in class UnderDerived shadows field x inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:41:28 ------------------------------------------------------------------------ -41 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // error // error // error +-- Warning: tests/neg/i17612b/i17612b.scala:41:28 ---------------------------------------------------------------------- +41 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // warn // warn // warn | ^ | value y in class UnderDerived shadows field y inherited from trait Base --- Error: tests/neg/i17612b/i17612b.scala:41:36 ------------------------------------------------------------------------ -41 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // error // error // error +-- Warning: tests/neg/i17612b/i17612b.scala:41:36 ---------------------------------------------------------------------- +41 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // warn // warn // warn | ^ | value z in class UnderDerived shadows field z inherited from trait Base +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i17612b/i17612b.scala b/tests/neg/i17612b/i17612b.scala index d16feb240c2a..62d6ad17ff3d 100644 --- a/tests/neg/i17612b/i17612b.scala +++ b/tests/neg/i17612b/i17612b.scala @@ -18,12 +18,12 @@ object i17612b: trait BaseB trait BaseC(var x2: Int) - class Derived(x : Int, x3: Int, y: Int, z2: Int) extends BaseB, BaseC(x3), Base(x, y + 1, z2): // error // error / for x, y translated to private[this] x field & shadowing var Base.x, Base.y + class Derived(x : Int, x3: Int, y: Int, z2: Int) extends BaseB, BaseC(x3), Base(x, y + 1, z2): // warn // warn / for x, y translated to private[this] x field & shadowing var Base.x, Base.y private def hello() = 4 - private val shadowed2 = 2 + 2 // error (In Scala 2 we cannot do that got the warning) - private[this] val shadowed3 = 3 + 3 // error + private val shadowed2 = 2 + 2 // warn (In Scala 2 we cannot do that got the warning) + private[this] val shadowed3 = 3 + 3 // warn - private val shadowed5 = 5 + 5 // error + private val shadowed5 = 5 + 5 // warn private val notShadowed2 = -4 val lambda: Int => Int => Int = @@ -38,7 +38,8 @@ object i17612b: override def toString = s"x : ${x.toString}, y : ${y.toString}" - class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // error // error // error + class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, 1, y, z) // warn // warn // warn def main(args: Array[String]) = val derived = new Derived(1, 1, 1, 1) +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i17613a.scala b/tests/neg/i17613a.scala deleted file mode 100644 index d0e413098cec..000000000000 --- a/tests/neg/i17613a.scala +++ /dev/null @@ -1,23 +0,0 @@ -//> using options -Xfatal-warnings -Xlint:type-parameter-shadow - -object i17613a: - class B: - type T = Int - trait D - - def foobar[D](in: D) = in.toString // error method parameter shadows some other type - type MySeq[D] = Seq[D] // error type member's parameter shadows some other type - - class Foo[T](t: T): // error class parameter shadows some other type - def bar[T](w: T) = w.toString // error a type parameter shadows another type parameter - - // even deeply nested... - class C[M[List[_]]] // error - type E[M[List[_]]] = Int // error - def foo[N[M[List[_]]]] = ??? // error - - // ...but not between type parameters in the same list - class F[A, M[N[A]]] - type G[A, M[L[A]]] = Int - def bar[A, N[M[L[A]]]] = ??? - def main(args: Array[String]) = println("Test for type parameter shadow") diff --git a/tests/neg/i17613b.check b/tests/neg/i17613b.check index d8cf8618fb27..494d218fb366 100644 --- a/tests/neg/i17613b.check +++ b/tests/neg/i17613b.check @@ -1,56 +1,61 @@ --- Error: tests/neg/i17613b/i17613b.scala:9:13 ------------------------------------------------------------------------- -9 | def foobar[ImTrait](in: D) = in.toString // error - | ^^^^^^^ - | Type parameter ImTrait for method foobar shadows the type defined by trait ImTrait in object importTry --- Error: tests/neg/i17613b/i17613b.scala:10:13 ------------------------------------------------------------------------ -10 | type MySeq[ImTrait] = Seq[D] // error +-- Warning: tests/neg/i17613b/i17613b.scala:7:18 ----------------------------------------------------------------------- +7 | trait Typeclass[T] + | ^ + | Type parameter T for trait Typeclass shadows the type defined by type T in class B +-- Warning: tests/neg/i17613b/i17613b.scala:10:13 ---------------------------------------------------------------------- +10 | def foobar[ImTrait](in: D) = in.toString // warn + | ^^^^^^^ + | Type parameter ImTrait for method foobar shadows the type defined by trait ImTrait in object importTry +-- Warning: tests/neg/i17613b/i17613b.scala:11:13 ---------------------------------------------------------------------- +11 | type MySeq[ImTrait] = Seq[D] // warn | ^^^^^^^ | Type parameter ImTrait for type MySeq shadows the type defined by trait ImTrait in object importTry --- Error: tests/neg/i17613b/i17613b.scala:12:14 ------------------------------------------------------------------------ -12 | def foobar2[ImClass](in: D) = in.toString // error +-- Warning: tests/neg/i17613b/i17613b.scala:13:14 ---------------------------------------------------------------------- +13 | def foobar2[ImClass](in: D) = in.toString // warn | ^^^^^^^ | Type parameter ImClass for method foobar2 shadows the type defined by class ImClass in object importTry --- Error: tests/neg/i17613b/i17613b.scala:13:14 ------------------------------------------------------------------------ -13 | type MySeq2[ImClass] = Seq[D] // error +-- Warning: tests/neg/i17613b/i17613b.scala:14:14 ---------------------------------------------------------------------- +14 | type MySeq2[ImClass] = Seq[D] // warn | ^^^^^^^ | Type parameter ImClass for type MySeq2 shadows the type defined by class ImClass in object importTry --- Error: tests/neg/i17613b/i17613b.scala:16:24 ------------------------------------------------------------------------ -16 | type TypeLambda[A] = [ImTrait] =>> Map[ImTrait, B] // error +-- Warning: tests/neg/i17613b/i17613b.scala:17:24 ---------------------------------------------------------------------- +17 | type TypeLambda[A] = [ImTrait] =>> Map[ImTrait, B] | ^^^^^^^ | Type parameter ImTrait for type TypeLambda shadows the type defined by trait ImTrait in object importTry --- Error: tests/neg/i17613b/i17613b.scala:17:21 ------------------------------------------------------------------------ -17 | type PolyFun[A] = [ImTrait] => ImTrait => B // error +-- Warning: tests/neg/i17613b/i17613b.scala:18:21 ---------------------------------------------------------------------- +18 | type PolyFun[A] = [ImTrait] => ImTrait => B // warn | ^^^^^^^ | Type parameter ImTrait for type PolyFun shadows the type defined by trait ImTrait in object importTry --- Error: tests/neg/i17613b/i17613b.scala:23:12 ------------------------------------------------------------------------ -23 | class Foo[T](t: T): // error class parameter shadows some other type +-- Warning: tests/neg/i17613b/i17613b.scala:24:12 ---------------------------------------------------------------------- +24 | class Foo[T](t: T): // warn class parameter shadows some other type | ^ | Type parameter T for class Foo shadows the type defined by type T in class B --- Error: tests/neg/i17613b/i17613b.scala:27:15 ------------------------------------------------------------------------ -27 | def intType[List1](x: T) = x.toString() // error +-- Warning: tests/neg/i17613b/i17613b.scala:28:15 ---------------------------------------------------------------------- +28 | def intType[List1](x: T) = x.toString() // warn | ^^^^^ | Type parameter List1 for method intType shadows an explicitly renamed type : List1 --- Error: tests/neg/i17613b/i17613b.scala:32:10 ------------------------------------------------------------------------ -32 | given [Int]: Ordering[Int]() // error +-- Warning: tests/neg/i17613b/i17613b.scala:33:10 ---------------------------------------------------------------------- +33 | given [Int]: Typeclass[Int]() // warn | ^^^ - | Type parameter Int for method given_Ordering_Int shadows the type defined by class Int in package scala --- Error: tests/neg/i17613b/i17613b.scala:34:12 ------------------------------------------------------------------------ -34 | class C[M[List[_]]] // error List not renamed here + | Type parameter Int for method given_Typeclass_Int shadows the type defined by class Int in package scala +-- Warning: tests/neg/i17613b/i17613b.scala:35:12 ---------------------------------------------------------------------- +35 | class C[M[List[_]]] // warn List not renamed here | ^^^^^^^ | Type parameter List for class C shadows the type defined by type List in package scala --- Error: tests/neg/i17613b/i17613b.scala:35:11 ------------------------------------------------------------------------ -35 | type E[M[Int[_]]] = Int // error +-- Warning: tests/neg/i17613b/i17613b.scala:36:11 ---------------------------------------------------------------------- +36 | type E[M[Int[_]]] = Int // warn | ^^^^^^ | Type parameter Int for type E shadows the type defined by class Int in package scala --- Error: tests/neg/i17613b/i17613b.scala:37:14 ------------------------------------------------------------------------ -37 | def foo[N[M[List[_]]]] = // error +-- Warning: tests/neg/i17613b/i17613b.scala:38:14 ---------------------------------------------------------------------- +38 | def foo[N[M[List[_]]]] = // warn | ^^^^^^^ | Type parameter List for method foo shadows the type defined by type List in package scala --- Error: tests/neg/i17613b/i17613b.scala:40:11 ------------------------------------------------------------------------ -40 | type Z[ImClassR] = Int // error +-- Warning: tests/neg/i17613b/i17613b.scala:41:11 ---------------------------------------------------------------------- +41 | type Z[ImClassR] = Int // warn | ^^^^^^^^ | Type parameter ImClassR for type Z shadows an explicitly renamed type : ImClassR --- Error: tests/neg/i17613b/i17613b.scala:41:18 ------------------------------------------------------------------------ -41 | class InnerCl[ImClassR] // error +-- Warning: tests/neg/i17613b/i17613b.scala:42:18 ---------------------------------------------------------------------- +42 | class InnerCl[ImClassR] // warn | ^^^^^^^^ | Type parameter ImClassR for class InnerCl shadows an explicitly renamed type : ImClassR +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i17613b/i17613b.scala b/tests/neg/i17613b/i17613b.scala index b0c4f11b949c..42506a274a65 100644 --- a/tests/neg/i17613b/i17613b.scala +++ b/tests/neg/i17613b/i17613b.scala @@ -1,44 +1,47 @@ -//> using options -Xfatal-warnings -Xlint:type-parameter-shadow +//> using options -Xlint:type-parameter-shadow -Xfatal-warnings object i17613b: import importTry._ class B: type T = Int + trait Typeclass[T] trait D - def foobar[ImTrait](in: D) = in.toString // error - type MySeq[ImTrait] = Seq[D] // error + def foobar[ImTrait](in: D) = in.toString // warn + type MySeq[ImTrait] = Seq[D] // warn - def foobar2[ImClass](in: D) = in.toString // error - type MySeq2[ImClass] = Seq[D] // error + def foobar2[ImClass](in: D) = in.toString // warn + type MySeq2[ImClass] = Seq[D] // warn - given [A]: Ordering[Int]() - type TypeLambda[A] = [ImTrait] =>> Map[ImTrait, B] // error - type PolyFun[A] = [ImTrait] => ImTrait => B // error + given [A]: Typeclass[Int]() // warn + type TypeLambda[A] = [ImTrait] =>> Map[ImTrait, B] + type PolyFun[A] = [ImTrait] => ImTrait => B // warn type MatchType[A] = A match { case String => Int case ImTrait => Boolean } - class Foo[T](t: T): // error class parameter shadows some other type + class Foo[T](t: T): // warn class parameter shadows some other type import scala.collection.immutable.{List => List1} def bar[List](w: T) = w.toString // no warning due to the explicit import renaming - def intType[List1](x: T) = x.toString() // error + def intType[List1](x: T) = x.toString() // warn type Y[List] = Int // no warning - given [A]: Ordering[A]() - given [Int]: Ordering[Int]() // error + given [A]: Typeclass[A]() + given [Int]: Typeclass[Int]() // warn - class C[M[List[_]]] // error List not renamed here - type E[M[Int[_]]] = Int // error + class C[M[List[_]]] // warn List not renamed here + type E[M[Int[_]]] = Int // warn - def foo[N[M[List[_]]]] = // error + def foo[N[M[List[_]]]] = // warn import importTry.{ImClass => ImClassR} def inner[ImClass] = // no warning - type Z[ImClassR] = Int // error - class InnerCl[ImClassR] // error + type Z[ImClassR] = Int // warn + class InnerCl[ImClassR] // warn 5 - def main(args: Array[String]) = println("Test for type parameter shadow") \ No newline at end of file + def main(args: Array[String]) = println("Test for type parameter shadow") + + // nopos-error fatal warnings diff --git a/tests/neg/i18265.check b/tests/neg/i18265.check new file mode 100644 index 000000000000..fc9f044f4e83 --- /dev/null +++ b/tests/neg/i18265.check @@ -0,0 +1,6 @@ +-- [E019] Syntax Error: tests/neg/i18265.scala:5:13 -------------------------------------------------------------------- +5 | def twice // error + | ^ + | Missing return type + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i18265.scala b/tests/neg/i18265.scala new file mode 100644 index 000000000000..5cc67b7bd182 --- /dev/null +++ b/tests/neg/i18265.scala @@ -0,0 +1,5 @@ +trait Foo + +val foo = new Foo: + extension (s: String) + def twice // error diff --git a/tests/neg/i18722.scala b/tests/neg/i18722.scala deleted file mode 100644 index c68390b76201..000000000000 --- a/tests/neg/i18722.scala +++ /dev/null @@ -1,9 +0,0 @@ -//> using options -Werror -explain - -def f1: Unit = null // error -def f2: Unit = 1 // error -def f3: Unit = "a" // error -val i: Int = 1 -def f4: Unit = i // error -val u: Unit = () -def f5: Unit = u diff --git a/tests/neg/i18862-3.4.scala b/tests/neg/i18862-3.4.scala deleted file mode 100644 index a30c8c8f1a59..000000000000 --- a/tests/neg/i18862-3.4.scala +++ /dev/null @@ -1,6 +0,0 @@ -//> using options -Werror - -import scala.language.`3.4` - -def f(x: Int*): Unit = () -def test(xs: List[Int]): Unit = f(xs: _*) // error: migration warning diff --git a/tests/neg/i18862-future-migration.scala b/tests/neg/i18862-future-migration.scala deleted file mode 100644 index ff8ba1c377c3..000000000000 --- a/tests/neg/i18862-future-migration.scala +++ /dev/null @@ -1,6 +0,0 @@ -//> using options -Werror - -import scala.language.`future-migration` - -def f(x: Int*): Unit = () -def test(xs: List[Int]): Unit = f(xs: _*) // error: migration warning diff --git a/tests/neg/i18867-3.4.scala b/tests/neg/i18867-3.4.scala deleted file mode 100644 index c5fd2976c8b0..000000000000 --- a/tests/neg/i18867-3.4.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Werror - -import language.`3.4` - -def foo(x: Int) = x - -def test = foo _ // error diff --git a/tests/neg/i18867.scala b/tests/neg/i18867.scala deleted file mode 100644 index 722347a613f5..000000000000 --- a/tests/neg/i18867.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Werror - -def foo(x: Int) = x - -def test = foo _ // error diff --git a/tests/neg/i19320.scala b/tests/neg/i19320.scala new file mode 100644 index 000000000000..e802215a1f10 --- /dev/null +++ b/tests/neg/i19320.scala @@ -0,0 +1,15 @@ +//> using scala "3.3.1" +//> using dep org.http4s::http4s-ember-client:1.0.0-M40 +//> using dep org.http4s::http4s-ember-server:1.0.0-M40 +//> using dep org.http4s::http4s-dsl:1.0.0-M40 + +//import cats.effect.* +//import cats.implicits.* + +class Concurrent[F[_]] + +class Test[F[_]: Concurren]: // error + def hello = ??? + +object Test: + def apply[F[_]: Concurrent] = new Test[F] diff --git a/tests/neg/i19328.check b/tests/neg/i19328.check new file mode 100644 index 000000000000..357be5b2d530 --- /dev/null +++ b/tests/neg/i19328.check @@ -0,0 +1,4 @@ +-- [E172] Type Error: tests/neg/i19328.scala:14:5 ---------------------------------------------------------------------- +14 | bar // error: missing implicit (should not crash) + | ^ + | No given instance of type Boolean was found for parameter bool of method bar in object i19328 diff --git a/tests/neg/i19328.scala b/tests/neg/i19328.scala new file mode 100644 index 000000000000..246491e663bd --- /dev/null +++ b/tests/neg/i19328.scala @@ -0,0 +1,14 @@ +import scala.language.implicitConversions + +object i19328: + + trait Foo[B] + given foo[C]: Foo[C] = new Foo[C] {} + + type Id[A] = A + + implicit def wrapId[A](a: A): Id[A] = a + + def bar(using bool: Boolean): Unit = () + + bar // error: missing implicit (should not crash) diff --git a/tests/neg/i19328conversion.check b/tests/neg/i19328conversion.check new file mode 100644 index 000000000000..46d05211d43d --- /dev/null +++ b/tests/neg/i19328conversion.check @@ -0,0 +1,4 @@ +-- [E172] Type Error: tests/neg/i19328conversion.scala:13:5 ------------------------------------------------------------ +13 | bar // error: missing implicit (should not crash) + | ^ + | No given instance of type Boolean was found for parameter bool of method bar in object i19328conversion diff --git a/tests/neg/i19328conversion.scala b/tests/neg/i19328conversion.scala new file mode 100644 index 000000000000..46dd1058b579 --- /dev/null +++ b/tests/neg/i19328conversion.scala @@ -0,0 +1,13 @@ +object i19328conversion: + + trait Foo[B] + given foo[C]: Foo[C] = new Foo[C] {} + + type Id[A] = A + + given wrapId[A]: Conversion[A, Id[A]] with + def apply(x: A): Id[A] = x + + def bar(using bool: Boolean): Unit = () + + bar // error: missing implicit (should not crash) diff --git a/tests/neg/i19334.check b/tests/neg/i19334.check new file mode 100644 index 000000000000..8c0b6b3c299e --- /dev/null +++ b/tests/neg/i19334.check @@ -0,0 +1,12 @@ +-- [E081] Type Error: tests/neg/i19334.scala:6:4 ----------------------------------------------------------------------- +6 | f(_) // error was OOM formatting TypeVar(TypeParamRef(T)) when offering explanations + | ^ + | Missing parameter type + | + | I could not infer the type of the parameter _$1 + | in expanded function: + | _$1 => f(_$1) + | Expected type for the whole anonymous function: + | T + | + | where: T is a type variable diff --git a/tests/neg/i19334.scala b/tests/neg/i19334.scala new file mode 100644 index 000000000000..cd6af1872241 --- /dev/null +++ b/tests/neg/i19334.scala @@ -0,0 +1,6 @@ + +def foo[T](f: T): T = ??? + +@main def main = foo: + def f() = () + f(_) // error was OOM formatting TypeVar(TypeParamRef(T)) when offering explanations diff --git a/tests/neg/i19351.check b/tests/neg/i19351.check new file mode 100644 index 000000000000..a9ee10510b32 --- /dev/null +++ b/tests/neg/i19351.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/i19351/A.scala:3:35 -------------------------------------------------------------------------------- +3 | inline def myMacro(): x.type = ${myMacroExpr} // error + | ^ + |Cyclic macro dependency; macro refers to a toplevel symbol in tests/neg/i19351/A.scala from which the macro is called diff --git a/tests/neg/i19351/A.scala b/tests/neg/i19351/A.scala new file mode 100644 index 000000000000..f2258631a15a --- /dev/null +++ b/tests/neg/i19351/A.scala @@ -0,0 +1,5 @@ +//object A: + val x: Int = 1 + inline def myMacro(): x.type = ${myMacroExpr} // error + def test = myMacro() + diff --git a/tests/neg/i19351/B.scala b/tests/neg/i19351/B.scala new file mode 100644 index 000000000000..8c8c071f3607 --- /dev/null +++ b/tests/neg/i19351/B.scala @@ -0,0 +1,3 @@ +import scala.quoted.* +//import A.* +def myMacroExpr(using Quotes): Expr[x.type] = '{???} \ No newline at end of file diff --git a/tests/neg/i19351a.check b/tests/neg/i19351a.check new file mode 100644 index 000000000000..3c1353811f3d --- /dev/null +++ b/tests/neg/i19351a.check @@ -0,0 +1,12 @@ +-- Error: tests/neg/i19351a/Test.scala:8:34 ---------------------------------------------------------------------------- +8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error // error + | ^ + |Cyclic macro dependency; macro refers to a toplevel symbol in tests/neg/i19351a/Test.scala from which the macro is called +-- [E046] Cyclic Error: tests/neg/i19351a/Test.scala:8:46 -------------------------------------------------------------- +8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error // error + | ^ + | Cyclic reference involving method $anonfun + | + | Run with -explain-cyclic for more details. + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i19351a/Macro.scala b/tests/neg/i19351a/Macro.scala new file mode 100644 index 000000000000..8e691771d69a --- /dev/null +++ b/tests/neg/i19351a/Macro.scala @@ -0,0 +1,13 @@ +// Macro class +package test + +import scala.quoted.* + +def notMacro(bool: Expr[Bool])(using Quotes): Expr[Bool] = + '{$bool(False, True)} + +def showMacro(bool: Expr[Bool])(using Quotes): Expr[String] = + '{$bool("TRUE", "FALSE")} + +def foldMacro[T: Type](bool: Expr[Bool], t: Expr[T], f: Expr[T])(using Quotes): Expr[T] = + '{$bool($t, $f)} \ No newline at end of file diff --git a/tests/neg/i19351a/Test.scala b/tests/neg/i19351a/Test.scala new file mode 100644 index 000000000000..51f608aa46ea --- /dev/null +++ b/tests/neg/i19351a/Test.scala @@ -0,0 +1,15 @@ +//Test class +package test + +type Bool = [R] => (R, R) => R +val True: Bool = [R] => (t: R, _: R) => t +val False: Bool = [R] => (_: R, f: R) => f + +inline def not(b: Bool): Bool = ${notMacro('b)} // error // error +inline def show(b: Bool): String = ${showMacro('b)} +//inline def not(b: Bool): Bool = ${foldMacro('b, 'False, 'True)} +//inline def show(b: Bool): String = ${foldMacro('b, '{"TRUE"}, '{"FALSE"})} + + +@main def testing = + println(show(not(True))) \ No newline at end of file diff --git a/tests/neg/i19364.scala b/tests/neg/i19364.scala new file mode 100644 index 000000000000..ae193e591c2e --- /dev/null +++ b/tests/neg/i19364.scala @@ -0,0 +1,14 @@ + +def f(using ?): Unit = {} // error: unbound wildcard type +class C(using ?) {} // error: unbound wildcard type + +def f2(using => ?): Unit = {} // error: unbound wildcard type +class C2(using => ?) {} // error: unbound wildcard type + +def f3(using ? *): Unit = {} // error: unbound wildcard type // error +class C3(using ? *) {} // error: unbound wildcard type // error + +def g(using x: ?): Unit = {} // error: unbound wildcard type +class D(using x: ?) {} // error: unbound wildcard type + +val h: (?) ?=> Unit = ??? // ok, but useless (it's a function from Nothing) diff --git a/tests/neg/i19372.check b/tests/neg/i19372.check new file mode 100644 index 000000000000..94522a5be329 --- /dev/null +++ b/tests/neg/i19372.check @@ -0,0 +1,50 @@ +-- [E140] Cyclic Error: tests/neg/i19372.scala:3:7 --------------------------------------------------------------------- +3 | type AAA = List[bar.BBB] // error: cyclic + | ^ + | illegal cyclic type reference: alias List[Test1.bar.BBB] of type AAA refers back to the type itself + | + | The error occurred while trying to compute the signature of type AAA + | which required to explore type BBB for cyclic references + | which required to explore type AAA for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i19372.scala:9:7 --------------------------------------------------------------------- +9 | type A = bar.B // error: cyclic + | ^ + | illegal cyclic type reference: alias Test2.bar.B of type A refers back to the type itself + | + | The error occurred while trying to compute the signature of type A + | which required to explore type B for cyclic references + | which required to explore type A for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i19372.scala:15:7 -------------------------------------------------------------------- +15 | type AAA = List[bar.BBB] // error: cyclic + | ^ + | illegal cyclic type reference: alias List[Test3.bar.BBB] of type AAA refers back to the type itself + | + | The error occurred while trying to compute the signature of type AAA + | which required to explore type BBB for cyclic references + | which required to explore type AAA for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i19372.scala:21:7 -------------------------------------------------------------------- +21 | type A = bar.B // error: cyclic + | ^ + | illegal cyclic type reference: alias Test4.bar.B of type A refers back to the type itself + | + | The error occurred while trying to compute the signature of type A + | which required to explore type B for cyclic references + | which required to explore type A for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. +-- [E140] Cyclic Error: tests/neg/i19372.scala:30:7 -------------------------------------------------------------------- +30 | type UCharIteratorReserved = Ptr[UCharIterator] // error: cyclic + | ^ + |illegal cyclic type reference: alias Ptr[structs.UCharIterator] of type UCharIteratorReserved refers back to the type itself + | + |The error occurred while trying to compute the signature of type UCharIteratorReserved + | which required to explore type UCharIterator for cyclic references + | which required to explore type UCharIteratorReserved for cyclic references + | + | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace. diff --git a/tests/neg/i19372.scala b/tests/neg/i19372.scala new file mode 100644 index 000000000000..84f460e373f2 --- /dev/null +++ b/tests/neg/i19372.scala @@ -0,0 +1,38 @@ +//> using options -explain-cyclic +object Test1: + type AAA = List[bar.BBB] // error: cyclic + def foo: AAA = ??? + object bar: + opaque type BBB = AAA + +object Test2: + type A = bar.B // error: cyclic + def foo: A = ??? + object bar: + opaque type B = A + +object Test3: + type AAA = List[bar.BBB] // error: cyclic + def foo: AAA = ??? + object bar: + type BBB = AAA + +object Test4: + type A = bar.B // error: cyclic + def foo: A = ??? + object bar: + type B = A + +trait Ptr[T] + +object aliases: + import structs.* + type UCharIteratorReserved = Ptr[UCharIterator] // error: cyclic + object UCharIteratorReserved: + def iterator: UCharIterator = ??? + +object structs: + import aliases.{*, given} + opaque type UCharIterator = Ptr[UCharIteratorReserved] + object UCharIterator: + def reservedFn: UCharIteratorReserved = ??? \ No newline at end of file diff --git a/tests/neg/i19445.check b/tests/neg/i19445.check new file mode 100644 index 000000000000..221b9c3d90b8 --- /dev/null +++ b/tests/neg/i19445.check @@ -0,0 +1,36 @@ +-- [E007] Type Mismatch Error: tests/neg/i19445.scala:17:15 ------------------------------------------------------------ +17 | val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: Test.UnwrapTypes[FooBar.Bar[Int]] + | Required: Int + | + | Note: a match type could not be fully reduced: + | + | trying to reduce Test.UnwrapTypes[FooBar.Bar[Int]] + | failed since selector FooBar.Bar[Int] + | does not match case BarFoo.Bar[x] => Test.UnwrapTypes[x] + | and cannot be shown to be disjoint from it either. + | Therefore, reduction cannot advance to the remaining cases + | + | case String => String + | case Int => Int + | + | longer explanation available when compiling with `-explain` +-- [E007] Type Mismatch Error: tests/neg/i19445.scala:18:28 ------------------------------------------------------------ +18 | val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: (Test.UnwrapTypes[FooBar.Bar[Int]], Test.UnwrapTypes[FooBar.Bar[String]]) + | Required: (Int, String) + | + | Note: a match type could not be fully reduced: + | + | trying to reduce Test.UnwrapTypes[FooBar.Bar[Int]] + | failed since selector FooBar.Bar[Int] + | does not match case BarFoo.Bar[x] => Test.UnwrapTypes[x] + | and cannot be shown to be disjoint from it either. + | Therefore, reduction cannot advance to the remaining cases + | + | case String => String + | case Int => Int + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i19445.scala b/tests/neg/i19445.scala new file mode 100644 index 000000000000..e47e43372dfd --- /dev/null +++ b/tests/neg/i19445.scala @@ -0,0 +1,19 @@ +trait Foo: + case class Bar[A](value: A) + +object FooBar extends Foo + +object BarFoo extends Foo + +object Test: + type UnwrapTypes[Xs] = + Xs match + case EmptyTuple => Xs + case x *: xs => UnwrapTypes[x] *: UnwrapTypes[xs] + case BarFoo.Bar[x] => UnwrapTypes[x] + case String => String + case Int => Int + + val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] // error + val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] // error +end Test diff --git a/tests/neg/i19470.check b/tests/neg/i19470.check new file mode 100644 index 000000000000..fdb336bef7e5 --- /dev/null +++ b/tests/neg/i19470.check @@ -0,0 +1,7 @@ +-- [E007] Type Mismatch Error: tests/neg/i19470.scala:9:12 ------------------------------------------------------------- +9 | List(foo(f())) // error + | ^^^^^^^^ + | Found: Inv[box IO^{f?}] + | Required: box Inv[box IO^?]^? + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i19470.scala b/tests/neg/i19470.scala new file mode 100644 index 000000000000..9659f4654042 --- /dev/null +++ b/tests/neg/i19470.scala @@ -0,0 +1,9 @@ +import language.experimental.captureChecking +trait IO +case class Inv[X](x: X) + +def foo(x: IO^): Inv[IO^{x}] = Inv(x) + +def main(io: IO^): Unit = + def test(f: () => IO^) = + List(foo(f())) // error diff --git a/tests/neg/i19506.scala b/tests/neg/i19506.scala index 4e139fed07d0..1b877a0bae7d 100644 --- a/tests/neg/i19506.scala +++ b/tests/neg/i19506.scala @@ -1,4 +1,4 @@ -//> using options "-source 3.4-migration", +//> using options -source 3.4-migration trait Reader[T] def read[T: Reader](s: String, trace: Boolean = false): T = ??? diff --git a/tests/neg/i2333.scala b/tests/neg/i2333.scala deleted file mode 100644 index 67cddbc73f48..000000000000 --- a/tests/neg/i2333.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -@deprecated("bla", "2.11.0") class Foo { - println("") - def this(x: Int) = this() -} - -object Test { - new Foo // error: deprecated - new Foo(1) // error: deprecated -} \ No newline at end of file diff --git a/tests/neg/i2673.scala b/tests/neg/i2673.scala deleted file mode 100644 index 62c787fa00fb..000000000000 --- a/tests/neg/i2673.scala +++ /dev/null @@ -1,6 +0,0 @@ -//> using options -Xfatal-warnings - -package Foos - -class Foo // error -class foo diff --git a/tests/neg/i2673b.scala b/tests/neg/i2673b.scala deleted file mode 100644 index 26e09ec3297e..000000000000 --- a/tests/neg/i2673b.scala +++ /dev/null @@ -1,6 +0,0 @@ -//> using options -Xfatal-warnings - -package Foos - -class Bar // error -object bar diff --git a/tests/neg/i2673c.scala b/tests/neg/i2673c.scala deleted file mode 100644 index 575d8c25d9e0..000000000000 --- a/tests/neg/i2673c.scala +++ /dev/null @@ -1,8 +0,0 @@ -//> using options -Xfatal-warnings - -package Foos - -object Outer { - case class X() // error - object x -} diff --git a/tests/neg/i4060.scala b/tests/neg/i4060.scala index ba641d633d3c..bd16ed867966 100644 --- a/tests/neg/i4060.scala +++ b/tests/neg/i4060.scala @@ -1,6 +1,6 @@ //> using options -language:experimental.erasedDefinitions -// See https://github.com/lampepfl/dotty/issues/4060#issuecomment-445808377 +// See https://github.com/scala/scala3/issues/4060#issuecomment-445808377 object App { trait A { type L >: Any} diff --git a/tests/neg/i4812.check b/tests/neg/i4812.check deleted file mode 100644 index f4aee0e35dde..000000000000 --- a/tests/neg/i4812.check +++ /dev/null @@ -1,42 +0,0 @@ --- [E092] Pattern Match Error: tests/neg/i4812.scala:8:11 -------------------------------------------------------------- -8 | case prev: A => // error: the type test for A cannot be checked at runtime - | ^ - | the type test for A cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i4812.scala:18:11 ------------------------------------------------------------- -18 | case prev: A => // error: the type test for A cannot be checked at runtime - | ^ - | the type test for A cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i4812.scala:28:11 ------------------------------------------------------------- -28 | case prev: A => // error: the type test for A cannot be checked at runtime - | ^ - | the type test for A cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i4812.scala:38:11 ------------------------------------------------------------- -38 | case prev: A => // error: the type test for A cannot be checked at runtime - | ^ - | the type test for A cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i4812.scala:50:13 ------------------------------------------------------------- -50 | case prev: A => // error: the type test for A cannot be checked at runtime - | ^ - | the type test for A cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i4812.scala:60:11 ------------------------------------------------------------- -60 | case prev: A => // error: the type test for A cannot be checked at runtime - | ^ - | the type test for A cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i4812.scala:96:11 ------------------------------------------------------------- -96 | case x: B => // error: the type test for B cannot be checked at runtime - | ^ - | the type test for B cannot be checked at runtime because it's a local class - | - | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i4936b.scala b/tests/neg/i4936b.scala deleted file mode 100644 index 58c240e92309..000000000000 --- a/tests/neg/i4936b.scala +++ /dev/null @@ -1,3 +0,0 @@ -//> using options -Xfatal-warnings - -final object Foo // error diff --git a/tests/neg/i4986d.scala b/tests/neg/i4986d.scala index 909221bea5f0..0def343fe847 100644 --- a/tests/neg/i4986d.scala +++ b/tests/neg/i4986d.scala @@ -3,10 +3,10 @@ trait Foo[A] type Fooable[A] = { - def foo(implicit @annotation.implicitNotFound("There's no Foo[${A}]") ev: Foo[A]): Any // error + def foo(implicit @annotation.implicitNotFound("There's no Foo[${A}]") ev: Foo[A]): Any // warn type InnerFooable = { - def foo(implicit @annotation.implicitNotFound("There's no Foo[${A}]") ev: Foo[A]): Any // error + def foo(implicit @annotation.implicitNotFound("There's no Foo[${A}]") ev: Foo[A]): Any // warn } } @@ -22,3 +22,4 @@ trait Bar[A] type Barable[A] = { def bar(implicit ev: Bar[A]): Any // ok } +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i5013.scala b/tests/neg/i5013.scala deleted file mode 100644 index adf09e2cf3be..000000000000 --- a/tests/neg/i5013.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -class Foo { - - def foo1: Unit = 2 // error: A pure expression does nothing in statement position - - def foo2: Unit = { - 3 // error: A pure expression does nothing in statement position - 4 // error: A pure expression does nothing in statement position - } -} diff --git a/tests/neg/i6190b.scala b/tests/neg/i6190b.scala deleted file mode 100644 index 42270c1a984c..000000000000 --- a/tests/neg/i6190b.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -case class Rule(name: String) - -def foo = List("1", "2").map(Rule) // error diff --git a/tests/neg/i6716.check b/tests/neg/i6716.check index cdf655710452..4684842e73fe 100644 --- a/tests/neg/i6716.check +++ b/tests/neg/i6716.check @@ -1,5 +1,5 @@ --- Error: tests/neg/i6716.scala:12:39 ---------------------------------------------------------------------------------- -12 | given Monad[Bar] = summon[Monad[Foo]] // error +-- Warning: tests/neg/i6716.scala:12:39 -------------------------------------------------------------------------------- +12 | given Monad[Bar] = summon[Monad[Foo]] // warn | ^ | Result of implicit search for Monad[Foo] will change. | Current result Bar.given_Monad_Bar will be no longer eligible @@ -13,3 +13,4 @@ | - rearrange definitions so that Bar.given_Monad_Bar comes earlier, | - use an explicit argument. | This will be an error in Scala 3.5 and later. +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i6716.scala b/tests/neg/i6716.scala index bbbd9d6d6cd0..311209fd9006 100644 --- a/tests/neg/i6716.scala +++ b/tests/neg/i6716.scala @@ -9,10 +9,11 @@ object Foo { opaque type Bar = Foo object Bar { - given Monad[Bar] = summon[Monad[Foo]] // error + given Monad[Bar] = summon[Monad[Foo]] // warn } object Test extends App { println(summon[Monad[Foo]].id) println(summon[Monad[Bar]].id) -} \ No newline at end of file +} +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i7294-a.check b/tests/neg/i7294-a.check index 2fe260fcf99a..c33735258ad0 100644 --- a/tests/neg/i7294-a.check +++ b/tests/neg/i7294-a.check @@ -1,5 +1,5 @@ -- [E007] Type Mismatch Error: tests/neg/i7294-a.scala:10:20 ----------------------------------------------------------- -10 | case x: T => x.g(10) // error // error +10 | case x: T => x.g(10) // error | ^^^^^^^ | Found: Any | Required: T @@ -7,8 +7,8 @@ | where: T is a type in given instance f with bounds <: foo.Foo | | longer explanation available when compiling with `-explain` --- Error: tests/neg/i7294-a.scala:10:12 -------------------------------------------------------------------------------- -10 | case x: T => x.g(10) // error // error +-- Warning: tests/neg/i7294-a.scala:10:12 ------------------------------------------------------------------------------ +10 | case x: T => x.g(10) // error | ^ | Result of implicit search for scala.reflect.TypeTest[Nothing, T] will change. | Current result foo.Test.f will be no longer eligible @@ -24,3 +24,4 @@ | This will be an error in Scala 3.5 and later. | | where: T is a type in given instance f with bounds <: foo.Foo +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i7294-a.scala b/tests/neg/i7294-a.scala index 3453e88cf741..a5193097e941 100644 --- a/tests/neg/i7294-a.scala +++ b/tests/neg/i7294-a.scala @@ -7,7 +7,8 @@ trait Foo { def g(x: Int): Any } object Test: inline given f[T <: Foo]: T = ??? match { - case x: T => x.g(10) // error // error + case x: T => x.g(10) // error } @main def Test = f +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i7294-b.scala b/tests/neg/i7294-b.scala index 8c6f9328cc20..ba12239af039 100644 --- a/tests/neg/i7294-b.scala +++ b/tests/neg/i7294-b.scala @@ -9,3 +9,4 @@ inline given f[T <: Foo]: T = ??? match { } @main def Test = f +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i7821b.scala b/tests/neg/i7821b.scala deleted file mode 100644 index f82a38d259e1..000000000000 --- a/tests/neg/i7821b.scala +++ /dev/null @@ -1,13 +0,0 @@ -//> using options -Xfatal-warnings - -object Test { - - { def f(x: Int, y: Int): Int = f(x, y) } // error - { def f(x: Int, y: Int): Int = { f(x, y) } } // error - { def f(x: Int, y: Int): Int = f(y, x) } // error - { def f(x: Int, y: Int): Int = f(x, x) } // error - { def f(x: Int, y: Int): Int = f(1, 1) } // error - { def f(x: Int, y: Int): Int = { val a = 3; f(a, 1) } } // error - { def f(x: Int): Int = f(1) } // error - -} diff --git a/tests/neg/i8681.scala b/tests/neg/i8681.scala index 4d91509eb0d3..637dd123bd48 100644 --- a/tests/neg/i8681.scala +++ b/tests/neg/i8681.scala @@ -13,4 +13,5 @@ val b = (A(1): A | B) match { case A(_) => "OK" case B(_) => "OK" case C(_) => "NOT OK" // error -} \ No newline at end of file +} +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i8711.check b/tests/neg/i8711.check index 5dbeeb22460c..245092a6dfd0 100644 --- a/tests/neg/i8711.check +++ b/tests/neg/i8711.check @@ -1,12 +1,21 @@ --- [E030] Match case Unreachable Error: tests/neg/i8711.scala:9:9 ------------------------------------------------------ +-- [E030] Match case Unreachable Warning: tests/neg/i8711.scala:9:9 ---------------------------------------------------- 9 | case x: B => x // error: this case is unreachable since class A is not a subclass of class B | ^^^^ | Unreachable case --- [E030] Match case Unreachable Error: tests/neg/i8711.scala:14:9 ----------------------------------------------------- +-- [E030] Match case Unreachable Warning: tests/neg/i8711.scala:14:9 --------------------------------------------------- 14 | case x: C => x // error | ^^^^ | Unreachable case --- [E030] Match case Unreachable Error: tests/neg/i8711.scala:19:9 ----------------------------------------------------- -19 | case x: (B | C) => x // error +-- [E030] Match case Unreachable Warning: tests/neg/i8711.scala:19:9 --------------------------------------------------- +19 | case x: (B | C) => x // warn | ^^^^^^^^^^ | Unreachable case +-- Error: tests/neg/i8711.scala:9:9 ------------------------------------------------------------------------------------ +9 | case x: B => x // error: this case is unreachable since class A is not a subclass of class B + | ^ + | this case is unreachable since type A and class B are unrelated +-- Error: tests/neg/i8711.scala:14:9 ----------------------------------------------------------------------------------- +14 | case x: C => x // error + | ^ + | this case is unreachable since type A | B and class C are unrelated +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i8711.scala b/tests/neg/i8711.scala index 2647e20fe03b..18f53447d024 100644 --- a/tests/neg/i8711.scala +++ b/tests/neg/i8711.scala @@ -16,7 +16,9 @@ object Test { } def baz(x: A) = x match { - case x: (B | C) => x // error + case x: (B | C) => x // warn case _ => } } + +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i8781b.scala b/tests/neg/i8781b.scala deleted file mode 100644 index 7c9b074e1be7..000000000000 --- a/tests/neg/i8781b.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Xfatal-warnings - -object Test: - - println((3: Boolean | Int).isInstanceOf[Boolean]) - - println(3.isInstanceOf[Boolean]) // error diff --git a/tests/neg/i8984.scala b/tests/neg/i8984.scala deleted file mode 100644 index ff798d803ba3..000000000000 --- a/tests/neg/i8984.scala +++ /dev/null @@ -1,61 +0,0 @@ -import scala.annotation.tailrec -type |@[F[+_], G[+_]] = [a] =>> F[a] | G[a] - -object Fix: - opaque type T[+F[+_]] = ApplyFix.T[F] - - def apply[F[+_]](f: F[Fix[F]]): T[F] = ApplyFix(f) - - extension [F[+_]](fix: T[F]) - def value: F[Fix[F]] = ApplyFix.unwrap(fix) - - object ApplyFix: - opaque type T[+F[+_]] = F[Fix[F]] - - def apply[F[+_]](f: F[Fix[F]]): T[F] = f - - def unwrap[F[+_]](v: T[F]): F[Fix[F]] = v - -type Fix[+F[+_]] = Fix.T[F] - -final case class Cat[+R](name: String, fur: String, rest: R) -object Cat: - def of[R, F[+_]](name: String, fur: String, rest: Fix[F]): Fix[F |@ Cat] = Fix(new Cat(name, fur, rest)) - -final case class Dog[+R](name: String, size: Long, rest: R) -object Dog: - def of[R, F[+_]](name: String, size: Long, rest: Fix[F]): Fix[F |@ Dog] = Fix(new Dog(name, size, rest)) - -case object End: - type f[+a] = End.type - def apply() = Fix[f](End) - -object DropRed: - @tailrec def dropRedCats[F[+a] >: Cat[a]](cats: Fix[F]): Fix[F] = - cats.value match - case Cat(_, "red", rest) => dropRedCats(rest) // error - case _ => cats - - type CatDogVector = Vector[Either[Cat[Unit], Dog[Unit]]] - type CatOrDogs[+a] = Cat[a] | Dog[a] | End.type - - extension (catDogs: Fix[CatOrDogs]) def toVector : CatDogVector = - @tailrec def go(acc: CatDogVector, catDogs: Fix[CatOrDogs]) : CatDogVector = catDogs.value match - case Cat(name, fur, rest) => go(acc :+ Left(Cat(name, fur, ())), rest) - case Dog(name, size, rest) => go(acc :+ Right(Dog(name, size, ())), rest) - case End => acc - - go(Vector(), catDogs) - - val x = - Cat.of("lilly" , "red" , - Cat.of("anya" , "red" , - Cat.of("boris" , "black", - Dog.of("mashka", 3 , - Cat.of("manya" , "red" , - End()))))) - - - def main(args: Array[String]) = - println(x.toVector) - println(dropRedCats(x).toVector) diff --git a/tests/neg/i9166.scala b/tests/neg/i9166.scala deleted file mode 100644 index b9644bf56f71..000000000000 --- a/tests/neg/i9166.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns -object UnitTest extends App { - def foo(m: Unit) = m match { - case runtime.BoxedUnit.UNIT => println("ok") // error - } - foo(()) -} diff --git a/tests/neg/i9266.scala b/tests/neg/i9266.scala deleted file mode 100644 index e6f8db7417c7..000000000000 --- a/tests/neg/i9266.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -import language.`future-migration` - -def test = { implicit x: Int => x + x } // error diff --git a/tests/neg/i9408b.check b/tests/neg/i9408b.check index 5f8a854a9282..15af4294c9bb 100644 --- a/tests/neg/i9408b.check +++ b/tests/neg/i9408b.check @@ -1,5 +1,6 @@ --- Error: tests/neg/i9408b/Test_2.scala:8:20 --------------------------------------------------------------------------- -8 | val length: Int = "abc" // error +-- Migration Warning: tests/neg/i9408b/Test_2.scala:8:20 --------------------------------------------------------------- +8 | val length: Int = "abc" // warn | ^^^^^ |The conversion (test.conversions.Conv.implicitLength : String => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/i9408b/Test_2.scala b/tests/neg/i9408b/Test_2.scala index 6b3cbbafcb0e..dc5c2bd7b30d 100644 --- a/tests/neg/i9408b/Test_2.scala +++ b/tests/neg/i9408b/Test_2.scala @@ -5,5 +5,7 @@ import scala.language.implicitConversions object Test { import test.conversions.Conv.* - val length: Int = "abc" // error + val length: Int = "abc" // warn } + +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/i9751.scala b/tests/neg/i9751.scala deleted file mode 100644 index 618d237e0cd4..000000000000 --- a/tests/neg/i9751.scala +++ /dev/null @@ -1,11 +0,0 @@ -//> using options -Xfatal-warnings - -def f(): Unit = { - () // error - () -} - -inline def g(): Unit = { - () // error - () -} diff --git a/tests/neg/impl-conv/A.scala b/tests/neg/impl-conv/A.scala index 31eccf4fa4f7..9c47e67ca789 100644 --- a/tests/neg/impl-conv/A.scala +++ b/tests/neg/impl-conv/A.scala @@ -2,7 +2,7 @@ package implConv object A { - implicit def s2i(x: String): Int = Integer.parseInt(x) // error: feature + implicit def s2i(x: String): Int = Integer.parseInt(x) // warn: feature given i2s: Conversion[Int, String] = _.toString // ok implicit class Foo(x: String) { diff --git a/tests/neg/impl-conv/B.scala b/tests/neg/impl-conv/B.scala index 618868b8bbc0..7ba9fbb92459 100644 --- a/tests/neg/impl-conv/B.scala +++ b/tests/neg/impl-conv/B.scala @@ -8,5 +8,6 @@ object B { "".foo val x: Int = "" // ok - val y: String = 1 // error: feature + val y: String = 1 // warn: feature } +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/implicit-conversions-old.scala b/tests/neg/implicit-conversions-old.scala deleted file mode 100644 index 0a7b75766bbf..000000000000 --- a/tests/neg/implicit-conversions-old.scala +++ /dev/null @@ -1,25 +0,0 @@ -//> using options -Xfatal-warnings -feature - -class A -class B - -object A { - - implicit def a2b(x: A): B = ??? // error under -Xfatal-warnings -feature - - implicit def b2a(x: B): A = ??? // error under -Xfatal-warnings -feature -} - -class C - -object D { - implicit def a2c(x: A): C = ??? // error under -Xfatal-warnings -feature -} - -object Test { - import D.* - - val x1: A = new B - val x2: B = new A // ok, since it's an old-style comversion - val x3: C = new A // ok, since it's an old-style comversion -} \ No newline at end of file diff --git a/tests/neg/indentLeft.scala b/tests/neg/indentLeft.scala index c4a260583de2..22386bd54561 100644 --- a/tests/neg/indentLeft.scala +++ b/tests/neg/indentLeft.scala @@ -1,10 +1,11 @@ //> using options -Xfatal-warnings +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) object Test { if (true) { println("hi") - println("!") // error: too far to the left + println("!") // warn: too far to the left } // error: too far to the left \ No newline at end of file diff --git a/tests/neg/indentRight.scala b/tests/neg/indentRight.scala index 8eb9deb23389..e3359bf238dd 100644 --- a/tests/neg/indentRight.scala +++ b/tests/neg/indentRight.scala @@ -1,19 +1,19 @@ //> using options -no-indent -Xfatal-warnings trait A - case class B() extends A // error: Line is indented too far to the right - case object C extends A // error: Line is indented too far to the right + case class B() extends A // warn: Line is indented too far to the right + case object C extends A // warn: Line is indented too far to the right object Test { if (true) println("ho") - println("hu") // error: Line is indented too far to the right + println("hu") // warn: Line is indented too far to the right if (true) { println("ho") } - println("hu") // error: Line is indented too far to the right + println("hu") // warn: Line is indented too far to the right while (true) () @@ -24,8 +24,8 @@ object Test { } trait A - case class B() extends A // error: Line is indented too far to the right - case object C extends A // error: Line is indented too far to the right + case class B() extends A // warn: Line is indented too far to the right + case object C extends A // warn: Line is indented too far to the right if (true) // OK println("hi") @@ -33,4 +33,4 @@ object Test { println("!") // error: expected a toplevel definition } - +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/infix.check b/tests/neg/infix.check new file mode 100644 index 000000000000..ddf6e22bff45 --- /dev/null +++ b/tests/neg/infix.check @@ -0,0 +1,30 @@ +-- Error: tests/neg/infix.scala:26:4 ----------------------------------------------------------------------------------- +26 | c mop 2 // error: should not be used as infix operator + | ^^^ + | Alphanumeric method mop is not declared infix; it should not be used as infix operator. + | Instead, use method syntax .mop(...) or backticked identifier `mop`. + | The latter can be rewritten automatically under -rewrite -source 3.4-migration. +-- Error: tests/neg/infix.scala:27:4 ----------------------------------------------------------------------------------- +27 | c meth 2 // error: should not be used as infix operator + | ^^^^ + | Alphanumeric method meth is not declared infix; it should not be used as infix operator. + | Instead, use method syntax .meth(...) or backticked identifier `meth`. + | The latter can be rewritten automatically under -rewrite -source 3.4-migration. +-- Error: tests/neg/infix.scala:45:14 ---------------------------------------------------------------------------------- +45 | val x1: Int Map String = ??? // error + | ^^^ + | Alphanumeric type Map is not declared infix; it should not be used as infix operator. + | Instead, use prefix syntax Map[...] or backticked identifier `Map`. + | The latter can be rewritten automatically under -rewrite -source 3.4-migration. +-- Error: tests/neg/infix.scala:47:14 ---------------------------------------------------------------------------------- +47 | val x3: Int AndC String = ??? // error + | ^^^^ + | Alphanumeric type AndC is not declared infix; it should not be used as infix operator. + | Instead, use prefix syntax AndC[...] or backticked identifier `AndC`. + | The latter can be rewritten automatically under -rewrite -source 3.4-migration. +-- Error: tests/neg/infix.scala:61:8 ----------------------------------------------------------------------------------- +61 | val _ Pair _ = p // error + | ^^^^ + | Alphanumeric extractor Pair is not declared infix; it should not be used as infix operator. + | Instead, use prefix syntax Pair(...) or backticked identifier `Pair`. + | The latter can be rewritten automatically under -rewrite -source 3.4-migration. diff --git a/tests/neg/infix.scala b/tests/neg/infix.scala index aefdd5c40d47..dda638c829f9 100644 --- a/tests/neg/infix.scala +++ b/tests/neg/infix.scala @@ -1,4 +1,4 @@ -//> using options -source future -deprecation -Xfatal-warnings +//> using options -source future -deprecation // Compile with -strict -Xfatal-warnings -deprecation class C: @@ -67,4 +67,4 @@ def test() = { val _ Q _ = q // OK -} +} \ No newline at end of file diff --git a/tests/neg/inline-unstable-accessors.check b/tests/neg/inline-unstable-accessors.check index eb226afc376b..c1984e4cc533 100644 --- a/tests/neg/inline-unstable-accessors.check +++ b/tests/neg/inline-unstable-accessors.check @@ -1,5 +1,5 @@ --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:10:6 ------------------------------------------ -10 | valBinaryAPI1 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:10:6 ---------------------------------------- +10 | valBinaryAPI1 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor foo$A$$inline$valBinaryAPI1 was generated in class A. |-------------------------------------------------------------------------------------------------------------------- @@ -21,8 +21,8 @@ | added to class A: | @publicInBinary private[A] final def foo$A$$inline$valBinaryAPI1: Int = this.valBinaryAPI1 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:11:6 ------------------------------------------ -11 | valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:11:6 ---------------------------------------- +11 | valBinaryAPI2 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor foo$A$$inline$valBinaryAPI2 was generated in class A. |-------------------------------------------------------------------------------------------------------------------- @@ -44,8 +44,8 @@ | added to class A: | @publicInBinary private[A] def foo$A$$inline$valBinaryAPI2: Int = this.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:15:6 ------------------------------------------ -15 | a.valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:15:6 ---------------------------------------- +15 | a.valBinaryAPI2 + // warn | ^^^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2$i1 was generated in class B. |-------------------------------------------------------------------------------------------------------------------- @@ -67,8 +67,8 @@ | added to class B: | @publicInBinary private[B] def inline$valBinaryAPI2$i1(x$0: foo.A): Int = x$0.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:23:6 ------------------------------------------ -23 | valBinaryAPI1 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:23:6 ---------------------------------------- +23 | valBinaryAPI1 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI1 was generated in class C. |-------------------------------------------------------------------------------------------------------------------- @@ -90,8 +90,8 @@ | added to class C: | @publicInBinary private[C] final def inline$valBinaryAPI1: Int = this.valBinaryAPI1 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:24:6 ------------------------------------------ -24 | valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:24:6 ---------------------------------------- +24 | valBinaryAPI2 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2 was generated in class C. |-------------------------------------------------------------------------------------------------------------------- @@ -113,8 +113,8 @@ | added to class C: | @publicInBinary private[C] def inline$valBinaryAPI2: Int = this.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:28:6 ------------------------------------------ -28 | c.valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:28:6 ---------------------------------------- +28 | c.valBinaryAPI2 + // warn | ^^^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2$i2 was generated in class D. |-------------------------------------------------------------------------------------------------------------------- @@ -136,8 +136,8 @@ | added to class D: | @publicInBinary private[D] def inline$valBinaryAPI2$i2(x$0: foo.C): Int = x$0.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:36:6 ------------------------------------------ -36 | valBinaryAPI1 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:36:6 ---------------------------------------- +36 | valBinaryAPI1 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI1 was generated in object E. |-------------------------------------------------------------------------------------------------------------------- @@ -159,8 +159,8 @@ | added to object E: | @publicInBinary private[E] final def inline$valBinaryAPI1: Int = foo.E.valBinaryAPI1 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:37:6 ------------------------------------------ -37 | valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:37:6 ---------------------------------------- +37 | valBinaryAPI2 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2 was generated in object E. |-------------------------------------------------------------------------------------------------------------------- @@ -182,8 +182,8 @@ | added to object E: | @publicInBinary private[E] def inline$valBinaryAPI2: Int = foo.E.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:41:6 ------------------------------------------ -41 | E.valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:41:6 ---------------------------------------- +41 | E.valBinaryAPI2 + // warn | ^^^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2$i3 was generated in object F. |-------------------------------------------------------------------------------------------------------------------- @@ -205,8 +205,8 @@ | added to object F: | @publicInBinary private[F] def inline$valBinaryAPI2$i3(x$0: object foo.E): Int = x$0.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:49:6 ------------------------------------------ -49 | valBinaryAPI1 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:49:6 ---------------------------------------- +49 | valBinaryAPI1 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI1 was generated in package G. |-------------------------------------------------------------------------------------------------------------------- @@ -228,8 +228,8 @@ | added to package G: | @publicInBinary private[G] def inline$valBinaryAPI1: Int = foo.G.valBinaryAPI1 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:50:6 ------------------------------------------ -50 | valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:50:6 ---------------------------------------- +50 | valBinaryAPI2 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2 was generated in package G. |-------------------------------------------------------------------------------------------------------------------- @@ -251,31 +251,8 @@ | added to package G: | @publicInBinary private[G] def inline$valBinaryAPI2: Int = foo.G.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:54:6 ------------------------------------------ -54 | G.valBinaryAPI2 + // error - | ^^^^^^^^^^^^^^^ - | Unstable inline accessor inline$valBinaryAPI2$i4 was generated in package H. - |-------------------------------------------------------------------------------------------------------------------- - | Explanation (enabled by `-explain`) - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Access to non-public value valBinaryAPI2 causes the automatic generation of an accessor. - | This accessor is not stable, its name may change or it may disappear - | if not needed in a future version. - | - | To make sure that the inlined code is binary compatible you must make sure that - | value valBinaryAPI2 is public in the binary API. - | * Option 1: Annotate value valBinaryAPI2 with @publicInBinary - | * Option 2: Make value valBinaryAPI2 public - | - | This change may break binary compatibility if a previous version of this - | library was compiled with generated accessors. Binary compatibility should - | be checked using MiMa. If binary compatibility is broken, you should add the - | old accessor explicitly in the source code. The following code should be - | added to package H: - | @publicInBinary private[H] def inline$valBinaryAPI2$i4(x$0: foo.G): Int = x$0.valBinaryAPI2 - -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:62:6 ------------------------------------------ -62 | valBinaryAPI1 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:62:6 ---------------------------------------- +62 | valBinaryAPI1 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI1 was generated in package I. |-------------------------------------------------------------------------------------------------------------------- @@ -297,8 +274,8 @@ | added to package I: | @publicInBinary private[I] def inline$valBinaryAPI1: Int = foo.I.valBinaryAPI1 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:63:6 ------------------------------------------ -63 | valBinaryAPI2 + // error +-- [E192] Compatibility Warning: tests/neg/inline-unstable-accessors.scala:63:6 ---------------------------------------- +63 | valBinaryAPI2 + // warn | ^^^^^^^^^^^^^ | Unstable inline accessor inline$valBinaryAPI2 was generated in package I. |-------------------------------------------------------------------------------------------------------------------- @@ -320,26 +297,4 @@ | added to package I: | @publicInBinary private[I] def inline$valBinaryAPI2: Int = foo.I.valBinaryAPI2 -------------------------------------------------------------------------------------------------------------------- --- [E192] Compatibility Error: tests/neg/inline-unstable-accessors.scala:67:6 ------------------------------------------ -67 | I.valBinaryAPI2 + // error - | ^^^^^^^^^^^^^^^ - | Unstable inline accessor inline$valBinaryAPI2$i5 was generated in package J. - |-------------------------------------------------------------------------------------------------------------------- - | Explanation (enabled by `-explain`) - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Access to non-public value valBinaryAPI2 causes the automatic generation of an accessor. - | This accessor is not stable, its name may change or it may disappear - | if not needed in a future version. - | - | To make sure that the inlined code is binary compatible you must make sure that - | value valBinaryAPI2 is public in the binary API. - | * Option 1: Annotate value valBinaryAPI2 with @publicInBinary - | * Option 2: Make value valBinaryAPI2 public - | - | This change may break binary compatibility if a previous version of this - | library was compiled with generated accessors. Binary compatibility should - | be checked using MiMa. If binary compatibility is broken, you should add the - | old accessor explicitly in the source code. The following code should be - | added to package J: - | @publicInBinary private[J] def inline$valBinaryAPI2$i5(x$0: foo.I): Int = x$0.valBinaryAPI2 - -------------------------------------------------------------------------------------------------------------------- +No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/inline-unstable-accessors.scala b/tests/neg/inline-unstable-accessors.scala index cf65006daaf8..a7fa75c2c6c9 100644 --- a/tests/neg/inline-unstable-accessors.scala +++ b/tests/neg/inline-unstable-accessors.scala @@ -7,12 +7,12 @@ class A: private[foo] val valBinaryAPI2: Int = 1 @publicInBinary private[foo] val valBinaryAPI3: Int = 1 inline def inlined = - valBinaryAPI1 + // error - valBinaryAPI2 + // error + valBinaryAPI1 + // warn + valBinaryAPI2 + // warn valBinaryAPI3 class B(val a: A): inline def inlined = - a.valBinaryAPI2 + // error + a.valBinaryAPI2 + // warn a.valBinaryAPI3 final class C: @@ -20,12 +20,12 @@ final class C: private[foo] val valBinaryAPI2: Int = 1 @publicInBinary private[foo] val valBinaryAPI3: Int = 1 inline def inlined = - valBinaryAPI1 + // error - valBinaryAPI2 + // error + valBinaryAPI1 + // warn + valBinaryAPI2 + // warn valBinaryAPI3 final class D(val c: C): inline def inlined = - c.valBinaryAPI2 + // error + c.valBinaryAPI2 + // warn c.valBinaryAPI3 object E: @@ -33,12 +33,12 @@ object E: private[foo] val valBinaryAPI2: Int = 1 @publicInBinary private[foo] val valBinaryAPI3: Int = 1 inline def inlined = - valBinaryAPI1 + // error - valBinaryAPI2 + // error + valBinaryAPI1 + // warn + valBinaryAPI2 + // warn valBinaryAPI3 object F: inline def inlined = - E.valBinaryAPI2 + // error + E.valBinaryAPI2 + // warn E.valBinaryAPI3 package object G: @@ -46,12 +46,12 @@ package object G: private[foo] val valBinaryAPI2: Int = 1 @publicInBinary private[foo] val valBinaryAPI3: Int = 1 inline def inlined = - valBinaryAPI1 + // error - valBinaryAPI2 + // error + valBinaryAPI1 + // warn + valBinaryAPI2 + // warn valBinaryAPI3 package object H: inline def inlined = - G.valBinaryAPI2 + // error + // G.valBinaryAPI2 + // FIXME should error (now fails -Ycheck) G.valBinaryAPI3 package I: @@ -59,10 +59,12 @@ package I: private[foo] val valBinaryAPI2: Int = 1 @publicInBinary private[foo] val valBinaryAPI3: Int = 1 inline def inlined = - valBinaryAPI1 + // error - valBinaryAPI2 + // error + valBinaryAPI1 + // warn + valBinaryAPI2 + // warn valBinaryAPI3 package J: inline def inlined = - I.valBinaryAPI2 + // error + // I.valBinaryAPI2 + // FIXME should error (now fails -Ycheck) I.valBinaryAPI3 + +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/main-functions-nameclash.scala b/tests/neg/main-functions-nameclash.scala deleted file mode 100644 index 1f9352e1592d..000000000000 --- a/tests/neg/main-functions-nameclash.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -object foo { - @main def foo(x: Int) = () // error: class foo and object foo produce classes that overwrite one another -} diff --git a/tests/neg/manifest-summoning-b.scala b/tests/neg/manifest-summoning-b.scala deleted file mode 100644 index 6d1b8baff007..000000000000 --- a/tests/neg/manifest-summoning-b.scala +++ /dev/null @@ -1,4 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -val foo = manifest[List[? <: Int]] // error -val bar = optManifest[Array[? <: String]] // error diff --git a/tests/neg/matchable.scala b/tests/neg/matchable.scala deleted file mode 100644 index aaf8234f6d1e..000000000000 --- a/tests/neg/matchable.scala +++ /dev/null @@ -1,29 +0,0 @@ -//> using options -Xfatal-warnings -source future - -def foo[T](x: T): Matchable = - println(x.getClass()) // ok - println(x.isInstanceOf[Int]) // ok - x match - case x: Int => // error: should not be scrutinized - println("int") - x - case x: String => // error: should not be scrutinized - println("string") - x - List(x) match - case (x: Int) :: Nil => // error: should not be scrutinized - println("int") - x - case List(x: String) => // error: should not be scrutinized - println("string") - x - case List(y :: Nil) => // error: should not be scrutinized - y :: Nil - case _ => - x // error: should not be scrutinized - -@main def Test = - val x: Matchable = foo(1) - val y: Matchable = foo("hello") - assert(x != y) - diff --git a/tests/neg/missing-targetName.scala b/tests/neg/missing-targetName.scala index b5403ac7cb19..32f4646cd5a3 100644 --- a/tests/neg/missing-targetName.scala +++ b/tests/neg/missing-targetName.scala @@ -5,7 +5,8 @@ import scala.annotation.targetName class & { // error @targetName("op") def *(x: Int): Int = ??? // OK - def / (x: Int): Int // error - val frozen_& : Int = ??? // error - object some_??? // error + def / (x: Int): Int // warn + val frozen_& : Int = ??? // warn + object some_??? // warn } +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/old-syntax.scala b/tests/neg/old-syntax.scala deleted file mode 100644 index 124781d13db2..000000000000 --- a/tests/neg/old-syntax.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings -deprecation - -val f = (x: Int) ⇒ x + 1 // error - -val list = for (n ← List(42)) yield n + 1 // error diff --git a/tests/neg/ovlazy.scala b/tests/neg/ovlazy.scala deleted file mode 100644 index 69078fbd2745..000000000000 --- a/tests/neg/ovlazy.scala +++ /dev/null @@ -1,8 +0,0 @@ -//> using options -source 3.0-migration -Xfatal-warnings - -class A { - val x: Int = 1 -} -class B extends A { - override lazy val x: Int = 2 // error -} diff --git a/tests/neg/private-this-3.4.scala b/tests/neg/private-this-3.4.scala deleted file mode 100644 index b198e954e41b..000000000000 --- a/tests/neg/private-this-3.4.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Werror - -import scala.language.`3.4` - -class Foo: - private[this] def foo: Int = ??? // error: migration warning - protected[this] def bar: Int = ??? // error: migration warning diff --git a/tests/neg/private-this-future-migration.scala b/tests/neg/private-this-future-migration.scala deleted file mode 100644 index 7e3da2be72e2..000000000000 --- a/tests/neg/private-this-future-migration.scala +++ /dev/null @@ -1,7 +0,0 @@ -//> using options -Werror - -import scala.language.`future-migration` - -class Foo: - private[this] def foo: Int = ??? // error: migration warning - protected[this] def bar: Int = ??? // error: migration warning diff --git a/tests/neg/pureStatement.scala b/tests/neg/pureStatement.scala index 4d2ea1d49b08..09a59f1621db 100644 --- a/tests/neg/pureStatement.scala +++ b/tests/neg/pureStatement.scala @@ -3,16 +3,16 @@ class IOCapability object Test { - "" // error: pure expression does nothing in statement position + "" // warn: pure expression does nothing in statement position locally { - "" // error: pure expression does nothing in statement position + "" // warn: pure expression does nothing in statement position println("") - 42 // error: pure expression does nothing in statement position + 42 // warn: pure expression does nothing in statement position - ((x: Int) => println("hi")) // error: pure expression does nothing in statement position + ((x: Int) => println("hi")) // warn: pure expression does nothing in statement position () } @@ -24,7 +24,7 @@ object Test { implicit val cap: IOCapability = new IOCapability - 2 // error: pure expression does nothing in statement position + 2 // warn: pure expression does nothing in statement position doSideEffects(1) // error: pure expression does nothing in statement position @@ -32,3 +32,4 @@ object Test { broken.foo // no extra error, and no pure expression warning broken.foo() // same } +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/quote-simple-hole.scala b/tests/neg/quote-simple-hole.scala deleted file mode 100644 index 64e2bcad4862..000000000000 --- a/tests/neg/quote-simple-hole.scala +++ /dev/null @@ -1,17 +0,0 @@ -//> using options -Xfatal-warnings - -import scala.quoted.Quotes - -def test(using Quotes) = { - val x = '{0} - val y = '{ // error: Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ. - $x - } - val z = '{ - val a = ${ // error: Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ. - '{ - $y - } - } - } -} diff --git a/tests/neg/refinements-this.scala b/tests/neg/refinements-this.scala deleted file mode 100644 index f8d41bd85360..000000000000 --- a/tests/neg/refinements-this.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Xfatal-warnings - -class Outer: - type X = { type O = Outer.this.type } // ok - type Y = { type O = this.type } // error diff --git a/tests/neg/refutable-pattern-binding-messages.check b/tests/neg/refutable-pattern-binding-messages.check index 5a9d85fd4447..4a8f895264a3 100644 --- a/tests/neg/refutable-pattern-binding-messages.check +++ b/tests/neg/refutable-pattern-binding-messages.check @@ -22,24 +22,24 @@ | If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern, | which will result in a filtering for expression (using `withFilter`). | This patch can be rewritten automatically under -rewrite -source 3.2-migration. --- Error: tests/neg/refutable-pattern-binding-messages.scala:5:14 ------------------------------------------------------ -5 | val Positive(p) = 5 // error: refutable extractor +-- Warning: tests/neg/refutable-pattern-binding-messages.scala:5:14 ---------------------------------------------------- +5 | val Positive(p) = 5 // warn: refutable extractor | ^^^^^^^^^^^^^^^ | pattern binding uses refutable extractor `Test.Positive` | | If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. | This patch can be rewritten automatically under -rewrite -source 3.2-migration. --- Error: tests/neg/refutable-pattern-binding-messages.scala:10:20 ----------------------------------------------------- -10 | val i :: is = List(1, 2, 3) // error: pattern type more specialized +-- Warning: tests/neg/refutable-pattern-binding-messages.scala:10:20 --------------------------------------------------- +10 | val i :: is = List(1, 2, 3) // warn: pattern type more specialized | ^^^^^^^^^^^^^ | pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int] | | If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. | This patch can be rewritten automatically under -rewrite -source 3.2-migration. --- Error: tests/neg/refutable-pattern-binding-messages.scala:16:10 ----------------------------------------------------- -16 | val 1 = 2 // error: pattern type does not match +-- Warning: tests/neg/refutable-pattern-binding-messages.scala:16:10 --------------------------------------------------- +16 | val 1 = 2 // warn: pattern type does not match | ^ | pattern's type (1 : Int) does not match the right hand side expression's type (2 : Int) | diff --git a/tests/neg/refutable-pattern-binding-messages.scala b/tests/neg/refutable-pattern-binding-messages.scala index c6ae043652c2..e71371785d15 100644 --- a/tests/neg/refutable-pattern-binding-messages.scala +++ b/tests/neg/refutable-pattern-binding-messages.scala @@ -1,17 +1,17 @@ -//> using options -Werror + object Test { // refutable extractor object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } - val Positive(p) = 5 // error: refutable extractor + val Positive(p) = 5 // warn: refutable extractor for Positive(i) <- List(1, 2, 3) do () // error: refutable extractor // more specialized val xs: List[AnyRef] = ??? - val i :: is = List(1, 2, 3) // error: pattern type more specialized + val i :: is = List(1, 2, 3) // warn: pattern type more specialized for ((x: String) <- xs) do () // error: pattern type more specialized // does not match val ys: List[Option[?]] = ??? for none @ None <- ys do () // error: pattern type does not match - val 1 = 2 // error: pattern type does not match + val 1 = 2 // warn: pattern type does not match } diff --git a/tests/neg/rewrite-messages.scala b/tests/neg/rewrite-messages.scala deleted file mode 100644 index 7509682c4baa..000000000000 --- a/tests/neg/rewrite-messages.scala +++ /dev/null @@ -1,8 +0,0 @@ -//> using options -source:future-migration -deprecation -Werror - -import scala.util._ // error - -object Test { - extension (x: Int) def foo(y: Int) = x + y - 2 foo 4 // error -} diff --git a/tests/neg/strict-pattern-bindings-3.2.scala b/tests/neg/strict-pattern-bindings-3.2.scala deleted file mode 100644 index d7db6cd165e4..000000000000 --- a/tests/neg/strict-pattern-bindings-3.2.scala +++ /dev/null @@ -1,37 +0,0 @@ -//> using options -Xfatal-warnings -// These tests should fail under -Xfatal-warnings with source version source version 3.2 or later -import language.`3.2` - -object Test: - // from filtering-fors.scala - val xs: List[AnyRef] = ??? - - for ((x: String) <- xs) do () // error - for (y@ (x: String) <- xs) do () // error - for ((x, y) <- xs) do () // error - - for ((x: String) <- xs if x.isEmpty) do () // error - for ((x: String) <- xs; y = x) do () // error - for ((x: String) <- xs; (y, z) <- xs) do () // error // error - for (case (x: String) <- xs; (y, z) <- xs) do () // error - for ((x: String) <- xs; case (y, z) <- xs) do () // error - - val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) - for ((x, y) <- pairs) yield (y, x) // error - - // from unchecked-patterns.scala - val y :: ys = List(1, 2, 3) // error - val (1, c) = (1, 2) // error - val 1 *: cs = 1 *: Tuple() // error - - val (_: Int | _: AnyRef) = ??? : AnyRef // error - - val 1 = 2 // error - - object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } - object Always1 { def unapply(i: Int): Some[Int] = Some(i) } - object Pair { def unapply(t: (Int, Int)): t.type = t } - object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } - - val Positive(p) = 5 // error - val Some(s1) = Option(1) // error diff --git a/tests/neg/structural-2.scala b/tests/neg/structural-2.scala index 3613d6073e34..4353467fc821 100644 --- a/tests/neg/structural-2.scala +++ b/tests/neg/structural-2.scala @@ -69,7 +69,8 @@ object Test { package p6 { class Refinements { - val y: { val x: T; type T } // error: deprecated warning: illegal forward reference in refinement; now illegal + val y: { val x: T; type T } // warn: deprecated warning: illegal forward reference in refinement; now illegal } } +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) diff --git a/tests/neg/symbolic-packages.scala b/tests/neg/symbolic-packages.scala deleted file mode 100644 index 12719d027b4c..000000000000 --- a/tests/neg/symbolic-packages.scala +++ /dev/null @@ -1,13 +0,0 @@ -//> using options -Xfatal-warnings - -package `with spaces` { // error - class Foo -} - -package +.* { // error // error - class Bar -} - -package object `mixed_*` { // error - class Baz -} diff --git a/tests/neg/unchecked-patterns.scala b/tests/neg/unchecked-patterns.scala index db304a2f1875..d0e04be687dc 100644 --- a/tests/neg/unchecked-patterns.scala +++ b/tests/neg/unchecked-patterns.scala @@ -5,23 +5,24 @@ object Test { val (y1: Some[Int]) = Some(1): Option[Int] @unchecked // OK val y2: Some[Int] @unchecked = Some(1): Option[Int] // error - val x :: xs = List(1, 2, 3) // error - val (1, c) = (1, 2) // error - val 1 *: cs = 1 *: Tuple() // error + val x :: xs = List(1, 2, 3) // warn + val (1, c) = (1, 2) // warn + val 1 *: cs = 1 *: Tuple() // warn - val (_: Int | _: AnyRef) = ??? : AnyRef // error + val (_: Int | _: AnyRef) = ??? : AnyRef // warn - val 1 = 2 // error + val 1 = 2 // warn object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } object Always1 { def unapply(i: Int): Some[Int] = Some(i) } object Pair { def unapply(t: (Int, Int)): t.type = t } object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } - val Positive(p) = 5 // error - val Some(s1) = Option(1) // error + val Positive(p) = 5 // warn + val Some(s1) = Option(1) // warn val Some(s2) = Some(1) // OK val Always1(p1) = 5 // OK val Pair(t1, t2) = (5, 5) // OK val Triple(u1, u2, u3) = (5, 5, 5) // OK -} \ No newline at end of file +} +// nopos-error: No warnings can be incurred under -Werror (or -Xfatal-warnings) \ No newline at end of file diff --git a/tests/neg/warn-value-discard.check b/tests/neg/warn-value-discard.check deleted file mode 100644 index ba43c743709f..000000000000 --- a/tests/neg/warn-value-discard.check +++ /dev/null @@ -1,20 +0,0 @@ --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:27:36 ---------------------------------------------- -27 | mutable.Set.empty[String].remove("") // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type Boolean --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:39:41 ---------------------------------------------- -39 | mutable.Set.empty[String].subtractOne("") // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type scala.collection.mutable.Set[String] --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:59:4 ----------------------------------------------- -59 | mutable.Set.empty[String] += "" // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | discarded non-Unit value of type scala.collection.mutable.Set[String] --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:15:35 ---------------------------------------------- -15 | firstThing().map(_ => secondThing()) // error - | ^^^^^^^^^^^^^ - | discarded non-Unit value of type Either[Failed, Unit] --- [E175] Potential Issue Error: tests/neg/warn-value-discard.scala:18:35 ---------------------------------------------- -18 | firstThing().map(_ => secondThing()) // error - | ^^^^^^^^^^^^^ - | discarded non-Unit value of type Either[Failed, Unit] diff --git a/tests/neg/with-type-operator-future-migration.scala b/tests/neg/with-type-operator-future-migration.scala deleted file mode 100644 index 3ed2e3a8f067..000000000000 --- a/tests/neg/with-type-operator-future-migration.scala +++ /dev/null @@ -1,5 +0,0 @@ -//> using options -Werror - -import scala.language.`future-migration` - -def foo: Int with String = ??? // error diff --git a/tests/patmat/aliasing.check b/tests/patmat/aliasing.check index c367626d6f1e..018905abf47e 100644 --- a/tests/patmat/aliasing.check +++ b/tests/patmat/aliasing.check @@ -1,3 +1,3 @@ -14: Pattern Match Exhaustivity: _: Trait & Test.Alias1, _: Clazz & Test.Alias1 -19: Pattern Match Exhaustivity: _: Trait & Test.Alias2 -23: Pattern Match Exhaustivity: _: Trait & (Test.Alias2 & OpenTrait2){val x: Int} +14: Pattern Match Exhaustivity: _: Trait & Alias1, _: Clazz & Alias1 +19: Pattern Match Exhaustivity: _: Trait & Alias2 +23: Pattern Match Exhaustivity: _: Trait & (Alias2 & OpenTrait2){val x: Int} diff --git a/tests/patmat/i12020.check b/tests/patmat/i12020.check index b89bdc8314e5..13b07e2e5992 100644 --- a/tests/patmat/i12020.check +++ b/tests/patmat/i12020.check @@ -1 +1 @@ -19: Pattern Match Exhaustivity: _: TypeDef +19: Pattern Match Exhaustivity: _: x$1.reflect.TypeDef diff --git a/tests/patmat/i14407.dupe.check b/tests/patmat/i14407.dupe.check index b0605bcd95e5..e6f742314d98 100644 --- a/tests/patmat/i14407.dupe.check +++ b/tests/patmat/i14407.dupe.check @@ -1 +1,2 @@ 6: Match case Unreachable +0: No Kind diff --git a/tests/patmat/i18118.check b/tests/patmat/i18118.check index 8861eb273fb9..f7ad777f5e8c 100644 --- a/tests/patmat/i18118.check +++ b/tests/patmat/i18118.check @@ -2,3 +2,4 @@ 21: Pattern Match 32: Pattern Match 41: Pattern Match +0: No Kind diff --git a/tests/patmat/i2502.check b/tests/patmat/i2502.check index fe2194e650cf..56cd3f6c0b8c 100644 --- a/tests/patmat/i2502.check +++ b/tests/patmat/i2502.check @@ -1 +1 @@ -5: Pattern Match Exhaustivity: _: BTypes.ClassBType \ No newline at end of file +5: Pattern Match Exhaustivity: _: BTypes.this.ClassBType diff --git a/tests/patmat/i2502b.check b/tests/patmat/i2502b.check index fe2194e650cf..56cd3f6c0b8c 100644 --- a/tests/patmat/i2502b.check +++ b/tests/patmat/i2502b.check @@ -1 +1 @@ -5: Pattern Match Exhaustivity: _: BTypes.ClassBType \ No newline at end of file +5: Pattern Match Exhaustivity: _: BTypes.this.ClassBType diff --git a/tests/patmat/i3938.check b/tests/patmat/i3938.check index 5aaefe2263e1..2acd1040ead4 100644 --- a/tests/patmat/i3938.check +++ b/tests/patmat/i3938.check @@ -1 +1 @@ -34: Pattern Match Exhaustivity: bar.C() +34: Pattern Match Exhaustivity: foo.bar.C() diff --git a/tests/patmat/i6255b.check b/tests/patmat/i6255b.check index 265ec9fa9c4b..bd9585becc56 100644 --- a/tests/patmat/i6255b.check +++ b/tests/patmat/i6255b.check @@ -1 +1 @@ -3: Pattern Match Exhaustivity: _: Expr[Int] +3: Pattern Match Exhaustivity: _: scala.quoted.Expr[Int] diff --git a/tests/patmat/t10100.check b/tests/patmat/t10100.check index d11715a5f371..19a89cd08a74 100644 --- a/tests/patmat/t10100.check +++ b/tests/patmat/t10100.check @@ -1 +1 @@ -12: Pattern Match Exhaustivity: (_, FancyFoo(_)) +12: Pattern Match Exhaustivity: (_, NonExhaustive#FancyFoo(_)) diff --git a/tests/patmat/t9779.check b/tests/patmat/t9779.check index 63f3b8963cac..c1886064d8ef 100644 --- a/tests/patmat/t9779.check +++ b/tests/patmat/t9779.check @@ -1 +1 @@ -10: Pattern Match Exhaustivity: _: a.Elem[_] +10: Pattern Match Exhaustivity: _: a.Elem[?] diff --git a/tests/pos-custom-args/captures/colltest.scala b/tests/pos-custom-args/captures/colltest.scala index ab3ac437db9f..eb2212f62b9b 100644 --- a/tests/pos-custom-args/captures/colltest.scala +++ b/tests/pos-custom-args/captures/colltest.scala @@ -3,22 +3,18 @@ object CollectionStrawMan5 { /** Base trait for generic collections */ trait Iterable[+A] extends IterableLike[A] { - this: Iterable[A]^ => def iterator: Iterator[A]^{this} def coll: Iterable[A]^{this} = this } trait IterableLike[+A]: - this: IterableLike[A]^ => def coll: Iterable[A]^{this} def partition(p: A => Boolean): Unit = val pn = Partition(coll, p) () /** Concrete collection type: View */ - trait View[+A] extends Iterable[A] with IterableLike[A] { - this: View[A]^ => - } + trait View[+A] extends Iterable[A] with IterableLike[A] case class Partition[A](val underlying: Iterable[A]^, p: A => Boolean) { self: Partition[A]^{underlying, p} => diff --git a/tests/pos-custom-args/captures/future-traverse.scala b/tests/pos-custom-args/captures/future-traverse.scala index 743984660af0..d19050d0865e 100644 --- a/tests/pos-custom-args/captures/future-traverse.scala +++ b/tests/pos-custom-args/captures/future-traverse.scala @@ -5,7 +5,7 @@ trait BuildFrom[-From, -A, +C] { def newBuilder(from: From): Builder[A, C] } -trait Future[+T] { this: Future[T]^ => +trait Future[+T] { import Future.* def foldLeft[R](r: R): R = r def traverse[A, B, M[X] <: IterableOnce[X]](in: M[A]^, bf: BuildFrom[M[A]^, B, M[B]^]): Unit = diff --git a/tests/pos-custom-args/captures/hk-param.scala b/tests/pos-custom-args/captures/hk-param.scala index bf2f75f29e7f..df4335069bbb 100644 --- a/tests/pos-custom-args/captures/hk-param.scala +++ b/tests/pos-custom-args/captures/hk-param.scala @@ -12,6 +12,5 @@ trait Itable[+A] extends ItableOnce[A] with ILike[A, Itable^] /** Iterator can be used only once */ trait ItableOnce[+A] { - this: ItableOnce[A]^ => def iterator: Iterator[A]^{this} } diff --git a/tests/pos-custom-args/captures/iterators.scala b/tests/pos-custom-args/captures/iterators.scala index 9a3ce7569b09..89e1eb91b4f4 100644 --- a/tests/pos-custom-args/captures/iterators.scala +++ b/tests/pos-custom-args/captures/iterators.scala @@ -1,7 +1,6 @@ package cctest trait IterableOnce[A]: - this: IterableOnce[A]^ => def iterator: Iterator[A]^{this} abstract class Iterator[T]: diff --git a/tests/pos-custom-args/captures/lazylists.scala b/tests/pos-custom-args/captures/lazylists.scala index 273f21c1fcf3..a6aa606483fa 100644 --- a/tests/pos-custom-args/captures/lazylists.scala +++ b/tests/pos-custom-args/captures/lazylists.scala @@ -2,8 +2,6 @@ class CC type Cap = CC^ trait LazyList[+A]: - this: LazyList[A]^ => - def isEmpty: Boolean def head: A def tail: LazyList[A]^{this} diff --git a/tests/pos-custom-args/captures/selftypes.scala b/tests/pos-custom-args/captures/selftypes.scala index fff7445c419a..2e33a56f609c 100644 --- a/tests/pos-custom-args/captures/selftypes.scala +++ b/tests/pos-custom-args/captures/selftypes.scala @@ -20,5 +20,11 @@ class IM: def coll: IM^{this} = ??? foo(coll) +// Demonstrates root mapping for self types, implicitly +class IM2: + def coll: IM2^{this} = ??? + foo2(coll) + def foo(im: IM^): Unit = ??? +def foo2(im: IM2^): Unit = ??? diff --git a/tests/pos-custom-args/captures/steppers.scala b/tests/pos-custom-args/captures/steppers.scala index 6169abab21dc..fa39f37f742f 100644 --- a/tests/pos-custom-args/captures/steppers.scala +++ b/tests/pos-custom-args/captures/steppers.scala @@ -1,6 +1,5 @@ -trait Stepper[+A]: - this: Stepper[A]^ => +trait Stepper[+A] object Stepper: trait EfficientSplit @@ -8,7 +7,6 @@ object Stepper: sealed trait StepperShape[-T, S <: Stepper[_]^] extends Pure trait IterableOnce[+A] extends Any: - this: IterableOnce[A]^ => def stepper[S <: Stepper[_]^{this}](implicit shape: StepperShape[A, S]): S = ??? sealed abstract class ArraySeq[T] extends IterableOnce[T], Pure: diff --git a/tests/pos-java16+/i19386/FromScala.scala b/tests/pos-java16+/i19386/FromScala.scala new file mode 100644 index 000000000000..82b5835753a1 --- /dev/null +++ b/tests/pos-java16+/i19386/FromScala.scala @@ -0,0 +1,2 @@ +def test(r: R1): Unit = + val i: Int = r.i() diff --git a/tests/pos-java16+/i19386/R1.java b/tests/pos-java16+/i19386/R1.java new file mode 100644 index 000000000000..40837040d659 --- /dev/null +++ b/tests/pos-java16+/i19386/R1.java @@ -0,0 +1 @@ +public record R1(int i) {} diff --git a/tests/pos-java16+/java-records/FromScala.scala b/tests/pos-java16+/java-records/FromScala.scala index 67747e658432..8654f88f1835 100644 --- a/tests/pos-java16+/java-records/FromScala.scala +++ b/tests/pos-java16+/java-records/FromScala.scala @@ -1,4 +1,8 @@ object C: + + def useR0: Unit = + val r = R0() + def useR1: Unit = // constructor signature val r = R1(123, "hello") @@ -41,3 +45,7 @@ object C: val l2: Long = r3.l(43L, 44L) // supertype val isRecord: java.lang.Record = r3 + + def useR4: Unit = + val r4 = R4(1) + val i: Int = r4.t diff --git a/tests/pos-java16+/java-records/R0.java b/tests/pos-java16+/java-records/R0.java new file mode 100644 index 000000000000..ad43a2b22673 --- /dev/null +++ b/tests/pos-java16+/java-records/R0.java @@ -0,0 +1 @@ +public record R0() {} diff --git a/tests/pos-java16+/java-records/R4.java b/tests/pos-java16+/java-records/R4.java new file mode 100644 index 000000000000..b8a415480afd --- /dev/null +++ b/tests/pos-java16+/java-records/R4.java @@ -0,0 +1 @@ +public record R4<T>(T t) {} diff --git a/tests/pos-macros/i19191/Lib_1.scala b/tests/pos-macros/i19191/Lib_1.scala new file mode 100644 index 000000000000..dd77aec377b2 --- /dev/null +++ b/tests/pos-macros/i19191/Lib_1.scala @@ -0,0 +1,15 @@ +trait Binding[+A]: + def value: A = ??? +object Binding: + inline def apply[A](inline a: A): Binding[A] = ??? + final case class Constant[+A](override val value: A) extends Binding[A] + +extension [A](inline binding: Binding[A]) + transparent inline def bind: A = null.asInstanceOf[A] + +trait Vars[A] extends BindingSeq[A] +trait BindingSeq[+A]: + def foreachBinding[U](f: A => Binding[U]): Binding[Unit] = ??? + +extension [A](inline bindingSeq: BindingSeq[A]) + transparent inline def foreach[U](inline f: A => U): Unit = ${ Macros.foreach('bindingSeq, 'f) } diff --git a/tests/pos-macros/i19191/Macro_1.scala b/tests/pos-macros/i19191/Macro_1.scala new file mode 100644 index 000000000000..b5ba403d3faa --- /dev/null +++ b/tests/pos-macros/i19191/Macro_1.scala @@ -0,0 +1,54 @@ +import scala.compiletime._ +import scala.deriving._ +import scala.quoted._ +import scala.annotation.meta.field + +object Macros{ + private def bindingFunctionBody[A: quoted.Type, B: quoted.Type](f: quoted.Expr[A => B])(using Quotes) = + import quoted.quotes.reflect.* + f.asTerm match + case inlined @ Inlined( + call, + bindings, + block @ Block( + List( + defDef @ DefDef( + name, + paramss @ List(TermParamClause(List(param @ ValDef(paramName, paramTpt, _)))), + tpt, + Some(rhs) + ) + ), + closureIdent + ) + ) => + Inlined + .copy(inlined)( + call, + bindings, + '{ (a: A) => + ${ + Block( + List( + ValDef + .copy(param)(paramName, paramTpt, Some('a.asTerm)) + .changeOwner(Symbol.spliceOwner) + ), + '{ + Binding(${ rhs.changeOwner(Symbol.spliceOwner).asExprOf[B] }) + }.asTerm.changeOwner(Symbol.spliceOwner) + ) + .asExprOf[Binding[B]] + }: Binding[B] + }.asTerm + ) + .asExprOf[A => Binding[B]] + case _ => + '{ (a: A) => Binding.Constant($f(a)): Binding[B] } + end match + end bindingFunctionBody + + def foreach[A: quoted.Type, U: quoted.Type](self: quoted.Expr[BindingSeq[A]], f: quoted.Expr[A => U])(using + qctx: Quotes + ): quoted.Expr[Unit] = '{ $self.foreachBinding(${ bindingFunctionBody(f) }).bind } +} diff --git a/tests/pos-macros/i19191/Test_2.scala b/tests/pos-macros/i19191/Test_2.scala new file mode 100644 index 000000000000..c7f40d996ed9 --- /dev/null +++ b/tests/pos-macros/i19191/Test_2.scala @@ -0,0 +1,6 @@ +def Test = { + val vars: Vars[Int] = ??? + + val works = vars.foreach { v => () } + val fails = for (v <- vars) () +} diff --git a/tests/pos-macros/i19369/Macro_1.scala b/tests/pos-macros/i19369/Macro_1.scala new file mode 100644 index 000000000000..151859d6e583 --- /dev/null +++ b/tests/pos-macros/i19369/Macro_1.scala @@ -0,0 +1,11 @@ +import scala.quoted._ + +object Unapplier: + transparent inline def unapply(arg: Any): Option[Int] = ${unapplyImpl('arg)} + + def unapplyImpl(using Quotes)(argExpr: Expr[Any]): Expr[Option[Int]] = + executionCount += 1 + assert(executionCount == 1, "macro should only expand once") + '{Some(1)} + + private var executionCount = 0 diff --git a/tests/pos-macros/i19369/Test_2.scala b/tests/pos-macros/i19369/Test_2.scala new file mode 100644 index 000000000000..8d697ff8f09e --- /dev/null +++ b/tests/pos-macros/i19369/Test_2.scala @@ -0,0 +1,2 @@ +@main def main() = + val Unapplier(result) = Some(5) diff --git a/tests/pos-macros/i19537/Macro_1.scala b/tests/pos-macros/i19537/Macro_1.scala new file mode 100644 index 000000000000..932994657d24 --- /dev/null +++ b/tests/pos-macros/i19537/Macro_1.scala @@ -0,0 +1,6 @@ +import scala.annotation.{experimental, MacroAnnotation} +import scala.quoted.* + +@experimental +class annotation extends MacroAnnotation: + def transform(using Quotes)(tree: quotes.reflect.Definition) = List(tree) diff --git a/tests/pos-macros/i19537/Test_2.scala b/tests/pos-macros/i19537/Test_2.scala new file mode 100644 index 000000000000..5c65a679b64a --- /dev/null +++ b/tests/pos-macros/i19537/Test_2.scala @@ -0,0 +1,4 @@ +@scala.annotation.experimental +@annotation +class Test: + { } diff --git a/tests/pos-macros/i19539/Macro_1.scala b/tests/pos-macros/i19539/Macro_1.scala new file mode 100644 index 000000000000..932994657d24 --- /dev/null +++ b/tests/pos-macros/i19539/Macro_1.scala @@ -0,0 +1,6 @@ +import scala.annotation.{experimental, MacroAnnotation} +import scala.quoted.* + +@experimental +class annotation extends MacroAnnotation: + def transform(using Quotes)(tree: quotes.reflect.Definition) = List(tree) diff --git a/tests/pos-macros/i19539/Test_2.scala b/tests/pos-macros/i19539/Test_2.scala new file mode 100644 index 000000000000..d7e63b80a386 --- /dev/null +++ b/tests/pos-macros/i19539/Test_2.scala @@ -0,0 +1,4 @@ +@scala.annotation.experimental +@annotation +class Test: + println() diff --git a/tests/pos-macros/i9361.scala b/tests/pos-macros/i9361.scala index 18efd203d885..abd711bbfcaa 100644 --- a/tests/pos-macros/i9361.scala +++ b/tests/pos-macros/i9361.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/9361 +// https://github.com/scala/scala3/issues/9361 import scala.quoted._ diff --git a/tests/pos-special/stdlib/collection/concurrent/BasicNode.java b/tests/pos-special/stdlib/collection/concurrent/BasicNode.java deleted file mode 100644 index c6ec91e4fde8..000000000000 --- a/tests/pos-special/stdlib/collection/concurrent/BasicNode.java +++ /dev/null @@ -1,19 +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.collection.concurrent; - -public abstract class BasicNode { - - public abstract String string(int lev); - -} diff --git a/tests/pos-special/stdlib/collection/concurrent/CNodeBase.java b/tests/pos-special/stdlib/collection/concurrent/CNodeBase.java deleted file mode 100644 index ddffa365234e..000000000000 --- a/tests/pos-special/stdlib/collection/concurrent/CNodeBase.java +++ /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.collection.concurrent; - -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; - -abstract class CNodeBase<K, V> extends MainNode<K, V> { - - @SuppressWarnings("unchecked") - public static final AtomicIntegerFieldUpdater<CNodeBase<?, ?>> updater = - AtomicIntegerFieldUpdater.newUpdater((Class<CNodeBase<?, ?>>) (Class<?>) CNodeBase.class, "csize"); - - public volatile int csize = -1; - - public boolean CAS_SIZE(int oldval, int nval) { - return updater.compareAndSet(this, oldval, nval); - } - - public void WRITE_SIZE(int nval) { - updater.set(this, nval); - } - - public int READ_SIZE() { - return updater.get(this); - } - -} diff --git a/tests/pos-special/stdlib/collection/concurrent/Gen.java b/tests/pos-special/stdlib/collection/concurrent/Gen.java deleted file mode 100644 index 07af2983f32d..000000000000 --- a/tests/pos-special/stdlib/collection/concurrent/Gen.java +++ /dev/null @@ -1,15 +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.collection.concurrent; - -final class Gen {} diff --git a/tests/pos-special/stdlib/collection/concurrent/INodeBase.java b/tests/pos-special/stdlib/collection/concurrent/INodeBase.java deleted file mode 100644 index dfb99806594f..000000000000 --- a/tests/pos-special/stdlib/collection/concurrent/INodeBase.java +++ /dev/null @@ -1,39 +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.collection.concurrent; - -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -abstract class INodeBase<K, V> extends BasicNode { - - @SuppressWarnings("unchecked") - public static final AtomicReferenceFieldUpdater<INodeBase<?, ?>, MainNode<?, ?>> updater = - AtomicReferenceFieldUpdater.newUpdater((Class<INodeBase<?, ?>>) (Class<?>) INodeBase.class, (Class<MainNode<?, ?>>) (Class<?>) MainNode.class, "mainnode"); - - static final Object RESTART = new Object(); - - static final Object NO_SUCH_ELEMENT_SENTINEL = new Object(); - - public volatile MainNode<K, V> mainnode = null; - - public final Gen gen; - - public INodeBase(Gen generation) { - gen = generation; - } - - public BasicNode prev() { - return null; - } - -} diff --git a/tests/pos-special/stdlib/collection/concurrent/MainNode.java b/tests/pos-special/stdlib/collection/concurrent/MainNode.java deleted file mode 100644 index f7f022974e9e..000000000000 --- a/tests/pos-special/stdlib/collection/concurrent/MainNode.java +++ /dev/null @@ -1,46 +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.collection.concurrent; - -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -abstract class MainNode<K, V> extends BasicNode { - - @SuppressWarnings("unchecked") - public static final AtomicReferenceFieldUpdater<MainNode<?, ?>, MainNode<?, ?>> updater = - AtomicReferenceFieldUpdater.newUpdater((Class<MainNode<?, ?>>) (Class<?>) MainNode.class, (Class<MainNode<?, ?>>) (Class<?>) MainNode.class, "prev"); - - public volatile MainNode<K, V> prev = null; - - public abstract int cachedSize(Object ct); - - // standard contract - public abstract int knownSize(); - - public boolean CAS_PREV(MainNode<K, V> oldval, MainNode<K, V> nval) { - return updater.compareAndSet(this, oldval, nval); - } - - public void WRITE_PREV(MainNode<K, V> nval) { - updater.set(this, nval); - } - - // do we need this? unclear in the javadocs... - // apparently not - volatile reads are supposed to be safe - // regardless of whether there are concurrent ARFU updates - @Deprecated @SuppressWarnings("unchecked") - public MainNode<K, V> READ_PREV() { - return (MainNode<K, V>) updater.get(this); - } - -} diff --git a/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala b/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala index 2454bca9d653..5ad6a99f6055 100644 --- a/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala +++ b/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala @@ -833,7 +833,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { case tp => report.warning( s"an unexpected type representation reached the compiler backend while compiling ${ctx.compilationUnit}: $tp. " + - "If possible, please file a bug on https://github.com/lampepfl/dotty/issues") + "If possible, please file a bug on https://github.com/scala/scala3/issues") tp match { case tp: ThisType if tp.cls == defn.ArrayClass => ObjectRef.asInstanceOf[ct.bTypes.ClassBType] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test @@ -874,7 +874,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { report.error( em"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName} |signature: $sig - |if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues + |if this is reproducible, please report bug at https://github.com/scala/scala3/issues """, sym.sourcePos) throw ex } diff --git a/tests/pos-with-compiler-cc/backend/jvm/BCodeSkelBuilder.scala b/tests/pos-with-compiler-cc/backend/jvm/BCodeSkelBuilder.scala index 1d8a9c579cb9..125ee26b0528 100644 --- a/tests/pos-with-compiler-cc/backend/jvm/BCodeSkelBuilder.scala +++ b/tests/pos-with-compiler-cc/backend/jvm/BCodeSkelBuilder.scala @@ -131,7 +131,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // Should we do this transformation earlier, say in Constructors? Or would that just cause // pain for scala-{js, native}? // - // @sjrd (https://github.com/lampepfl/dotty/pull/9181#discussion_r457458205): + // @sjrd (https://github.com/scala/scala3/pull/9181#discussion_r457458205): // moving that before the back-end would make things significantly more complicated for // Scala.js and Native. Both have a first-class concept of ModuleClass, and encode the // singleton pattern of MODULE$ in a completely different way. In the Scala.js IR, there @@ -142,7 +142,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { // TODO: remove `!f.name.is(LazyBitMapName)` once we change lazy val encoding - // https://github.com/lampepfl/dotty/issues/7140 + // https://github.com/scala/scala3/issues/7140 // // Lazy val encoding assumes bitmap fields are non-static // diff --git a/tests/pos-with-compiler-cc/backend/jvm/DottyBackendInterface.scala b/tests/pos-with-compiler-cc/backend/jvm/DottyBackendInterface.scala index a70d671f9c63..6ce434015b8c 100644 --- a/tests/pos-with-compiler-cc/backend/jvm/DottyBackendInterface.scala +++ b/tests/pos-with-compiler-cc/backend/jvm/DottyBackendInterface.scala @@ -126,7 +126,7 @@ object DottyBackendInterface { * See also `genPlainClass` in `BCodeSkelBuilder.scala`. * * TODO: remove the special handing of `LazyBitMapName` once we swtich to - * the new lazy val encoding: https://github.com/lampepfl/dotty/issues/7140 + * the new lazy val encoding: https://github.com/scala/scala3/issues/7140 */ def isStaticModuleField(using Context): Boolean = sym.owner.isStaticModuleClass && sym.isField && !sym.name.is(LazyBitMapName) diff --git a/tests/pos/erasure-array.scala b/tests/pos/erasure-array.scala index 63240e9801f0..83dc2a423306 100644 --- a/tests/pos/erasure-array.scala +++ b/tests/pos/erasure-array.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/1065 +// https://github.com/scala/scala3/issues/1065 package hello object world { diff --git a/tests/pos/export-main.scala b/tests/pos/export-main.scala new file mode 100644 index 000000000000..7ce0a23de76f --- /dev/null +++ b/tests/pos/export-main.scala @@ -0,0 +1,5 @@ +object Foo: + @main def baz: Int = 1 + +object Bar: + export Foo.baz // export Foo.baz but not create an new main entry point diff --git a/tests/pos/i10242.scala b/tests/pos/i10242.scala index 10883633971e..b4a9700e1634 100644 --- a/tests/pos/i10242.scala +++ b/tests/pos/i10242.scala @@ -1,6 +1,6 @@ //> using options -source:3.3 -// https://github.com/lampepfl/dotty/issues/10242 +// https://github.com/scala/scala3/issues/10242 type Foo[A, B <: A] = A type Bar[A] = A match { diff --git a/tests/pos/i11681.scala b/tests/pos/i11681.scala index 587285911610..3374cbf9a4af 100644 --- a/tests/pos/i11681.scala +++ b/tests/pos/i11681.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/11681 +// https://github.com/scala/scala3/issues/11681 import scala.collection.Factory diff --git a/tests/pos/i12663.scala b/tests/pos/i12663.scala index befbc65316cb..dc446acb6bdf 100644 --- a/tests/pos/i12663.scala +++ b/tests/pos/i12663.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/12663 +// https://github.com/scala/scala3/issues/12663 final class HookComponentBuilder[Ctx, CtxFn[_]] { def asd[A](f: Ctx => A): A = ??? diff --git a/tests/pos/i12679.scala b/tests/pos/i12679.scala index fed62c72dd42..3fb14a8a91ed 100644 --- a/tests/pos/i12679.scala +++ b/tests/pos/i12679.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/12679 +// https://github.com/scala/scala3/issues/12679 object Example: def foo[F[_]](qux: String, quux: String = ""): F[Unit] = ??? diff --git a/tests/pos/i14096.scala b/tests/pos/i14096.scala index 59365231b121..49f80332483a 100644 --- a/tests/pos/i14096.scala +++ b/tests/pos/i14096.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/14096 +// https://github.com/scala/scala3/issues/14096 object Test: object Forte: def test[T](i: Int, config: String = ""): Int = 1 diff --git a/tests/pos/i14271.scala b/tests/pos/i14271.scala index 8f46940afd09..d29cf306617a 100644 --- a/tests/pos/i14271.scala +++ b/tests/pos/i14271.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/14271 +// https://github.com/scala/scala3/issues/14271 class Bound[T] class MyClass[T <: Bound[T]] diff --git a/tests/pos/i14278.scala b/tests/pos/i14278.scala index ebc9376fbad5..09feb75a0c6f 100644 --- a/tests/pos/i14278.scala +++ b/tests/pos/i14278.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/14278 +// https://github.com/scala/scala3/issues/14278 class Foo extension (foo: Foo) diff --git a/tests/pos/i14642.scala b/tests/pos/i14642.scala index b69da7d8d6d7..f380c404bd03 100644 --- a/tests/pos/i14642.scala +++ b/tests/pos/i14642.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/14642 +// https://github.com/scala/scala3/issues/14642 case object A case class B() case class C() diff --git a/tests/pos/i14830.scala b/tests/pos/i14830.scala index 592a47c1a53c..6664bd44ea4a 100644 --- a/tests/pos/i14830.scala +++ b/tests/pos/i14830.scala @@ -1,5 +1,5 @@ -// https://github.com/lampepfl/dotty/issues/14830 +// https://github.com/scala/scala3/issues/14830 val a: Comparable[String] = "Fred" val b: { def length: Int } = "Fred" val c: Comparable[String] & { def length: Int } = "Fred" diff --git a/tests/pos/i15546.scala b/tests/pos/i15546.scala index 19c7f15b24f1..86303e283baa 100644 --- a/tests/pos/i15546.scala +++ b/tests/pos/i15546.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/15546 +// https://github.com/scala/scala3/issues/15546 trait Foo[F[_]] diff --git a/tests/pos/i15784.scala b/tests/pos/i15784.scala new file mode 100644 index 000000000000..ab4b82638a42 --- /dev/null +++ b/tests/pos/i15784.scala @@ -0,0 +1,8 @@ +def i15784 = List(42) match + case List(_, rest @ _*) => rest + case List(_, Rest @ _*) => Rest + case List(_, `Rest` @ _*) => Rest + case _ => ??? + +def i15784_auxiliary = 42 match + case `type` : Int => `type` diff --git a/tests/pos/i18260.scala b/tests/pos/i18260.scala new file mode 100644 index 000000000000..4cda6d48f05a --- /dev/null +++ b/tests/pos/i18260.scala @@ -0,0 +1,11 @@ +import scala.deriving.Mirror + +type Id[A] = A +object Id: + def apply[A](a: A): Id[A] = a + +def test[P <: Product](using mirror: Mirror.ProductOf[P])(tuples: Tuple.Map[mirror.MirroredElemTypes, Id]): Tuple.Map[mirror.MirroredElemTypes, Id] = tuples + +def main() = + case class Test(p1: 1, p2: 2, p3: 3, p4: 4, p5: 5, p6: 6, p7: 7, p8: 8, p9: 9, p10: 10, p11: 11, p12: 12, p13: 13, p14: 14, p15: 15, p16: 16, p17: 17, p18: 18, p19: 19, p20: 20, p21: 21, p22: 22, p23: 23) + test[Test](Id[1](1), Id[2](2), Id[3](3), Id[4](4), Id[5](5), Id[6](6), Id[7](7), Id[8](8), Id[9](9), Id[10](10), Id[11](11), Id[12](12), Id[13](13), Id[14](14), Id[15](15), Id[16](16), Id[17](17), Id[18](18), Id[19](19), Id[20](20), Id[21](21), Id[22](22), Id[23](23)) diff --git a/tests/pos/i18578.scala b/tests/pos/i18578.scala new file mode 100644 index 000000000000..ee0ec6628c66 --- /dev/null +++ b/tests/pos/i18578.scala @@ -0,0 +1,17 @@ + +trait Animal +class Dog extends Animal + +trait Ev[T] + +given Ev[Dog] = ??? +given Ev[Animal] = ??? +given[T: Ev]: Ev[Set[T]] = ??? + +def f[T: Ev](v: T): Unit = ??? + +def main = + val s = Set(new Dog) + f(s) // Ok + f(Set(new Dog)) // Error before changes: Ambiguous given instances: both given instance given_Ev_Dog and given instance given_Ev_Animal match type Ev[T] + diff --git a/tests/pos/i19201.scala b/tests/pos/i19201.scala new file mode 100644 index 000000000000..4d9fa7bf3df1 --- /dev/null +++ b/tests/pos/i19201.scala @@ -0,0 +1,12 @@ +class Person( + val firstName: String, + val lastName: String, + val birthYear: Int = -1, + val address: String = "" +): + // Works if remove this constructor + def this() = this("John", "Doe") + +class Test: + def p1 = Person("First", "Last") // was: Type Error: none of the overloads.. match arguments + def p2 = Person("Josh", "Joe", 1912, "Main Street") diff --git a/tests/pos/i19202.scala b/tests/pos/i19202.scala new file mode 100644 index 000000000000..75226b0c8b65 --- /dev/null +++ b/tests/pos/i19202.scala @@ -0,0 +1,27 @@ +class Test { + def test1(s: String): Unit = { + if s == null then return + + case class XXX() + } + + def test2(s: String): Unit = { + if s == "" then return + + case class XXX() + } + + def test3(s: String): Unit = { + if s == null then return + + case class XXX() + () + } + + def test4(s: String): String = { + if s == null then return "" + + case class XXX() + "xxx" + } +} \ No newline at end of file diff --git a/tests/pos/i19301.scala b/tests/pos/i19301.scala new file mode 100644 index 000000000000..a4a5a858b754 --- /dev/null +++ b/tests/pos/i19301.scala @@ -0,0 +1,12 @@ +//> using options -Xfatal-warnings + +object Extensions: + infix def foo(x: String): Unit = () + extension (arg1: Int) infix def X (arg2: Int): Int = arg1 * arg2 + infix type X[A, B] + +export Extensions.* + +val x = 1 X 2 +type Foo = Int X Int +val u = Extensions foo "" diff --git a/tests/pos/i19304.scala b/tests/pos/i19304.scala new file mode 100644 index 000000000000..c8dee26f00fb --- /dev/null +++ b/tests/pos/i19304.scala @@ -0,0 +1,9 @@ +import scala.annotation.static +trait Foo[A] +object Foo: + @static val foo: Foo[String] = new {} + @static given Foo[String] = foo + + def bar = + val foo: Foo[String] = new {} + given Foo[String] = foo diff --git a/tests/pos/i19385.scala b/tests/pos/i19385.scala new file mode 100644 index 000000000000..0f66a15c13bc --- /dev/null +++ b/tests/pos/i19385.scala @@ -0,0 +1,8 @@ +import scala.compiletime.summonAll + +inline def f[M <: Tuple]: Unit = + type Alias = Tuple.Map[M, [X] =>> Numeric[X]] + summonAll[Tuple.Map[M, [X] =>> Numeric[X]]] // compiles + summonAll[Alias] // error: Tuple element types must be known at compile time + +val y1 = f[(Int, Int)] \ No newline at end of file diff --git a/tests/pos/i19445.scala b/tests/pos/i19445.scala new file mode 100644 index 000000000000..b3be4916500c --- /dev/null +++ b/tests/pos/i19445.scala @@ -0,0 +1,17 @@ +trait Foo: + case class Bar[A](value: A) + +object FooBar extends Foo + +object Test: + type UnwrapTypes[Xs] = + Xs match + case EmptyTuple => Xs + case x *: xs => UnwrapTypes[x] *: UnwrapTypes[xs] + case Foo#Bar[x] => UnwrapTypes[x] + case String => String + case Int => Int + + val x: Int = ??? : UnwrapTypes[FooBar.Bar[Int]] + val tup: (Int, String) = ??? : UnwrapTypes[(FooBar.Bar[Int], FooBar.Bar[String])] +end Test diff --git a/tests/pos/i19460.scala b/tests/pos/i19460.scala new file mode 100644 index 000000000000..b0b9a4ba4ea3 --- /dev/null +++ b/tests/pos/i19460.scala @@ -0,0 +1,5 @@ +type T[A] = A | Any + +def perform[A](using T[A]): A = perform2 + +def perform2[A](using T[A]): A = ??? \ No newline at end of file diff --git a/tests/pos/i19505.scala b/tests/pos/i19505.scala new file mode 100644 index 000000000000..69fb0217c1d7 --- /dev/null +++ b/tests/pos/i19505.scala @@ -0,0 +1,10 @@ +import scala.annotation.tailrec + +object Foo: + @tailrec + def foo(n: Int): Int = + if n == 0 then 0 + else foo(n-1) + +object Bar: + export Foo.foo // def foo here should not have `@tailrec` diff --git a/tests/pos/i19521.scala b/tests/pos/i19521.scala new file mode 100644 index 000000000000..19230fa4ed69 --- /dev/null +++ b/tests/pos/i19521.scala @@ -0,0 +1,13 @@ + +final abstract class PLet + +sealed trait Expr[+P] +case class ELet[+A](name: String, expr: Expr[A]) extends Expr[A | PLet] + +def go[P](e: Expr[P]): P = e match + case ELet(_, _) => + val x: Expr[P] | ELet[P] = ??? + val y: Expr[P] = x // conforms iff using gadt constraints + // error before changes: cast from gadt reasoning was not inserted because + // `Expr[P]` was erronously cached as a baseType of `Expr[P] | ELet[P]` (only true with gadt constraints) + ??? diff --git a/tests/pos/i19530.scala b/tests/pos/i19530.scala new file mode 100644 index 000000000000..01c3cc50a12d --- /dev/null +++ b/tests/pos/i19530.scala @@ -0,0 +1,3 @@ +object A { + def x = classOf[scala.Singleton] +} \ No newline at end of file diff --git a/tests/pos/i19548.scala b/tests/pos/i19548.scala new file mode 100644 index 000000000000..18d40f622236 --- /dev/null +++ b/tests/pos/i19548.scala @@ -0,0 +1,2 @@ +def byName[T](p: => T): T = p +val test = (if ??? then byName else (??? : ((=> Int) => Int))) (42) \ No newline at end of file diff --git a/tests/pos/i19570.min1.scala b/tests/pos/i19570.min1.scala new file mode 100644 index 000000000000..2cbc852641d3 --- /dev/null +++ b/tests/pos/i19570.min1.scala @@ -0,0 +1,23 @@ +enum Op[A]: + case Dup[T]() extends Op[(T, T)] + +def foo[R](f: [A] => Op[A] => R): R = ??? + +def test = + foo([A] => (o: Op[A]) => o match + case o: Op.Dup[u] => + summon[A =:= (u, u)] // Error: Cannot prove that A =:= (u, u) + () + ) + foo[Unit]([A] => (o: Op[A]) => o match + case o: Op.Dup[u] => + summon[A =:= (u, u)] // Ok + () + ) + foo({ + val f1 = [B] => (o: Op[B]) => o match + case o: Op.Dup[u] => + summon[B =:= (u, u)] // Also ok + () + f1 + }) diff --git a/tests/pos/i19570.min2.scala b/tests/pos/i19570.min2.scala new file mode 100644 index 000000000000..b1450d7e2d1a --- /dev/null +++ b/tests/pos/i19570.min2.scala @@ -0,0 +1,24 @@ +sealed trait Op[A, B] { def giveA: A; def giveB: B } +final case class Dup[T](x: T) extends Op[T, (T, T)] { def giveA: T = x; def giveB: (T, T) = (x, x) } + +class Test: + def foo[R](f: [A, B] => (o: Op[A, B]) => R): R = ??? + + def m1: Unit = + foo([A, B] => (o: Op[A, B]) => o match + case o: Dup[t] => + var a1: t = o.giveA + var a2: A = o.giveA + a1 = a2 + a2 = a1 + + var b1: (t, t) = o.giveB + var b2: B = o.giveB + b1 = b2 + b2 = b1 + + summon[A =:= t] // ERROR: Cannot prove that A =:= t. + summon[B =:= (t, t)] // ERROR: Cannot prove that B =:= (t, t). + + () + ) diff --git a/tests/pos/i19570.orig.scala b/tests/pos/i19570.orig.scala new file mode 100644 index 000000000000..6e574f52be91 --- /dev/null +++ b/tests/pos/i19570.orig.scala @@ -0,0 +1,14 @@ +enum Op[A, B]: + case Dup[T]() extends Op[T, (T, T)] + +def foo[R](f: [A, B] => (o: Op[A, B]) => R): R = + f(Op.Dup()) + +def test = + foo([A, B] => (o: Op[A, B]) => { + o match + case o: Op.Dup[t] => + summon[A =:= t] // ERROR: Cannot prove that A =:= t. + summon[B =:= (t, t)] // ERROR: Cannot prove that B =:= (t, t). + 42 + }) diff --git a/tests/pos/i19604/ZSet.scala b/tests/pos/i19604/ZSet.scala new file mode 100644 index 000000000000..b27c6a939f6c --- /dev/null +++ b/tests/pos/i19604/ZSet.scala @@ -0,0 +1,11 @@ +// ZSet.scala +// moving it to core.scala would lead to Recursion limit exceeded: find-member prelude.ZSetSyntax +package prelude + +import prelude.newtypes._ + +class ZSet[+A, +B] +object ZSet +trait ZSetSyntax { + implicit final class ZSetMapOps[+A](self: Map[A, Natural]) +} \ No newline at end of file diff --git a/tests/pos/i19604/core.scala b/tests/pos/i19604/core.scala new file mode 100644 index 000000000000..26b56fb0f8f2 --- /dev/null +++ b/tests/pos/i19604/core.scala @@ -0,0 +1,37 @@ +// core.scala +package prelude + +sealed trait Assertion[-A] +object Assertion: + def greaterThanOrEqualTo[A](value: A): Assertion[A] = ??? + +sealed trait AssertionError + +abstract class NewtypeCustom[A] { + type Type + protected inline def validateInline(inline value: A): Unit + + inline def apply(inline a1: A): Type = { + validateInline(a1) + a1.asInstanceOf[Type] + } +} +abstract class Newtype[A] extends NewtypeCustom[A] { + def assertion: Assertion[A] = ??? + protected inline def validateInline(inline value: A): Unit = ${ + Macros.validateInlineImpl[A]('assertion, 'value) + } +} + +abstract class Subtype[A] extends Newtype[A] { + type Type <: A +} + + +package object newtypes { + type Natural = Natural.Type + object Natural extends Subtype[Int] { + override inline def assertion = Assertion.greaterThanOrEqualTo(0) + val one: Natural = Natural(1) // triggers macro + } +} \ No newline at end of file diff --git a/tests/pos/i19604/macro.scala b/tests/pos/i19604/macro.scala new file mode 100644 index 000000000000..fa1faba10512 --- /dev/null +++ b/tests/pos/i19604/macro.scala @@ -0,0 +1,8 @@ +// macro.scala +package prelude +import scala.quoted.* + +object Macros { + def validateInlineImpl[A: Type](assertionExpr: Expr[Assertion[A]], a: Expr[A])(using Quotes): Expr[Unit] = + '{ () } +} diff --git a/tests/pos/i19604/prelude.scala b/tests/pos/i19604/prelude.scala new file mode 100644 index 000000000000..3a8292d3d2ec --- /dev/null +++ b/tests/pos/i19604/prelude.scala @@ -0,0 +1,8 @@ +// prelude.scala + +import prelude.newtypes.Natural + +package object prelude extends ZSetSyntax { + type MultiSet[+A] = ZSet[A, Natural] + val MultiSet: ZSet.type = ZSet +} \ No newline at end of file diff --git a/tests/pos/i19637.scala b/tests/pos/i19637.scala new file mode 100644 index 000000000000..53e609407bd0 --- /dev/null +++ b/tests/pos/i19637.scala @@ -0,0 +1,11 @@ +import java.util.stream.* +import java.util.function.* + +val map: java.util.Map[String, String] = Stream.of("1", "2", "3").collect(Collectors.toMap( + (s: String) => s, + Function.identity(), + { + case ("1", "1") => "1" + case (_, l) => l + } +)) diff --git a/tests/pos/i5700.scala b/tests/pos/i5700.scala index 69892dea16f4..89e8ca025c64 100644 --- a/tests/pos/i5700.scala +++ b/tests/pos/i5700.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/5700 +// https://github.com/scala/scala3/issues/5700 object noRecursionLimit: type M = { type T[+A]; type Ev >: T[Any] <: T[Nothing] } val M: M = ().asInstanceOf[M] diff --git a/tests/pos/i7414.scala b/tests/pos/i7414.scala index fd85ed2a2265..2c65b6cce466 100644 --- a/tests/pos/i7414.scala +++ b/tests/pos/i7414.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/7414 +// https://github.com/scala/scala3/issues/7414 object DepTest { trait Trait { diff --git a/tests/pos/i7445a.scala b/tests/pos/i7445a.scala index 2b54166de3f0..c23a5ebd12b9 100644 --- a/tests/pos/i7445a.scala +++ b/tests/pos/i7445a.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/7445 +// https://github.com/scala/scala3/issues/7445 object Main { type O1[A] = { diff --git a/tests/pos/i7445b.scala b/tests/pos/i7445b.scala index 1d49479ef0a5..0f6859fdb5c3 100644 --- a/tests/pos/i7445b.scala +++ b/tests/pos/i7445b.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/7445 +// https://github.com/scala/scala3/issues/7445 type O1[A] = { type OutInner[Ts] <: Tuple = Ts match { diff --git a/tests/pos/i7586.scala b/tests/pos/i7586.scala new file mode 100644 index 000000000000..364c99478337 --- /dev/null +++ b/tests/pos/i7586.scala @@ -0,0 +1,38 @@ + +trait Nat +case object Z extends Nat +case class S[N <: Nat](pred: N) extends Nat + +type Z = Z.type +given zero: Z = Z +given succ[N <: Nat](using n: N): S[N] = S(n) + +case class Sum[N <: Nat, M <: Nat, R <: Nat](result: R) + +given sumZ[N <: Nat](using n: N): Sum[Z, N, N] = Sum(n) +given sumS[N <: Nat, M <: Nat, R <: Nat]( + using sum: Sum[N, M, R] +): Sum[S[N], M, S[R]] = Sum(S(sum.result)) + +def add[N <: Nat, M <: Nat, R <: Nat](n: N, m: M)( + using sum: Sum[N, M, R] +): R = sum.result + +case class Prod[N <: Nat, M <: Nat, R <: Nat](result: R) + + +@main def Test: Unit = + + val n1: S[Z] = add(Z, S(Z)) + summon[n1.type <:< S[Z]] // OK + + val n3: S[S[S[Z]]] = add(S(S(Z)), S(Z)) + summon[n3.type <:< S[S[S[Z]]]] // Ok + + val m3_2 = add(S(Z), S(S(Z))) + summon[m3_2.type <:< S[S[S[Z]]]] // Error before changes: Cannot prove that (m3_2 : S[S[Nat]]) <:< S[S[S[Z]]] + + val m4_2 = add(S(Z), S(S(S(Z)))) + summon[m4_2.type <:< S[S[S[S[Z]]]]] + + diff --git a/tests/pos/i7653.scala b/tests/pos/i7653.scala index 8511b6eef69b..61c75634d10e 100644 --- a/tests/pos/i7653.scala +++ b/tests/pos/i7653.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/7653 +// https://github.com/scala/scala3/issues/7653 object options2 { type Option[T] = { diff --git a/tests/pos/i7790.scala b/tests/pos/i7790.scala index 0a0e2d2ce347..d2dfc5c892a4 100644 --- a/tests/pos/i7790.scala +++ b/tests/pos/i7790.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/7790 +// https://github.com/scala/scala3/issues/7790 trait Foo: given Int = 10 def map(f: Int ?=> Int) = f diff --git a/tests/pos/i7807.scala b/tests/pos/i7807.scala index df8a41ddcf8d..118ad77c58c4 100644 --- a/tests/pos/i7807.scala +++ b/tests/pos/i7807.scala @@ -11,6 +11,6 @@ object Test: val m: n.type match { case 0 => 1 case 1 => 0 } = flip(n) - // The following do not work, see discussion in https://github.com/lampepfl/dotty/pull/7835/files/6e60814e69be5c8d60265d4ce4bc1758863c23d8#r361741296: + // The following do not work, see discussion in https://github.com/scala/scala3/pull/7835/files/6e60814e69be5c8d60265d4ce4bc1758863c23d8#r361741296: // flip(m) // flip(flip(n)) diff --git a/tests/pos/i8300.scala b/tests/pos/i8300.scala index f106b24dbd1c..f4634f7cd520 100644 --- a/tests/pos/i8300.scala +++ b/tests/pos/i8300.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/8300 +// https://github.com/scala/scala3/issues/8300 type Bar[X] = X match { case List[a] => List[Tuple1[a]] diff --git a/tests/pos/invariant-cc.scala b/tests/pos/invariant-cc.scala new file mode 100644 index 000000000000..347b0d2fda64 --- /dev/null +++ b/tests/pos/invariant-cc.scala @@ -0,0 +1,18 @@ +import language.experimental.captureChecking +import scala.annotation.unchecked.uncheckedVariance + +trait IterableFactory[+CC[_]] extends Pure: + + def fill[A](n: Int)(elem: => A): CC[A]^{elem} = ??? + def fill[A](n1: Int, n2: Int)(elem: => A): CC[(CC[A]^{elem}) @uncheckedVariance]^{elem} = + fill[CC[A]^{elem}](n1)(fill(n2)(elem)) + fill(n1)(fill(n2)(elem)) + + def fill2[A](n: Int)(elem: () => A): CC[A]^{elem} = ??? + def fill2[A](n1: Int, n2: Int)(elem: () => A): CC[(CC[A]^{elem}) @uncheckedVariance]^{elem} = + fill2[CC[A]^{elem}](n1)(() => fill2(n2)(elem)) + fill2(n1)(() => fill2(n2)(elem)) + + + + diff --git a/tests/pos/kind-projector.scala b/tests/pos/kind-projector.scala index ff787d0111e2..4d6ec8c932a9 100644 --- a/tests/pos/kind-projector.scala +++ b/tests/pos/kind-projector.scala @@ -53,7 +53,7 @@ class BackticksAreFine6 extends FooPlus[BazPlus[Int => `-*`, `-*`, Int]] class BackticksAreFine7 extends Foo[λ[`-x` => BazPlus[x => `-*`, Int, x]]] class BackticksAreFine8 extends Foo[λ[`x` => BazPlus[x => `*`, Int, x]]] -// https://github.com/lampepfl/dotty/issues/13141 +// https://github.com/scala/scala3/issues/13141 // i13141 object A { class X { type Blah = Int } diff --git a/tests/pos/t12396/A_1.java b/tests/pos/t12396/A_1.java new file mode 100644 index 000000000000..a394d3a0a59d --- /dev/null +++ b/tests/pos/t12396/A_1.java @@ -0,0 +1,17 @@ +// test: -jvm 21+ + +public class A_1 { + public int f(Object s) { + switch(s) { + case Res.R -> { + return 1; + } + default -> { + return 3; + } + } + } + static enum Res { + R + } +} diff --git a/tests/pos/t12396/B_2.scala b/tests/pos/t12396/B_2.scala new file mode 100644 index 000000000000..662da7b3a575 --- /dev/null +++ b/tests/pos/t12396/B_2.scala @@ -0,0 +1,5 @@ +// test: -jvm 21+ + +class B { + def bar = (new A_1).f(null) +} diff --git a/tests/run-macros/annot-export/Macro_1.scala b/tests/run-macros/annot-export/Macro_1.scala new file mode 100644 index 000000000000..9a8267bfae4b --- /dev/null +++ b/tests/run-macros/annot-export/Macro_1.scala @@ -0,0 +1,13 @@ +import scala.annotation.{experimental, MacroAnnotation} +import scala.quoted._ +import scala.collection.mutable.Map + +@experimental +class returnClassName extends MacroAnnotation { + def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + import quotes.reflect._ + tree match + case DefDef(name, params, tpt, _) => + val rhs = Literal(StringConstant(Symbol.spliceOwner.name.stripSuffix("$"))) + List(DefDef.copy(tree)(name, params, tpt, Some(rhs))) +} diff --git a/tests/run-macros/annot-export/Test_2.scala b/tests/run-macros/annot-export/Test_2.scala new file mode 100644 index 000000000000..abae5716bc5d --- /dev/null +++ b/tests/run-macros/annot-export/Test_2.scala @@ -0,0 +1,10 @@ +object Bar: + @returnClassName + def f(): String = ??? // def f(): String = "Bar" + +object Baz: + export Bar.f // def f(): String = Bar.f(n) + +@main def Test = + assert(Bar.f() == "Bar") + assert(Baz.f() == "Bar") diff --git a/tests/run-macros/f-interpolator-tests.scala b/tests/run-macros/f-interpolator-tests.scala index 8c59ae19a187..e10301ad3115 100755 --- a/tests/run-macros/f-interpolator-tests.scala +++ b/tests/run-macros/f-interpolator-tests.scala @@ -2,7 +2,7 @@ * * The tests are sorted by argument category as the arguments are on https://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#detail * - * Some tests come from https://github.com/lampepfl/dotty/pull/3894/files + * Some tests come from https://github.com/scala/scala3/pull/3894/files */ object Test { def main(args: Array[String]) = { diff --git a/tests/run-staging/i11162.scala b/tests/run-staging/i11162.scala index 81db85f24274..d15e976611af 100644 --- a/tests/run-staging/i11162.scala +++ b/tests/run-staging/i11162.scala @@ -2,7 +2,7 @@ import scala.quoted.* object Test { - given staging.Compiler = staging.Compiler.make(getClass.getClassLoader) + given staging.Compiler = staging.Compiler.make(this.getClass.getClassLoader) def main(args: Array[String]): Unit = staging.run { diff --git a/tests/run-staging/i19170.scala b/tests/run-staging/i19170.scala new file mode 100644 index 000000000000..5462929f9302 --- /dev/null +++ b/tests/run-staging/i19170.scala @@ -0,0 +1,14 @@ +import scala.quoted.* + +given staging.Compiler = + object Dummy + staging.Compiler.make(Dummy.getClass.getClassLoader) + +class A(i: Int) + +def f(i: Expr[Int])(using Quotes): Expr[A] = { '{ new A($i) } } + +@main def Test = { + val g: Int => A = staging.run { '{ (i: Int) => ${ f('{i}) } } } + println(g(3)) +} diff --git a/tests/run-staging/i19170b.scala b/tests/run-staging/i19170b.scala new file mode 100644 index 000000000000..79d7e2db634f --- /dev/null +++ b/tests/run-staging/i19170b.scala @@ -0,0 +1,18 @@ +import scala.quoted.* + +given staging.Compiler = + staging.Compiler.make(getClass.getClassLoader) // warn: Suspicious top-level unqualified call to getClass + +class A(i: Int) + +def f(i: Expr[Int])(using Quotes): Expr[A] = { '{ new A($i) } } + +@main def Test = { + // The heuristic to give the extra information does not work on JDK 8 + if System.getProperty("java.specification.version") != "1.8" then + try + val g: Int => A = staging.run { '{ (i: Int) => ${ f('{i}) } } } + println(g(3)) + catch case ex: Exception => + assert(ex.getMessage().startsWith("`scala.quoted.staging.run` failed to load a class."), ex.getMessage()) +} diff --git a/tests/run-staging/i19176.scala b/tests/run-staging/i19176.scala new file mode 100644 index 000000000000..a8367074d48e --- /dev/null +++ b/tests/run-staging/i19176.scala @@ -0,0 +1,10 @@ +import scala.quoted.* + +given staging.Compiler = + object Dummy + staging.Compiler.make(Dummy.getClass.getClassLoader) + +class A +val f: (A, Int) => Int = staging.run { '{ (q: A, x: Int) => x } } + +@main def Test = f(new A, 3) diff --git a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala index 12ea8eb26c47..111c8c0bada3 100644 --- a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala @@ -51,6 +51,7 @@ val experimentalDefinitionInLibrary = Set( "scala.annotation.capability", "scala.annotation.retains", "scala.annotation.retainsByName", + "scala.annotation.retainsCap", "scala.Pure", "scala.caps", "scala.caps$", diff --git a/tests/run/i11583.scala b/tests/run/i11583.scala index 87701ac95310..fd4d63faa084 100644 --- a/tests/run/i11583.scala +++ b/tests/run/i11583.scala @@ -5,7 +5,7 @@ class Context: class Env: type Extra -// TODO: enable after https://github.com/lampepfl/dotty/issues/11700 is fixed +// TODO: enable after https://github.com/scala/scala3/issues/11700 is fixed // extension [Ctx <: Context](using ctx: Ctx)(tpe: ctx.Type)(using env: Env) // /** essentially: `extension (s: String) def &&:(b: Boolean)(i: Int)` // * but exercises the RefinedPrinter and safety of reordering parameters diff --git a/tests/run/i11706.scala b/tests/run/i11706.scala index 276ee408d266..f87f5697c35d 100644 --- a/tests/run/i11706.scala +++ b/tests/run/i11706.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/11706 +// https://github.com/scala/scala3/issues/11706 import scala.compiletime.erasedValue object Obj: diff --git a/tests/run/i12032.scala b/tests/run/i12032.scala index 52358332e2c8..867a485e8222 100644 --- a/tests/run/i12032.scala +++ b/tests/run/i12032.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/12032 +// https://github.com/scala/scala3/issues/12032 class Foo(val strings: Seq[String]) extends FooLowPriority trait FooLowPriority { self: Foo => diff --git a/tests/run/i13216.scala b/tests/run/i13216.scala index 174d0f200f31..59943672eac1 100644 --- a/tests/run/i13216.scala +++ b/tests/run/i13216.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/13216 +// https://github.com/scala/scala3/issues/13216 import scala.annotation.targetName class C(s: String) extends AnyVal { diff --git a/tests/run/i13334.scala b/tests/run/i13334.scala index 2ee0987c13cc..4443114443e0 100644 --- a/tests/run/i13334.scala +++ b/tests/run/i13334.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/13334 +// https://github.com/scala/scala3/issues/13334 trait DFC given DFC = new DFC {} diff --git a/tests/run/i13691b.scala b/tests/run/i13691b.scala index 1da726827467..eef09c38d431 100644 --- a/tests/run/i13691b.scala +++ b/tests/run/i13691b.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/13691 +// https://github.com/scala/scala3/issues/13691 import language.experimental.saferExceptions trait Decoder[+T]: diff --git a/tests/run/i14582.scala b/tests/run/i14582.scala index bce33aa170b2..1f4d26dccf8d 100644 --- a/tests/run/i14582.scala +++ b/tests/run/i14582.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/14582 +// https://github.com/scala/scala3/issues/14582 @main def Test() = val map = Map( "a" -> 1, diff --git a/tests/run/i15913.scala b/tests/run/i15913.scala index f3e98a3bfd6a..f3853e2f8cfe 100644 --- a/tests/run/i15913.scala +++ b/tests/run/i15913.scala @@ -1,4 +1,4 @@ -// https://github.com/lampepfl/dotty/issues/15913 +// https://github.com/lampepfl/scala/scala3/15913 class injector[F] diff --git a/tests/run/i16459.scala b/tests/run/i16459.scala new file mode 100644 index 000000000000..2964928d522c --- /dev/null +++ b/tests/run/i16459.scala @@ -0,0 +1,107 @@ +object Test { + import scala.xml.* + def main(args: Array[String]): Unit = { + + val xml = if(true) { + <script type="text/javascript"> + 'location.reload()' + 'foo bar' + </script> + } else <div>empty</div> + + assert( + xml match + case elm: Elem if + elm.label == "script" + && elm.child.length == 1 + && elm.child(0) == Atom(Text("\n 'location.reload()'\n 'foo bar'\n ")) + => true + case _ => false + , + xml + ) + // Scala 3 syntax + val auxiliary0 = if true then { + <script type="text/javascript"> + 'location.reload()' + 'foo bar' + </script> + } else <div>empty</div> + + val auxiliary1 = if true then + <script type="text/javascript"> + 'location.reload()' + 'foo bar' + </script> + else <div>empty</div> + + val auxiliary2 = if true then <div>A</div>else <div>B</div> + + // Note: + // This does not pass in Scala 2.12.18 and 2.13.12 + // due to "Sequence argument type annotation `: _*` cannot be used here:" + val auxiliary3 = if(true) <div>A</div>else <div>B</div> + + // Note: This passes in Scala 2.12.18 and 2.13.12 too. + val auxiliary4 = if(true) <div attr="...">A</div>else <div attr="...">B</div> + + // Pattern match without guard. + // Note: This passes in Scala 2.12.18 and 2.13.12 too. + val auxiliary5 = for (case _ @ <div>empty</div> <- Seq(xml)) yield () + // Note: These pass in Scala 2.12.18 and 2.13.12. + val auxiliary6 = for (case _ @ <div>empty</div><- Seq(xml)) yield () + val auxiliary7 = for (case _ @ <div>empty</div><-Seq(xml)) yield () + // Pattern match with if guard. + // Note: This passes in Scala 2.12.18 and 2.13.12 too. + val auxiliary8 = for (case _ @ <foo>FooBar</foo> <- Seq(xml) if true) + yield () + // Note: These pass in Scala 2.12.18 and 2.13.12. + val auxiliary9 = for (case _ @ <foo>FooBar</foo><- Seq(xml) if true) + yield () + val auxiliary10 = for (case _ @ <foo>FooBar</foo><-Seq(xml) if true) + yield () + + } + +} + +package scala.xml { + type MetaData = AnyRef + + class UnprefixedAttribute( + val key: String, + val value: Text, + next1: MetaData + ) extends MetaData + + trait NamespaceBinding + object TopScope extends NamespaceBinding + object Null + abstract class Node { + def label: String + def child: Seq[Node] + override def toString = label + child.mkString + } + + class Elem(prefix: String, val label: String, attributes1: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, val child: Node*) extends Node + object Elem { + def unapply(e:Elem):Option[(String,String,Any,Text,Any)] = Some(("dummy","dummy",null,null,null)) + } + class NodeBuffer extends Seq[Node] { + val nodes = scala.collection.mutable.ArrayBuffer.empty[Node] + def &+(o: Any): NodeBuffer = o match { + case n: Node => nodes.addOne(n) ; this + case t: Text => nodes.addOne(Atom(t)) ; this + } + // 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) + case class Atom(t: Text) extends Node { + def label = t.text + def child = Nil + } +} \ No newline at end of file diff --git a/tests/run/i17317-b.check b/tests/run/i17317-b.check new file mode 100644 index 000000000000..3b18e512dba7 --- /dev/null +++ b/tests/run/i17317-b.check @@ -0,0 +1 @@ +hello world diff --git a/tests/run/i17317-b.scala b/tests/run/i17317-b.scala new file mode 100644 index 000000000000..b1606da6df20 --- /dev/null +++ b/tests/run/i17317-b.scala @@ -0,0 +1,12 @@ +object foo { + object HelloGen { + println("hello world") + } + val Hello = HelloGen +} + +import foo.Hello + +object Test { + def main(args: Array[String]): Unit = Hello: Unit +} diff --git a/tests/run/i17317.check b/tests/run/i17317.check new file mode 100644 index 000000000000..3b18e512dba7 --- /dev/null +++ b/tests/run/i17317.check @@ -0,0 +1 @@ +hello world diff --git a/tests/run/i17317.scala b/tests/run/i17317.scala new file mode 100644 index 000000000000..41ea627c20b9 --- /dev/null +++ b/tests/run/i17317.scala @@ -0,0 +1,12 @@ +package object foo { + object HelloGen { + println("hello world") + } + val Hello = HelloGen +} + +import foo.Hello + +object Test { + def main(args: Array[String]): Unit = Hello: Unit +} diff --git a/tests/run/i17332.scala b/tests/run/i17332.scala new file mode 100644 index 000000000000..b609bf215d80 --- /dev/null +++ b/tests/run/i17332.scala @@ -0,0 +1,18 @@ +package foo { + +import annotation.static + +class MirrorHelpers + +object MirrorHelpers: + + @static + def throwStuff(i: Int): Any = throw new NoSuchElementException(String.valueOf(i)) + +} + +@main def Test = + try + foo.MirrorHelpers.throwStuff(23) + ??? // ko + catch case ex: NoSuchElementException if ex.getMessage == "23" => () // ok diff --git a/tests/run/i19394.scala b/tests/run/i19394.scala new file mode 100644 index 000000000000..7c6938c97503 --- /dev/null +++ b/tests/run/i19394.scala @@ -0,0 +1,20 @@ +import scala.annotation.{ static, targetName } + +class Foo +object Foo: + @static def foo: String = "foo" + @targetName("foo") def fooBincompat: String = foo + +class Bar +object Bar: + @static def bar: String = "bar" + def bar: String = bar + +object Test: + def main(args: Array[String]): Unit = + assert(Foo.foo == "foo") + assert(Bar.bar == "bar") + + import scala.reflect.Selectable.reflectiveSelectable + assert(Foo.asInstanceOf[{ def foo: String }].foo == "foo") + assert(Bar.asInstanceOf[{ def bar: String }].bar == "bar") diff --git a/tests/run/i19396.scala b/tests/run/i19396.scala new file mode 100644 index 000000000000..2fcf23022b0f --- /dev/null +++ b/tests/run/i19396.scala @@ -0,0 +1,16 @@ +import scala.annotation.static + +class Foo + +object Foo { + @static def foo = "foo" +} + +class Bar { + def bar = Foo.foo +} + +object Test: + def main(args: Array[String]): Unit = + Foo.foo + Bar().bar diff --git a/tests/run/i19641.scala b/tests/run/i19641.scala new file mode 100644 index 000000000000..3a3ef191aafc --- /dev/null +++ b/tests/run/i19641.scala @@ -0,0 +1,17 @@ +type DiagnosticConsturctor = (Int) => DiagnosticSet + +final class Diagnostic + +final class DiagnosticSet(elements: List[Diagnostic] = List()) + +enum Result: + case Success extends Result + case Failure(diagnose: DiagnosticConsturctor) extends Result + def diagnose(n: Int): DiagnosticSet = + this match + case Success => DiagnosticSet() + case Failure(d) => d(n) + +@main def Test(): Unit = + val r : Result = Result.Failure((n) => DiagnosticSet(List(Diagnostic()))) + r.diagnose(1) diff --git a/tests/run/i4192/TestCases.scala b/tests/run/i4192/TestCases.scala index 33b4e458ebe7..7935b57d7fc2 100644 --- a/tests/run/i4192/TestCases.scala +++ b/tests/run/i4192/TestCases.scala @@ -62,7 +62,7 @@ class A { topLevel => new AA object AB { - val nestedOnce = this // self alias cannot be used uniformly here: https://github.com/lampepfl/dotty/issues/11648 + val nestedOnce = this // self alias cannot be used uniformly here: https://github.com/scala/scala3/issues/11648 checkMember(this, topLevel) diff --git a/tests/run/i4364a.scala b/tests/run/i4364a.scala index 8bf62e545807..869e7dd6530e 100644 --- a/tests/run/i4364a.scala +++ b/tests/run/i4364a.scala @@ -6,8 +6,10 @@ object Test { def f(x: String): Unit = () def foo(c: Consumer[String]) = c.accept("") + def bar(c: String => Unit) = c("") def main(args: Array[String]) = { foo(f) + bar(f) } } diff --git a/tests/run/i4496b.scala b/tests/run/i4496b.scala index a6ed5b105e59..54459d15a8af 100644 --- a/tests/run/i4496b.scala +++ b/tests/run/i4496b.scala @@ -102,7 +102,7 @@ object Test { assert(consume(v) == 10) assert(consumeInl(v) == 10) assert(v.a == 10) - // Pending, per https://github.com/lampepfl/dotty/issues/4528. + // Pending, per https://github.com/scala/scala3/issues/4528. // v.a = 11 // assert(consume(v) == 11) // assert(consumeInl(v) == 11) diff --git a/tests/run/i8530.check b/tests/run/i8530.check index c8f75a704ff7..34749b91c683 100644 --- a/tests/run/i8530.check +++ b/tests/run/i8530.check @@ -3,3 +3,5 @@ MyBoooleanUnapply 3 (4,5) 5 +6 +7 diff --git a/tests/run/i8530.scala b/tests/run/i8530.scala index bbbc52587ee0..2ce24dc8e7ce 100644 --- a/tests/run/i8530.scala +++ b/tests/run/i8530.scala @@ -13,6 +13,12 @@ object MySeqUnapply: object MyWhiteboxUnapply: transparent inline def unapply(x: Int): Option[Any] = Some(x) +object MyWhiteboxUnapply1: + transparent inline def unapply(using DummyImplicit)(x: Int)(using DummyImplicit): Option[Any] = Some(x) + +object MyWhiteboxUnapply2: + transparent inline def unapply(using DummyImplicit)(using DummyImplicit)(x: Int)(using DummyImplicit)(using DummyImplicit): Option[Any] = Some(x) + @main def Test = 1 match @@ -30,4 +36,10 @@ object MyWhiteboxUnapply: 5 match case MyWhiteboxUnapply(x) => println(x: Int) + 6 match + case MyWhiteboxUnapply1(x) => println(x: Int) + + 7 match + case MyWhiteboxUnapply2(x) => println(x: Int) + end Test diff --git a/scala2-library-tasty-tests/src/Main.scala b/tests/run/scala2-library-test/Main.scala similarity index 92% rename from scala2-library-tasty-tests/src/Main.scala rename to tests/run/scala2-library-test/Main.scala index b33219271201..0629d5de6b7e 100644 --- a/scala2-library-tasty-tests/src/Main.scala +++ b/tests/run/scala2-library-test/Main.scala @@ -1,4 +1,5 @@ -package hello +// This tests language features that have a special handling in the Scala 2 library TASTy. +// These should behave the same way from if compiled against the Scala 2 library class files ot TASTy. import scala.util.* import scala.compiletime.testing.typeChecks @@ -6,7 +7,7 @@ import scala.compiletime.testing.typeChecks enum Color: case Red, Green, Blue -object HelloWorld: +object Test: def main(args: Array[String]): Unit = { println("hello 2.13 library bootstrapped") println(Color.Red) @@ -74,4 +75,4 @@ object HelloWorld: new collection.ArrayOps[String](Array[String]("foo")).exists(x => true) } -end HelloWorld +end Test diff --git a/scala2-library-tasty-tests/src/UnrolledBufferTest.scala b/tests/run/scala2-library-test/UnrolledBufferTest.scala similarity index 100% rename from scala2-library-tasty-tests/src/UnrolledBufferTest.scala rename to tests/run/scala2-library-test/UnrolledBufferTest.scala diff --git a/tests/run/static/i2054.scala b/tests/run/static/i2054.scala index dbf88b0efa14..84ebf5d9efeb 100644 --- a/tests/run/static/i2054.scala +++ b/tests/run/static/i2054.scala @@ -1,5 +1,3 @@ -// scalajs: --skip --pending - import scala.annotation.static class Test diff --git a/tests/semanticdb/expect/Advanced.expect.scala b/tests/semanticdb/expect/Advanced.expect.scala index d36fcd611eef..0078bde9a078 100644 --- a/tests/semanticdb/expect/Advanced.expect.scala +++ b/tests/semanticdb/expect/Advanced.expect.scala @@ -43,7 +43,7 @@ object Test/*<-advanced::Test.*/ { } } - // see: https://github.com/lampepfl/dotty/pull/14608#discussion_r835642563 + // see: https://github.com/scala/scala3/pull/14608#discussion_r835642563 lazy val foo/*<-advanced::Test.foo.*/: (reflect.Selectable/*->scala::reflect::Selectable#*/ { type A/*<-local16*/ = Int/*->scala::Int#*/ }) &/*->scala::`&`#*/ (reflect.Selectable/*->scala::reflect::Selectable#*/ { type A/*<-local17*/ = Int/*->scala::Int#*/; val a/*<-local18*/: A/*->local17*/ }) = ???/*->scala::Predef.`???`().*/ def bar/*<-advanced::Test.bar().*/: foo/*->advanced::Test.foo.*/.A/*->local17*/ = foo/*->advanced::Test.foo.*/.a/*->scala::reflect::Selectable#selectDynamic().*/ } diff --git a/tests/semanticdb/expect/Advanced.scala b/tests/semanticdb/expect/Advanced.scala index 8e0d2f3a1692..dffd122aa798 100644 --- a/tests/semanticdb/expect/Advanced.scala +++ b/tests/semanticdb/expect/Advanced.scala @@ -43,7 +43,7 @@ object Test { } } - // see: https://github.com/lampepfl/dotty/pull/14608#discussion_r835642563 + // see: https://github.com/scala/scala3/pull/14608#discussion_r835642563 lazy val foo: (reflect.Selectable { type A = Int }) & (reflect.Selectable { type A = Int; val a: A }) = ??? def bar: foo.A = foo.a } diff --git a/tests/semanticdb/expect/StructuralTypes.expect.scala b/tests/semanticdb/expect/StructuralTypes.expect.scala index 96c7181d6f10..98aaca95f880 100644 --- a/tests/semanticdb/expect/StructuralTypes.expect.scala +++ b/tests/semanticdb/expect/StructuralTypes.expect.scala @@ -16,7 +16,7 @@ object StructuralTypes/*<-example::StructuralTypes.*/: val V/*<-example::StructuralTypes.V.*/: Object/*->java::lang::Object#*/ { def scalameta/*<-local4*/: String/*->scala::Predef.String#*/ - } = /*<-local6*/new: - def scalameta/*<-local5*/ = "4.0" + } = new: + /*<-local6*/def scalameta/*<-local5*/ = "4.0" V/*->example::StructuralTypes.V.*/.scalameta/*->scala::reflect::Selectable#selectDynamic().*/ end StructuralTypes/*->example::StructuralTypes.*/ \ No newline at end of file diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index c8b652d85469..d1eabaa95bf7 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -44,11 +44,13 @@ Occurrences: Diagnostics: [3:14..3:16): [warning] unused private member -[4:16..4:16): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[4:16..4:16): [warning] 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. [4:20..4:22): [warning] unused private member -[7:18..7:18): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[7:18..7:18): [warning] 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. @@ -397,7 +399,7 @@ Diagnostics => 3 entries Synthetics => 2 entries Symbols: -example/Anonymous# => class Anonymous extends Object { self: Anonymous & Anonymous => +9 decls } +example/Anonymous# => class Anonymous extends Object { self: Anonymous => +9 decls } example/Anonymous#Bar# => trait Bar extends Object { self: Bar => +2 decls } example/Anonymous#Bar#`<init>`(). => primary ctor <init> (): Bar example/Anonymous#Bar#bar(). => abstract method bar => String @@ -817,11 +819,13 @@ Occurrences: Diagnostics: [18:9..18:10): [warning] unused explicit parameter -[20:23..20:23): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[20:23..20:23): [warning] 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. [20:27..20:28): [warning] unused explicit parameter -[22:23..22:23): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[22:23..22:23): [warning] 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. [22:27..22:28): [warning] unused explicit parameter @@ -3410,7 +3414,7 @@ local1 => selfparam self: B local2 => selfparam self: B & C1 selfs/B# => class B extends Object { self: B => +1 decls } selfs/B#`<init>`(). => primary ctor <init> (): B -selfs/C1# => class C1 extends B { self: C1 & C1 => +1 decls } +selfs/C1# => class C1 extends B { self: C1 => +1 decls } selfs/C1#`<init>`(). => primary ctor <init> (): C1 selfs/C2# => class C2 extends B { self: B & C2 => +1 decls } selfs/C2#`<init>`(). => primary ctor <init> (): C2 @@ -3503,7 +3507,7 @@ Occurrences: [16:9..16:15): Object -> java/lang/Object# [17:8..17:17): scalameta <- local4 [17:19..17:25): String -> scala/Predef.String# -[18:6..18:6): <- local6 +[19:4..19:4): <- local6 [19:8..19:17): scalameta <- local5 [20:2..20:3): V -> example/StructuralTypes.V. [20:4..20:13): scalameta -> scala/reflect/Selectable#selectDynamic(). @@ -4129,16 +4133,20 @@ Occurrences: Diagnostics: [2:20..2:21): [warning] unused explicit parameter -[5:16..5:16): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[5:16..5:16): [warning] 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. -[7:16..7:16): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[7:16..7:16): [warning] 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. -[12:16..12:16): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[12:16..12:16): [warning] 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. -[13:16..13:16): [warning] The [this] qualifier will be deprecated in the future; it should be dropped. +[13:16..13:16): [warning] 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. diff --git a/tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala b/tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala new file mode 100644 index 000000000000..45e3b8a405c7 --- /dev/null +++ b/tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala @@ -0,0 +1,58 @@ +package org.scalajs.testsuite.jsinterop + +import scala.language.dynamics + +import org.junit.Assert.* +import org.junit.Test + +import scala.scalajs.js +import scala.scalajs.js.annotation.* + +class CustomDynamicTestScala3 { + import CustomDynamicTestScala3.* + + @Test + def testCustomDynamicClass_Issue19528(): Unit = { + val obj = new CustomDynamicClass() + + assertEquals(false, obj.hasOwnProperty("foo")) + obj.foo = "bar" + assertEquals("bar", obj.foo) + assertEquals(true, obj.hasOwnProperty("foo")) + } + + @Test + def testCustomDynamicTrait_Issue19528(): Unit = { + val obj = new js.Object().asInstanceOf[CustomDynamicTrait] + + assertEquals(false, obj.hasOwnProperty("foo")) + obj.foo = "bar" + assertEquals("bar", obj.foo) + assertEquals(true, obj.hasOwnProperty("foo")) + } +} + +object CustomDynamicTestScala3 { + @js.native + @JSGlobal("Object") + class CustomDynamicClass extends js.Any with Dynamic { + @JSBracketAccess + def selectDynamic(name: String): js.Any = js.native + @JSBracketAccess + def updateDynamic(name: String)(value: js.Any): Unit = js.native + + @JSBracketCall + def applyDynamic(name: String)(args: js.Any*): js.Any = js.native + } + + @js.native + trait CustomDynamicTrait extends js.Any with Dynamic { + @JSBracketAccess + def selectDynamic(name: String): js.Any = js.native + @JSBracketAccess + def updateDynamic(name: String)(value: js.Any): Unit = js.native + + @JSBracketCall + def applyDynamic(name: String)(args: js.Any*): js.Any = js.native + } +} diff --git a/tests/warn/14034b.scala b/tests/warn/14034b.scala new file mode 100644 index 000000000000..fdef353f7aca --- /dev/null +++ b/tests/warn/14034b.scala @@ -0,0 +1,15 @@ +//> using options -deprecation + +@deprecated trait Exp +@deprecated val exp = 1 + +def test1 = exp // warn +def test2(a: Exp) = () // warn + +type Foo0 = Exp // warn +type Foo = Option[Exp] // warn +type Bar = Option[exp.type] // warn +type Baz = Exp | Int // warn +type Quux = [X] =>> X match + case Exp => Int // warn +type Quuz[A <: Exp] = Int // warn \ No newline at end of file diff --git a/tests/neg/15981.check b/tests/warn/15981.check similarity index 68% rename from tests/neg/15981.check rename to tests/warn/15981.check index 10745839c566..6cc57d86385f 100644 --- a/tests/neg/15981.check +++ b/tests/warn/15981.check @@ -1,5 +1,5 @@ --- [E092] Pattern Match Error: tests/neg/15981.scala:4:45 -------------------------------------------------------------- -4 | override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // error +-- [E092] Pattern Match Unchecked Warning: tests/warn/15981.scala:4:45 ------------------------------------------------- +4 | override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // warn | ^^^ | the type test for PosInt cannot be checked at runtime because it's a local class | diff --git a/tests/neg/15981.scala b/tests/warn/15981.scala similarity index 76% rename from tests/neg/15981.scala rename to tests/warn/15981.scala index 5aba3555c010..a52da28c8462 100644 --- a/tests/neg/15981.scala +++ b/tests/warn/15981.scala @@ -1,6 +1,6 @@ -//> using options -Werror + val _ = locally{ sealed abstract class PosInt(val value: Int) { - override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // error + override def equals(any: Any): Boolean = any.isInstanceOf[PosInt] // warn } } diff --git a/tests/neg/17284.check b/tests/warn/17284.check similarity index 86% rename from tests/neg/17284.check rename to tests/warn/17284.check index fa248c598311..47df2d21e3a7 100644 --- a/tests/neg/17284.check +++ b/tests/warn/17284.check @@ -1,5 +1,5 @@ --- [E187] Potential Issue Error: tests/neg/17284.scala:4:6 ------------------------------------------------------------- -4 | 451.synchronized {} // error +-- [E187] Potential Issue Warning: tests/warn/17284.scala:4:6 ---------------------------------------------------------- +4 | 451.synchronized {} // warn | ^^^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |--------------------------------------------------------------------------------------------------------------------- @@ -8,8 +8,8 @@ | You called the synchronized method on a boxed primitive. This might not be what | you intended. --------------------------------------------------------------------------------------------------------------------- --- [E187] Potential Issue Error: tests/neg/17284.scala:8:4 ------------------------------------------------------------- -8 | x.synchronized {} // error +-- [E187] Potential Issue Warning: tests/warn/17284.scala:8:4 ---------------------------------------------------------- +8 | x.synchronized {} // warn | ^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |--------------------------------------------------------------------------------------------------------------------- @@ -18,8 +18,8 @@ | You called the synchronized method on a boxed primitive. This might not be what | you intended. --------------------------------------------------------------------------------------------------------------------- --- [E187] Potential Issue Error: tests/neg/17284.scala:11:7 ------------------------------------------------------------ -11 | true.synchronized {} // error +-- [E187] Potential Issue Warning: tests/warn/17284.scala:11:7 --------------------------------------------------------- +11 | true.synchronized {} // warn | ^^^^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |-------------------------------------------------------------------------------------------------------------------- diff --git a/tests/warn/17284.scala b/tests/warn/17284.scala new file mode 100644 index 000000000000..c30e8cb478ec --- /dev/null +++ b/tests/warn/17284.scala @@ -0,0 +1,14 @@ +//> using options -explain + +def test = + 451.synchronized {} // warn + +def test2 = + val x: Integer = 451 + x.synchronized {} // warn + +def test3 = + true.synchronized {} // warn + +def test4 = + true.hashCode() // success \ No newline at end of file diff --git a/tests/neg-deep-subtype/1828.scala b/tests/warn/1828.scala similarity index 69% rename from tests/neg-deep-subtype/1828.scala rename to tests/warn/1828.scala index ae228a83e898..2231967a53e0 100644 --- a/tests/neg-deep-subtype/1828.scala +++ b/tests/warn/1828.scala @@ -1,8 +1,8 @@ -//> using options -Xfatal-warnings + class Test { def remove[S](a: S | Int, f: Int => S):S = a match { - case a: S => a // error + case a: S => a // warn case a: Int => f(a) } diff --git a/tests/warn/18493.check b/tests/warn/18493.check new file mode 100644 index 000000000000..64f2e2aac735 --- /dev/null +++ b/tests/warn/18493.check @@ -0,0 +1,8 @@ +-- [E030] Match case Unreachable Warning: tests/warn/18493.scala:6:9 --------------------------------------------------- +6 | case "abc" => // warn + | ^^^^^ + | Unreachable case +-- [E030] Match case Unreachable Warning: tests/warn/18493.scala:12:9 -------------------------------------------------- +12 | case "abc" => // warn + | ^^^^^ + | Unreachable case diff --git a/tests/neg/18493.scala b/tests/warn/18493.scala similarity index 68% rename from tests/neg/18493.scala rename to tests/warn/18493.scala index 8dfb3bf923cc..d3ca292a346e 100644 --- a/tests/neg/18493.scala +++ b/tests/warn/18493.scala @@ -1,14 +1,14 @@ -//> using options -Werror + object PartialFunctionNoWarning { // nice warning "abc" match { case "abc" => - case "abc" => // error + case "abc" => // warn } // no warnings val pf: PartialFunction[String, Unit] = { case "abc" => - case "abc" => // error + case "abc" => // warn } } \ No newline at end of file diff --git a/tests/warn/3324b.scala b/tests/warn/3324b.scala new file mode 100644 index 000000000000..9a2011d18012 --- /dev/null +++ b/tests/warn/3324b.scala @@ -0,0 +1,11 @@ + + +class C[T] { + val x: Any = ??? + if (x.isInstanceOf[List[String]]) // warn: unchecked + if (x.isInstanceOf[T]) // warn: unchecked + x match { + case x: List[String] => // warn: unchecked + case x: T => // warn: unchecked + } +} \ No newline at end of file diff --git a/tests/warn/3324f.scala b/tests/warn/3324f.scala new file mode 100644 index 000000000000..86af918b0d5a --- /dev/null +++ b/tests/warn/3324f.scala @@ -0,0 +1,11 @@ + + +trait C[T] +class D[T] + +class Test { + def foo[T](x: C[T]) = x match { + case _: D[T] => // warn + case _: C[Int] => // warn + } +} \ No newline at end of file diff --git a/tests/neg-deep-subtype/3324g.scala b/tests/warn/3324g.scala similarity index 73% rename from tests/neg-deep-subtype/3324g.scala rename to tests/warn/3324g.scala index a5b842e4e450..23ff4b3d23f9 100644 --- a/tests/neg-deep-subtype/3324g.scala +++ b/tests/warn/3324g.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + class Test { trait A[+T] @@ -6,7 +6,7 @@ class Test { class C[T] extends B[Any] with A[T] def foo[T](c: C[T]): Unit = c match { - case _: B[T] => // error + case _: B[T] => // warn } def bar[T](b: B[T]): Unit = b match { @@ -14,8 +14,8 @@ class Test { } def quux[T](a: A[T]): Unit = a match { - case _: B[T] => // error!! + case _: B[T] => // warn!! } quux(new C[Int]) -} +} \ No newline at end of file diff --git a/tests/neg/IsInstanceOfClassTag2.scala b/tests/warn/IsInstanceOfClassTag2.scala similarity index 80% rename from tests/neg/IsInstanceOfClassTag2.scala rename to tests/warn/IsInstanceOfClassTag2.scala index 9d32ee401092..5ca8a8c91765 100644 --- a/tests/neg/IsInstanceOfClassTag2.scala +++ b/tests/warn/IsInstanceOfClassTag2.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -11,7 +11,7 @@ object IsInstanceOfClassTag { } def main(args: Array[String]): Unit = { - safeCast[List[String]](List[Int](1)) match { // error + safeCast[List[String]](List[Int](1)) match { // warn case None => case Some(xs) => } @@ -22,3 +22,4 @@ object IsInstanceOfClassTag { } } } + diff --git a/tests/neg-deep-subtype/JavaSeqLiteral.scala b/tests/warn/JavaSeqLiteral.scala similarity index 82% rename from tests/neg-deep-subtype/JavaSeqLiteral.scala rename to tests/warn/JavaSeqLiteral.scala index 6003731ae657..9652a9fa502c 100644 --- a/tests/neg-deep-subtype/JavaSeqLiteral.scala +++ b/tests/warn/JavaSeqLiteral.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + object Test1 { trait Tree[-T] @@ -10,7 +10,7 @@ object Test1 { class DummyTree extends JavaSeqLiteral[Any] def foo1(tree: Tree[Type]) = - tree.isInstanceOf[JavaSeqLiteral[Type]] // error + tree.isInstanceOf[JavaSeqLiteral[Type]] // warn foo1(new DummyTree) } @@ -28,4 +28,4 @@ object Test2 { tree.isInstanceOf[JavaSeqLiteral[Type]] foo1(new DummyTree) -} \ No newline at end of file +} diff --git a/tests/neg/alphanumeric-infix-operator-3.4.scala b/tests/warn/alphanumeric-infix-operator-3.4.scala similarity index 63% rename from tests/neg/alphanumeric-infix-operator-3.4.scala rename to tests/warn/alphanumeric-infix-operator-3.4.scala index 14d3358127ca..1ea3d42f4ccd 100644 --- a/tests/neg/alphanumeric-infix-operator-3.4.scala +++ b/tests/warn/alphanumeric-infix-operator-3.4.scala @@ -1,5 +1,3 @@ -//> using options -Werror - import language.`3.4` class Foo: @@ -7,5 +5,5 @@ class Foo: infix def y(i: Int) = i def test(foo: Foo): Unit = - foo x 1 // error (because it was compiled with 3.4+) + foo x 1 // warn (because it was compiled with 3.4+) foo y 2 // ok: is marked as infix diff --git a/tests/neg/alphanumeric-infix-operator.check b/tests/warn/alphanumeric-infix-operator.check similarity index 72% rename from tests/neg/alphanumeric-infix-operator.check rename to tests/warn/alphanumeric-infix-operator.check index 52b08f16b88c..b35cfff793e2 100644 --- a/tests/neg/alphanumeric-infix-operator.check +++ b/tests/warn/alphanumeric-infix-operator.check @@ -1,5 +1,5 @@ --- Error: tests/neg/alphanumeric-infix-operator.scala:8:6 -------------------------------------------------------------- -8 | foo x 1 // error (because it was compiled with 3.4+) +-- Warning: tests/warn/alphanumeric-infix-operator.scala:6:6 ----------------------------------------------------------- +6 | foo x 1 // warn (because it was compiled with 3.4+) | ^ | Alphanumeric method x is not declared infix; it should not be used as infix operator. | Instead, use method syntax .x(...) or backticked identifier `x`. diff --git a/tests/neg/alphanumeric-infix-operator.scala b/tests/warn/alphanumeric-infix-operator.scala similarity index 59% rename from tests/neg/alphanumeric-infix-operator.scala rename to tests/warn/alphanumeric-infix-operator.scala index 1f2233dda6ce..ceba6174d312 100644 --- a/tests/neg/alphanumeric-infix-operator.scala +++ b/tests/warn/alphanumeric-infix-operator.scala @@ -1,9 +1,7 @@ -//> using options -Werror - class Foo: def x(i: Int) = i infix def y(i: Int) = i def test(foo: Foo): Unit = - foo x 1 // error (because it was compiled with 3.4+) + foo x 1 // warn (because it was compiled with 3.4+) foo y 2 // ok: is marked as infix diff --git a/tests/warn/avoid-warn-deprecation.scala b/tests/warn/avoid-warn-deprecation.scala new file mode 100644 index 000000000000..364added5e8a --- /dev/null +++ b/tests/warn/avoid-warn-deprecation.scala @@ -0,0 +1,11 @@ +//> using options -feature + +object A { + @deprecated("use bar instead of this one", "0.2.3") + def foo: Int = 3 +} + +object B { + A.foo +} +// nopos-warn there was 1 deprecation warning; re-run with -deprecation for details \ No newline at end of file diff --git a/tests/neg-deep-subtype/conditionalWarnings.scala b/tests/warn/conditionalWarnings.scala similarity index 75% rename from tests/neg-deep-subtype/conditionalWarnings.scala rename to tests/warn/conditionalWarnings.scala index c4757cbb7546..5ab63c263abf 100644 --- a/tests/neg-deep-subtype/conditionalWarnings.scala +++ b/tests/warn/conditionalWarnings.scala @@ -1,15 +1,15 @@ -//> using options -deprecation -Xfatal-warnings +//> using options -deprecation object Test { @deprecated def foo = ??? given Conversion[String, Int] = _.length - foo // error + foo // warn val x: Int = "abc" // OK, since -feature warnings are not enabled. // The program compiles with final line // there was 1 feature warning; re-run with -feature for details - // nopos-error -} + // nopos-warn +} \ No newline at end of file diff --git a/tests/neg/convertible.scala b/tests/warn/convertible.scala similarity index 60% rename from tests/neg/convertible.scala rename to tests/warn/convertible.scala index e72de452f41d..c98006ecdc9b 100644 --- a/tests/neg/convertible.scala +++ b/tests/warn/convertible.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -feature +//> using options -feature import language.experimental.into @@ -11,9 +11,9 @@ object Test: def f(x: Text, y: => Text, zs: Text*) = println(s"${x.str} ${y.str} ${zs.map(_.str).mkString(" ")}") - f("abc", "def") // error // error - f("abc", "def", "xyz", "uvw") // error // error // error // error - f("abc", "def", "xyz", Text("uvw")) // error // error // error + f("abc", "def") // warn // warn + f("abc", "def", "xyz", "uvw") // warn // warn // warn // warn + f("abc", "def", "xyz", Text("uvw")) // warn // warn // warn def g(x: into Text) = println(x.str) @@ -27,5 +27,4 @@ object Test: def h(x: into Text) = val y = h1(x) - y("abc") // error, inference through type variable does not propagate - + y("abc") // warn, inference through type variable does not propagate \ No newline at end of file diff --git a/tests/neg/deprecated-override.scala b/tests/warn/deprecated-override.scala similarity index 52% rename from tests/neg/deprecated-override.scala rename to tests/warn/deprecated-override.scala index b532416c7126..2d0b0ceb4aea 100644 --- a/tests/neg/deprecated-override.scala +++ b/tests/warn/deprecated-override.scala @@ -1,4 +1,4 @@ -//> using options -source future -deprecation -Xfatal-warnings +//> using options -source future -deprecation trait A: def f: Int @@ -7,10 +7,9 @@ class B extends A: @deprecatedOverriding def f = 1 class C extends B: - override def f = 2 // error + override def f = 2 // warn trait D extends A: override def f = 3 -object E extends B, D // error - +object E extends B, D // warn \ No newline at end of file diff --git a/tests/neg/feature-shadowing.scala b/tests/warn/feature-shadowing.scala similarity index 77% rename from tests/neg/feature-shadowing.scala rename to tests/warn/feature-shadowing.scala index 16286d5eea87..301f24b241f7 100644 --- a/tests/neg/feature-shadowing.scala +++ b/tests/warn/feature-shadowing.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -feature +//> using options -feature import language.implicitConversions given Conversion[Int, String] = _.toString @@ -8,7 +8,7 @@ object a: object b: import language.implicitConversions as _ - val s: String = 2 // error + val s: String = 2 // warn object c: import language.implicitConversions diff --git a/tests/neg/gadt-contradictory-pattern.scala b/tests/warn/gadt-contradictory-pattern.scala similarity index 54% rename from tests/neg/gadt-contradictory-pattern.scala rename to tests/warn/gadt-contradictory-pattern.scala index 6fbd06120a48..5d85b23653db 100644 --- a/tests/neg/gadt-contradictory-pattern.scala +++ b/tests/warn/gadt-contradictory-pattern.scala @@ -1,14 +1,14 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns object Test { sealed abstract class Foo[T] case object Bar1 extends Foo[Int] case object Bar2 extends Foo[String] case object Bar3 extends Foo[AnyRef] - def fail4[T <: AnyRef](xx: (Foo[T], Foo[T])) = xx match { - case (Bar1, Bar1) => () // error // error + def fail4[T <: AnyRef](xx: (Foo[T], Foo[T])) = xx match { // warn match may not be exhaustive + case (Bar1, Bar1) => () // warn // warn case (Bar2, Bar3) => () case (Bar3, _) => () } -} +} \ No newline at end of file diff --git a/tests/neg-deep-subtype/gadt.scala b/tests/warn/gadt.scala similarity index 68% rename from tests/neg-deep-subtype/gadt.scala rename to tests/warn/gadt.scala index 661c04fef373..9d7b81220284 100644 --- a/tests/neg-deep-subtype/gadt.scala +++ b/tests/warn/gadt.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + class Test { trait A[+T] @@ -8,8 +8,8 @@ class Test { class D extends C def quux(a: A[C]): Unit = a match { - case _: B[C] => // error!! + case _: B[C] => // warn } quux(new B[D]) -} \ No newline at end of file +} diff --git a/tests/neg-deep-subtype/html.scala b/tests/warn/html.scala similarity index 87% rename from tests/neg-deep-subtype/html.scala rename to tests/warn/html.scala index f17cfb661505..98189c1bf2cb 100644 --- a/tests/neg-deep-subtype/html.scala +++ b/tests/warn/html.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + object HTML: type AttrArg = AppliedAttr | Seq[AppliedAttr] @@ -12,7 +12,7 @@ object HTML: attrs.filter(_ != Nil).foreach{ case s: Seq[AppliedAttr] => s.foreach(sb.append(" ").append) - case s: Seq[Int] => // error + case s: Seq[Int] => // warn case e: AppliedAttr => sb.append(" ").append(e) } diff --git a/tests/warn/i10247.scala b/tests/warn/i10247.scala new file mode 100644 index 000000000000..aa344362cac2 --- /dev/null +++ b/tests/warn/i10247.scala @@ -0,0 +1,28 @@ +//> using options -deprecation + +def usered = Color.Red // warn: value Red is deprecated + +object DeprecatedContainer { + @deprecated("no foo", "0.1") val foo = 23 +} + +enum Day { + + @deprecated("no more Mondays!", "0.1") case Monday + +} + +enum Color { + + @deprecated("no Red", "0.1") case Red + + @deprecated("no Generic", "0.1") case Generic(rgb: Int) + + def useFoo1 = DeprecatedContainer.foo // warn // check that only enum cases are avoided + def useMonday = Day.Monday // warn // check that enum cases are declared in this enum + +} + +object Color { + def useFoo2 = DeprecatedContainer.foo // warn // check that only enum cases are avoided +} \ No newline at end of file diff --git a/tests/warn/i10930.scala b/tests/warn/i10930.scala new file mode 100644 index 000000000000..5d88235d0951 --- /dev/null +++ b/tests/warn/i10930.scala @@ -0,0 +1,15 @@ + + +import language.future +@main def Test = + type LeafElem[X] = X match + case String => Char + case Array[t] => LeafElem[t] + case Iterable[t] => LeafElem[t] + case AnyVal => X + + def leafElem[X](x: X): LeafElem[X] = x match + case x: String => x.charAt(0) // warn + case x: Array[t] => leafElem(x(1)) // warn + case x: Iterable[t] => leafElem(x.head) // warn + case x: AnyVal => x // warn \ No newline at end of file diff --git a/tests/warn/i10994.scala b/tests/warn/i10994.scala new file mode 100644 index 000000000000..74fe3bba3778 --- /dev/null +++ b/tests/warn/i10994.scala @@ -0,0 +1,5 @@ + + +def foo = true match + case (b: Boolean): Boolean => () // warn + diff --git a/tests/warn/i11022.check b/tests/warn/i11022.check new file mode 100644 index 000000000000..4257bb64652c --- /dev/null +++ b/tests/warn/i11022.check @@ -0,0 +1,20 @@ +-- Deprecation Warning: tests/warn/i11022.scala:10:7 ------------------------------------------------------------------- +10 |val a: CaseClass = CaseClass(42) // warn: deprecated type // warn: deprecated apply method + | ^^^^^^^^^ + | class CaseClass is deprecated: no CaseClass +-- Deprecation Warning: tests/warn/i11022.scala:10:19 ------------------------------------------------------------------ +10 |val a: CaseClass = CaseClass(42) // warn: deprecated type // warn: deprecated apply method + | ^^^^^^^^^ + | class CaseClass is deprecated: no CaseClass +-- Deprecation Warning: tests/warn/i11022.scala:11:7 ------------------------------------------------------------------- +11 |val b: CaseClass = new CaseClass(42) // warn: deprecated type // warn: deprecated class + | ^^^^^^^^^ + | class CaseClass is deprecated: no CaseClass +-- Deprecation Warning: tests/warn/i11022.scala:11:23 ------------------------------------------------------------------ +11 |val b: CaseClass = new CaseClass(42) // warn: deprecated type // warn: deprecated class + | ^^^^^^^^^ + | class CaseClass is deprecated: no CaseClass +-- Deprecation Warning: tests/warn/i11022.scala:12:14 ------------------------------------------------------------------ +12 |val c: Unit = CaseClass(42).magic() // warn: deprecated apply method + | ^^^^^^^^^ + | class CaseClass is deprecated: no CaseClass diff --git a/tests/warn/i11022.scala b/tests/warn/i11022.scala new file mode 100644 index 000000000000..8e2de9d8f519 --- /dev/null +++ b/tests/warn/i11022.scala @@ -0,0 +1,13 @@ +//> using options -deprecation + +@deprecated("no CaseClass") +case class CaseClass(rgb: Int): + def magic(): Unit = () + +object CaseClass: + def notDeprecated(): Unit = () + +val a: CaseClass = CaseClass(42) // warn: deprecated type // warn: deprecated apply method +val b: CaseClass = new CaseClass(42) // warn: deprecated type // warn: deprecated class +val c: Unit = CaseClass(42).magic() // warn: deprecated apply method +val d: Unit = CaseClass.notDeprecated() // compiles \ No newline at end of file diff --git a/tests/neg/i11097.scala b/tests/warn/i11097.scala similarity index 89% rename from tests/neg/i11097.scala rename to tests/warn/i11097.scala index 149fe89249c8..51c02a627a15 100644 --- a/tests/neg/i11097.scala +++ b/tests/warn/i11097.scala @@ -1,12 +1,12 @@ -//> using options -Xfatal-warnings + @main def test: Unit = { class C { type T1; type T2 } def pmatch(s: C): s.T2 = s match { - case p: (C { type T1 = Int; type T2 >: T1 } & s.type) => // error + case p: (C { type T1 = Int; type T2 >: T1 } & s.type) => // warn (3: p.T1): p.T2 - case p: (C { type T1 = String; type T2 >: T1 } & s.type) => // error + case p: (C { type T1 = String; type T2 >: T1 } & s.type) => // warn ("this branch should be matched": p.T1): p.T2 } diff --git a/tests/warn/i11333.check b/tests/warn/i11333.check new file mode 100644 index 000000000000..df22502cc649 --- /dev/null +++ b/tests/warn/i11333.check @@ -0,0 +1,30 @@ +-- [E167] Lossy Conversion Warning: tests/warn/i11333.scala:4:19 ------------------------------------------------------- +4 | val f1: Float = 123456789 // warn + | ^^^^^^^^^ + | Widening conversion from Int to Float loses precision. + | Write `.toFloat` instead. +-- [E167] Lossy Conversion Warning: tests/warn/i11333.scala:5:19 ------------------------------------------------------- +5 | val d1: Double = 1234567890123456789L // warn + | ^^^^^^^^^^^^^^^^^^^^ + | Widening conversion from Long to Double loses precision. + | Write `.toDouble` instead. +-- [E167] Lossy Conversion Warning: tests/warn/i11333.scala:6:19 ------------------------------------------------------- +6 | val f2: Float = 123456789L // warn + | ^^^^^^^^^^ + | Widening conversion from Long to Float loses precision. + | Write `.toFloat` instead. +-- [E167] Lossy Conversion Warning: tests/warn/i11333.scala:12:21 ------------------------------------------------------ +12 | val f1_b: Float = i1 // warn + | ^^ + | Widening conversion from Int to Float loses precision. + | Write `.toFloat` instead. +-- [E167] Lossy Conversion Warning: tests/warn/i11333.scala:13:21 ------------------------------------------------------ +13 | val d1_b: Double = l1 // warn + | ^^ + | Widening conversion from Long to Double loses precision. + | Write `.toDouble` instead. +-- [E167] Lossy Conversion Warning: tests/warn/i11333.scala:14:21 ------------------------------------------------------ +14 | val f2_b: Float = l2 // warn + | ^^ + | Widening conversion from Long to Float loses precision. + | Write `.toFloat` instead. diff --git a/tests/warn/i11333.scala b/tests/warn/i11333.scala new file mode 100644 index 000000000000..210916b30aaf --- /dev/null +++ b/tests/warn/i11333.scala @@ -0,0 +1,14 @@ + + +class C: + val f1: Float = 123456789 // warn + val d1: Double = 1234567890123456789L // warn + val f2: Float = 123456789L // warn + + inline val i1 = 123456789 + inline val l1 = 1234567890123456789L + inline val l2 = 123456789L + + val f1_b: Float = i1 // warn + val d1_b: Double = l1 // warn + val f2_b: Float = l2 // warn \ No newline at end of file diff --git a/tests/neg/i11344.scala b/tests/warn/i11344.scala similarity index 73% rename from tests/neg/i11344.scala rename to tests/warn/i11344.scala index 0602fe14a995..f8af81369162 100644 --- a/tests/neg/i11344.scala +++ b/tests/warn/i11344.scala @@ -1,8 +1,9 @@ -//> using options -Xfatal-warnings -deprecation +//> using options -deprecation trait Pet(val name: String, rest: Int): def f(suffix: String) = s"$name$suffix$rest" -class Birdie(override val name: String) extends Pet("huh", 1) // error +class Birdie(override val name: String) extends Pet("huh", 1) // warn + diff --git a/tests/warn/i11963a.scala b/tests/warn/i11963a.scala new file mode 100644 index 000000000000..b6743d92a4ac --- /dev/null +++ b/tests/warn/i11963a.scala @@ -0,0 +1,4 @@ + + +open trait Foo // warn + diff --git a/tests/warn/i11963b.scala b/tests/warn/i11963b.scala new file mode 100644 index 000000000000..5868e6979214 --- /dev/null +++ b/tests/warn/i11963b.scala @@ -0,0 +1,4 @@ + + +open abstract class Foo // warn + diff --git a/tests/warn/i11963c.scala b/tests/warn/i11963c.scala new file mode 100644 index 000000000000..245b436ee1e9 --- /dev/null +++ b/tests/warn/i11963c.scala @@ -0,0 +1,8 @@ + + +object Test { + def foo: Any = { + open class Bar // warn + new Bar + } +} diff --git a/tests/neg/i12253.check b/tests/warn/i12253.check similarity index 69% rename from tests/neg/i12253.check rename to tests/warn/i12253.check index 75a698249dee..e33a6214a438 100644 --- a/tests/neg/i12253.check +++ b/tests/warn/i12253.check @@ -1,11 +1,11 @@ --- [E092] Pattern Match Error: tests/neg/i12253.scala:13:10 ------------------------------------------------------------ -13 | case extractors.InlinedLambda(_, Select(_, name)) => Expr(name) // error // error +-- [E092] Pattern Match Unchecked Warning: tests/warn/i12253.scala:13:10 ----------------------------------------------- +13 | case extractors.InlinedLambda(_, Select(_, name)) => Expr(name) // warn // warn | ^ |the type test for extractors.q2.reflect.Term cannot be checked at runtime because it refers to an abstract type member or type parameter | | longer explanation available when compiling with `-explain` --- [E092] Pattern Match Error: tests/neg/i12253.scala:13:38 ------------------------------------------------------------ -13 | case extractors.InlinedLambda(_, Select(_, name)) => Expr(name) // error // error +-- [E092] Pattern Match Unchecked Warning: tests/warn/i12253.scala:13:38 ----------------------------------------------- +13 | case extractors.InlinedLambda(_, Select(_, name)) => Expr(name) // warn // warn | ^ |the type test for q1.reflect.Select cannot be checked at runtime because it refers to an abstract type member or type parameter | diff --git a/tests/neg/i12253.scala b/tests/warn/i12253.scala similarity index 93% rename from tests/neg/i12253.scala rename to tests/warn/i12253.scala index 540ff8ef6d5b..d632de7c43f4 100644 --- a/tests/neg/i12253.scala +++ b/tests/warn/i12253.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.quoted.{given, *} import deriving.*, compiletime.* @@ -10,7 +10,7 @@ object MacroUtils: import quotes.reflect.* val extractors = new Extractors code.asTerm match - case extractors.InlinedLambda(_, Select(_, name)) => Expr(name) // error // error + case extractors.InlinedLambda(_, Select(_, name)) => Expr(name) // warn // warn case t => report.throwError(s"Illegal argument to extractor: ${code.show}, in tasty: $t") class Extractors(using val q2: Quotes): @@ -27,4 +27,5 @@ object MacroUtils: end Extractors end MacroUtils -// nopos-error + +// nopos-warn deprecation \ No newline at end of file diff --git a/tests/warn/i12597.scala b/tests/warn/i12597.scala new file mode 100644 index 000000000000..57546a69b173 --- /dev/null +++ b/tests/warn/i12597.scala @@ -0,0 +1,8 @@ +//> using options -deprecation + +@main def Test = + val a: IArray[Int] = IArray(2) + val b: IArray[Any] = a + val c = b.toArray // warn: deprecated + c(0) = "" + diff --git a/tests/neg/i13011.scala b/tests/warn/i13011.scala similarity index 60% rename from tests/neg/i13011.scala rename to tests/warn/i13011.scala index c0541aeb7f8e..0675ec936d0c 100644 --- a/tests/neg/i13011.scala +++ b/tests/warn/i13011.scala @@ -1,23 +1,23 @@ -//> using options -Xfatal-warnings + class i13011 { - lazy implicit val simple1: String = simple1 // error + lazy implicit val simple1: String = simple1 // warn def f: Unit = { - lazy val simple2: String = simple2 // error + lazy val simple2: String = simple2 // warn } - lazy val simple3: String = if true then this.simple3 else "a" // error + lazy val simple3: String = if true then this.simple3 else "a" // warn def firstDigitIsEven(n: Int): Boolean = if n % 10 == n then n % 2 == 0 else firstDigitIsEven(n / 10) lazy val simple4: String = if firstDigitIsEven(22) then this.simple4 else "a" // ok - lazy val simple5: String = identity(this.simple5) // error + lazy val simple5: String = identity(this.simple5) // warn - lazy val simple6: String = { // error + lazy val simple6: String = { // warn this.simple6 "aa" } lazy val simple7: Function0[Any] = () => this.simple7 // Ok -} +} \ No newline at end of file diff --git a/tests/neg/i13440.check b/tests/warn/i13440.check similarity index 71% rename from tests/neg/i13440.check rename to tests/warn/i13440.check index 277d3dce0bf0..4ed3dbb09f7b 100644 --- a/tests/neg/i13440.check +++ b/tests/warn/i13440.check @@ -1,15 +1,15 @@ --- Error: tests/neg/i13440.scala:5:4 ----------------------------------------------------------------------------------- -5 |def given = 42 // error +-- Migration Warning: tests/warn/i13440.scala:5:4 ---------------------------------------------------------------------- +5 |def given = 42 // warn | ^ | given is now a keyword, write `given` instead of given to keep it as an identifier | This can be rewritten automatically under -rewrite -source 3.0-migration. --- Error: tests/neg/i13440.scala:7:13 ---------------------------------------------------------------------------------- -7 |case class C(enum: List[Int] = Nil) { // error +-- Migration Warning: tests/warn/i13440.scala:7:13 --------------------------------------------------------------------- +7 |case class C(enum: List[Int] = Nil) { // warn | ^ | enum is now a keyword, write `enum` instead of enum to keep it as an identifier | This can be rewritten automatically under -rewrite -source 3.0-migration. --- Error: tests/neg/i13440.scala:8:11 ---------------------------------------------------------------------------------- -8 | val s = s"$enum" // error +-- Migration Warning: tests/warn/i13440.scala:8:11 --------------------------------------------------------------------- +8 | val s = s"$enum" // warn | ^ | enum is now a keyword, write `enum` instead of enum to keep it as an identifier | This can be rewritten automatically under -rewrite -source 3.0-migration. diff --git a/tests/warn/i13440.scala b/tests/warn/i13440.scala new file mode 100644 index 000000000000..4f1337391d61 --- /dev/null +++ b/tests/warn/i13440.scala @@ -0,0 +1,9 @@ + + +import language.`3.0-migration` + +def given = 42 // warn + +case class C(enum: List[Int] = Nil) { // warn + val s = s"$enum" // warn +} \ No newline at end of file diff --git a/tests/neg/i13542.scala b/tests/warn/i13542.scala similarity index 75% rename from tests/neg/i13542.scala rename to tests/warn/i13542.scala index c0feb88b556d..f573aafadc7a 100644 --- a/tests/neg/i13542.scala +++ b/tests/warn/i13542.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.language.implicitConversions @@ -16,12 +16,12 @@ def lazyIdentity[T](x: => T): T = x def repIdentity[T](x: T*): T = x(0) val x1 = - implicit def barToFoo(bar: Bar): Foo = bar.toFoo // error: infinite loop in function body + implicit def barToFoo(bar: Bar): Foo = bar.toFoo // warn: infinite loop in function body val foo: Foo = Bar(1) val x2 = implicit def barToFoo2(bar: Bar): Foo = - identity(bar.toFoo) // error + identity(bar.toFoo) // warn val foo: Foo = Bar(1) val x3 = @@ -31,12 +31,12 @@ val x3 = val x4 = implicit def barToFoo4(bar: Bar): Foo = - repIdentity(bar.toFoo) // error + repIdentity(bar.toFoo) // warn val foo: Foo = Bar(1) val x5 = implicit def barToFoo4(bar: Bar): Foo = - val y = bar.toFoo // error + val y = bar.toFoo // warn y val foo: Foo = Bar(1) @@ -44,9 +44,4 @@ val x6 = implicit def barToFoo4(bar: Bar): Foo = lazy val y = bar.toFoo if false then y else ??? - val foo: Foo = Bar(1) - - - - - + val foo: Foo = Bar(1) \ No newline at end of file diff --git a/tests/warn/i14705.scala b/tests/warn/i14705.scala new file mode 100644 index 000000000000..a6c56ed8b927 --- /dev/null +++ b/tests/warn/i14705.scala @@ -0,0 +1,6 @@ + + +val n = Nil +val b = n.head.isInstanceOf[String] // warn + + diff --git a/tests/neg/i14721.scala b/tests/warn/i14721.scala similarity index 72% rename from tests/neg/i14721.scala rename to tests/warn/i14721.scala index 46786f04558b..9739bab5801b 100644 --- a/tests/neg/i14721.scala +++ b/tests/warn/i14721.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + class C: def op: Unit = println("op") @@ -6,4 +6,5 @@ class C: def test: Unit = try op catch case _: NullPointerException => - handler // error + handler // warn + diff --git a/tests/warn/i15474.scala b/tests/warn/i15474.scala new file mode 100644 index 000000000000..d7c41130a1bb --- /dev/null +++ b/tests/warn/i15474.scala @@ -0,0 +1,16 @@ + + +import scala.language.implicitConversions + +object Test2: + given c: Conversion[ String, Int ] = _.toInt // warn + +object Prices { + opaque type Price = BigDecimal + + object Price{ + given Ordering[Price] = summon[Ordering[BigDecimal]] // warn + } +} + + diff --git a/tests/neg/i15479.scala b/tests/warn/i15479.scala similarity index 68% rename from tests/neg/i15479.scala rename to tests/warn/i15479.scala index d4f306a12368..b69296ae23e4 100644 --- a/tests/neg/i15479.scala +++ b/tests/warn/i15479.scala @@ -1,4 +1,4 @@ -//> using options -source future -deprecation -Xfatal-warnings +//> using options -source future -deprecation package deptest { @deprecated("Not used any more", since="7") @@ -8,11 +8,11 @@ package deptest { } package depuser { - import deptest.DeprecatedThing.* // error + import deptest.DeprecatedThing.* // warn object DepUser { def main(args: Array[String]): Unit = println { oldValue } } -} \ No newline at end of file +} diff --git a/tests/neg/i15503a.scala b/tests/warn/i15503a.scala similarity index 85% rename from tests/neg/i15503a.scala rename to tests/warn/i15503a.scala index b5f17a1e2f52..df8691c21a13 100644 --- a/tests/neg/i15503a.scala +++ b/tests/warn/i15503a.scala @@ -1,13 +1,13 @@ -//> using options -Xfatal-warnings -Wunused:imports +//> using options -Wunused:imports object FooUnused: - import collection.mutable.Set // error - import collection.mutable.{Map => MutMap} // error - import collection.mutable._ // error + import collection.mutable.Set // warn + import collection.mutable.{Map => MutMap} // warn + import collection.mutable._ // warn object FooWildcardUnused: - import collection.mutable._ // error + import collection.mutable._ // warn object Foo: import collection.mutable.Set // OK @@ -22,7 +22,7 @@ object FooWildcard: val bar = Set() // OK object FooNestedUnused: - import collection.mutable.Set // error + import collection.mutable.Set // warn object Nested: def hello = 1 @@ -32,11 +32,11 @@ object FooNested: def hello = Set() object FooGivenUnused: - import SomeGivenImports.given // error + import SomeGivenImports.given // warn object FooGiven: import SomeGivenImports.given // OK - import SomeGivenImports._ // error + import SomeGivenImports._ // warn val foo = summon[Int] @@ -52,7 +52,7 @@ object FooTypeName: import collection.mutable.Map // OK import collection.mutable.Seq // OK import collection.mutable.ArrayBuilder // OK - import collection.mutable.ListBuffer // error + import collection.mutable.ListBuffer // warn def checkImplicit[A](using Set[A]) = () def checkParamType[B](a: Map[B,B]): Seq[B] = ??? @@ -64,12 +64,12 @@ object FooTypeName: object InlineChecks: object InlineFoo: import collection.mutable.Set // ok - import collection.mutable.Map // error + import collection.mutable.Map // warn inline def getSet = Set(1) object InlinedBar: import collection.mutable.Set // ok - import collection.mutable.Map // error + import collection.mutable.Map // warn val a = InlineFoo.getSet object MacroChecks: @@ -80,7 +80,7 @@ object MacroChecks: object InnerMostCheck: - import collection.mutable.* // error + import collection.mutable.* // warn def check = import collection.mutable.* //OK val a = Set(1) @@ -88,7 +88,7 @@ object InnerMostCheck: object IgnoreExclusion: import collection.mutable.{Set => _} // OK import collection.mutable.{Map => _} // OK - import collection.mutable.{ListBuffer} // error + import collection.mutable.{ListBuffer} // warn def check = val a = Set(1) val b = Map(1 -> 2) @@ -106,7 +106,7 @@ package testsamepackageimport: } package p { - import p._ // error + import p._ // warn package q { class U { def f = new C @@ -120,7 +120,7 @@ package testpackageimport: val x: Int = 0 package b: - import a._ // error + import a._ // warn /* END : Check on packages*/ @@ -149,7 +149,7 @@ object GivenImportOrderAtoB: object A { implicit val x: X = new X } object B { implicit val y: Y = new Y } class C { - import A._ // error + import A._ // warn import B._ // OK def t = implicitly[X] } @@ -161,7 +161,7 @@ object GivenImportOrderBtoA: object B { implicit val y: Y = new Y } class C { import B._ // OK - import A._ // error + import A._ // warn def t = implicitly[X] } /* END : tests on given import order */ @@ -174,19 +174,19 @@ object Scala2ImplicitsGiven: import A.given // OK val b = summon[Int] object C: - import A.given // error + import A.given // warn val b = 1 object D: import A._ // OK val b = summon[Int] object E: - import A._ // error + import A._ // warn val b = 1 object F: import A.x // OK val b = summon[Int] object G: - import A.x // error + import A.x // warn val b = 1 // ------------------------------------- @@ -226,7 +226,7 @@ package testOnOverloadedMethodsImports: package b: object D extends a.C package c: - import b.D.foo // error + import b.D.foo // warn package d: import b.D.foo // OK def bar = foo((??? : a.A)) @@ -242,13 +242,13 @@ package testOnOverloadedMethodsImports: package foo.testing.rename.imports: import collection.mutable.{Set => MutSet1} // OK import collection.mutable.{Set => MutSet2} // OK - import collection.mutable.{Set => MutSet3} // error + import collection.mutable.{Set => MutSet3} // warn type A[X] = MutSet1[X] val a = MutSet2(1) //------------------------------------- package foo.testing.imports.precedence: - import scala.collection.immutable.{BitSet => _, _} // error + import scala.collection.immutable.{BitSet => _, _} // warn import scala.collection.immutable.BitSet // OK def t = BitSet.empty diff --git a/tests/neg/i15503b.scala b/tests/warn/i15503b.scala similarity index 71% rename from tests/neg/i15503b.scala rename to tests/warn/i15503b.scala index 4dc10e12606d..7ab86026ff00 100644 --- a/tests/neg/i15503b.scala +++ b/tests/warn/i15503b.scala @@ -1,17 +1,17 @@ -//> using options -Xfatal-warnings -Wunused:locals +//> using options -Wunused:locals val a = 1 // OK var cs = 3 // OK val b = // OK - var e3 = 2 // error - val e1 = 1 // error - def e2 = 2 // error + var e3 = 2 // warn + val e1 = 1 // warn + def e2 = 2 // warn 1 val c = // OK - var e1 = 1 // error not set + var e1 = 1 // warn not set def e2 = e1 // OK val e3 = e2 // OK e3 @@ -26,14 +26,14 @@ val g = // OK def d = 1 // OK def e = // OK - val e1 = 1 // error - def e2 = 2 // error - var e3 = 4 // error + val e1 = 1 // warn + def e2 = 2 // warn + var e3 = 4 // warn 1 def f = // OK val f1 = 1 // OK - var f2 = f1 // error not set + var f2 = f1 // warn not set def f3 = f2 // OK f3 @@ -50,13 +50,13 @@ class Foo { var cs = 3 // OK val b = // OK - var e3 = 2 // error - val e1 = 1 // error - def e2 = 2 // error + var e3 = 2 // warn + val e1 = 1 // warn + def e2 = 2 // warn 1 val c = // OK - var e1 = 1 // error not set + var e1 = 1 // warn not set def e2 = e1 // OK val e3 = e2 // OK e3 @@ -71,14 +71,14 @@ class Foo { def d = 1 // OK def e = // OK - val e1 = 1 // error - def e2 = 2 // error - var e3 = 4 // error + val e1 = 1 // warn + def e2 = 2 // warn + var e3 = 4 // warn 1 def f = // OK val f1 = 1 // OK - var f2 = f1 // error not set + var f2 = f1 // warn not set def f3 = f2 // OK f3 @@ -99,18 +99,18 @@ package foo.scala2.tests: trait Locals { def f0 = { - var x = 1 // error + var x = 1 // warn var y = 2 // OK y = 3 y + y } def f1 = { val a = new Outer // OK - val b = new Outer // error + val b = new Outer // warn new a.Inner } def f2 = { - var x = 100 // error not set + var x = 100 // warn not set x } } @@ -118,14 +118,14 @@ package foo.scala2.tests: object Types { def l1() = { object HiObject { def f = this } // OK - class Hi { // error + class Hi { // warn def f1: Hi = new Hi def f2(x: Hi) = x } - class DingDongDoobie // error + class DingDongDoobie // warn class Bippy // OK type Something = Bippy // OK - type OtherThing = String // error + type OtherThing = String // warn (new Bippy): Something } } @@ -141,4 +141,4 @@ package test.foo.twisted.i16682: } isInt - def f = myPackage("42") + def f = myPackage("42") \ No newline at end of file diff --git a/tests/neg/i15503c.scala b/tests/warn/i15503c.scala similarity index 69% rename from tests/neg/i15503c.scala rename to tests/warn/i15503c.scala index 040dae43a2c9..e70df10f3140 100644 --- a/tests/neg/i15503c.scala +++ b/tests/warn/i15503c.scala @@ -1,29 +1,30 @@ -//> using options -Xfatal-warnings -Wunused:privates -source:3.3 +//> using options -Wunused:privates -source:3.3 + trait C class A: self: C => // OK class B: private[A] val a = 1 // OK private[B] val b = 1 // OK - private[this] val c = 1 // error - private val d = 1 // error + private[this] val c = 1 // warn + private val d = 1 // warn private[A] val e = 1 // OK private[this] val f = e // OK private val g = f // OK private[A] var h = 1 // OK - private[this] var i = h // error not set - private var j = i // error not set + private[this] var i = h // warn not set + private var j = i // warn not set private[this] var k = 1 // OK private var l = 2 // OK - private val m = // error + private val m = // warn k = l l = k l - private def fac(x: Int): Int = // error + private def fac(x: Int): Int = // warn if x == 0 then 1 else x * fac(x - 1) val x = 1 // OK @@ -34,10 +35,10 @@ class A: package foo.test.contructors: case class A private (x:Int) // OK class B private (val x: Int) // OK - class C private (private val x: Int) // error + class C private (private val x: Int) // warn class D private (private val x: Int): // OK def y = x - class E private (private var x: Int): // error not set + class E private (private var x: Int): // warn not set def y = x class F private (private var x: Int): // OK def y = @@ -54,4 +55,4 @@ package test.foo.i16682: case _ => println("NaN") } - def f = myPackage.isInt("42") + def f = myPackage.isInt("42") \ No newline at end of file diff --git a/tests/neg/i15503d.scala b/tests/warn/i15503d.scala similarity index 60% rename from tests/neg/i15503d.scala rename to tests/warn/i15503d.scala index c43dc07c638e..9a0ba9b2f8dc 100644 --- a/tests/neg/i15503d.scala +++ b/tests/warn/i15503d.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wunused:unsafe-warn-patvars +//> using options -Wunused:unsafe-warn-patvars // todo : change to :patvars sealed trait Calc @@ -8,15 +8,15 @@ case class S(pred: Const) extends Const case object Z extends Const val a = Sum(S(S(Z)),Z) match { - case Sum(a,Z) => Z // error + case Sum(a,Z) => Z // warn // case Sum(a @ _,Z) => Z // todo : this should pass in the future - case Sum(a@S(_),Z) => Z // error - case Sum(a@S(_),Z) => a // OK - case Sum(a@S(b@S(_)), Z) => a // error - case Sum(a@S(b@S(_)), Z) => a // error - case Sum(a@S(b@(S(_))), Z) => Sum(a,b) // OK + case Sum(a@S(_),Z) => Z // warn + case Sum(a@S(_),Z) => a // warn unreachable + case Sum(a@S(b@S(_)), Z) => a // warn + case Sum(a@S(b@S(_)), Z) => a // warn + case Sum(a@S(b@(S(_))), Z) => Sum(a,b) // warn unreachable case Sum(_,_) => Z // OK - case _ => Z // OK + case _ => Z // warn unreachable } // todo : This should pass in the future @@ -27,4 +27,4 @@ val a = Sum(S(S(Z)),Z) match { // todo : This should *NOT* pass in the future // val c = for { // case Some(x) <- Option(Option(1)) -// } println(s"hello world") +// } println(s"hello world") \ No newline at end of file diff --git a/tests/neg/i15503e.scala b/tests/warn/i15503e.scala similarity index 81% rename from tests/neg/i15503e.scala rename to tests/warn/i15503e.scala index f3214e7b24e6..46d73a4945cd 100644 --- a/tests/neg/i15503e.scala +++ b/tests/warn/i15503e.scala @@ -1,14 +1,14 @@ -//> using options -Xfatal-warnings -Wunused:explicits +//> using options -Wunused:explicits object Foo { /* This goes around the "trivial method" detection */ val default_val = 1 private def f1(a: Int) = a // OK - private def f2(a: Int) = default_val // error + private def f2(a: Int) = default_val // warn private def f3(a: Int)(using Int) = a // OK - private def f4(a: Int)(using Int) = default_val // error - private def f6(a: Int)(using Int) = summon[Int] // error + private def f4(a: Int)(using Int) = default_val // warn + private def f6(a: Int)(using Int) = summon[Int] // warn private def f7(a: Int)(using Int) = summon[Int] + a // OK } @@ -49,9 +49,9 @@ package foo.test.trivial: private def f6(x: Int) = X // OK private def f7(x: Int) = Y // OK private def f8(x: Int): List[C] = Nil // OK - private def f9(x: Int): List[Int] = List(1,2,3,4) // error + private def f9(x: Int): List[Int] = List(1,2,3,4) // warn private def foo:Int = 32 // OK - private def f77(x: Int) = foo // error + private def f77(x: Int) = foo // warn } object Y @@ -67,5 +67,4 @@ package foo.test.i16865: def fn(a: Int, b: Int): Int = b + 3 // OK object Ex2 extends Bar: - override def fn(a: Int, b: Int): Int = b + 3 // OK - + override def fn(a: Int, b: Int): Int = b + 3 // OK \ No newline at end of file diff --git a/tests/neg/i15503f.scala b/tests/warn/i15503f.scala similarity index 77% rename from tests/neg/i15503f.scala rename to tests/warn/i15503f.scala index 08520d149b95..ccf0b7e74065 100644 --- a/tests/neg/i15503f.scala +++ b/tests/warn/i15503f.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wunused:implicits +//> using options -Wunused:implicits /* This goes around the "trivial method" detection */ val default_int = 1 @@ -10,5 +10,5 @@ object Xd { private def f4(a: Int)(using Int) = default_int // OK private def f6(a: Int)(using Int) = summon[Int] // OK private def f7(a: Int)(using Int) = summon[Int] + a // OK - private def f8(a: Int)(using foo: Int) = a // error + private def f8(a: Int)(using foo: Int) = a // warn } diff --git a/tests/neg/i15503g.scala b/tests/warn/i15503g.scala similarity index 68% rename from tests/neg/i15503g.scala rename to tests/warn/i15503g.scala index 4da98a8d43f2..fbd9f3c1352c 100644 --- a/tests/neg/i15503g.scala +++ b/tests/warn/i15503g.scala @@ -1,14 +1,14 @@ -//> using options -Xfatal-warnings -Wunused:params +//> using options -Wunused:params /* This goes around the "trivial method" detection */ object Foo { val default_int = 1 private def f1(a: Int) = a // OK - private def f2(a: Int) = default_int // error + private def f2(a: Int) = default_int // warn private def f3(a: Int)(using Int) = a // OK - private def f4(a: Int)(using Int) = default_int // error - private def f6(a: Int)(using Int) = summon[Int] // error + private def f4(a: Int)(using Int) = default_int // warn + private def f6(a: Int)(using Int) = summon[Int] // warn private def f7(a: Int)(using Int) = summon[Int] + a // OK /* --- Trivial method check --- */ private def g1(x: Int) = 1 // OK @@ -20,4 +20,4 @@ package foo.test.i17101: extension[A] (x: Test[A]) { // OK def value: A = x def causesIssue: Unit = println("oh no") - } + } \ No newline at end of file diff --git a/tests/warn/i15503h.scala b/tests/warn/i15503h.scala new file mode 100644 index 000000000000..854693981488 --- /dev/null +++ b/tests/warn/i15503h.scala @@ -0,0 +1,20 @@ +//> using options -Wunused:linted + +import collection.mutable.Set // warn + +class A { + private val a = 1 // warn + val b = 2 // OK + + private def c = 2 // warn + def d(using x:Int): Int = b // ok + def e(x: Int) = 1 // OK + def f = + val x = 1 // warn + def f = 2 // warn + 3 + + def g(x: Int): Int = x match + case x:1 => 0 // OK + case _ => 1 +} \ No newline at end of file diff --git a/tests/neg/i15503i.scala b/tests/warn/i15503i.scala similarity index 88% rename from tests/neg/i15503i.scala rename to tests/warn/i15503i.scala index d415c95a701a..329b81327288 100644 --- a/tests/neg/i15503i.scala +++ b/tests/warn/i15503i.scala @@ -1,11 +1,11 @@ -//> using options -Xfatal-warnings -Wunused:all +//> using options -Wunused:all -import collection.mutable.{Map => MutMap} // error -import collection.mutable.Set // error +import collection.mutable.{Map => MutMap} // warn +import collection.mutable.Set // warn class A { import collection.mutable.{Map => MutMap} // OK - private val a = 1 // error + private val a = 1 // warn val b = 2 // OK /* This goes around the trivial method detection */ @@ -13,7 +13,7 @@ class A { val someMap = MutMap() - private def c1 = 2 // error + private def c1 = 2 // warn private def c2 = 2 // OK def c3 = c2 @@ -23,8 +23,8 @@ class A { def e1(x: Int) = default_int // ok def e2(x: Int) = x // OK def f = - val x = 1 // error - def f = 2 // error + val x = 1 // warn + def f = 2 // warn val y = 3 // OK def g = 4 // OK y + g @@ -49,7 +49,7 @@ package foo.test.scala.annotation: def a3(@unused a: Int) = default_int //OK def b1 = - def f = 1 // error + def f = 1 // warn 1 def b2 = @@ -61,7 +61,7 @@ package foo.test.scala.annotation: 1 object Foo: - private def a = 1 // error + private def a = 1 // warn private def b = 2 // OK @unused private def c = 3 // OK @@ -81,8 +81,8 @@ package foo.test.i16678: def run = println(foo(number => number.toString, value = 5)) // OK - println(foo(number => "<number>", value = 5)) // error - println(foo(func = number => "<number>", value = 5)) // error + println(foo(number => "<number>", value = 5)) // warn + println(foo(func = number => "<number>", value = 5)) // warn println(foo(func = number => number.toString, value = 5)) // OK println(foo(func = _.toString, value = 5)) // OK @@ -93,7 +93,7 @@ package foo.test.possibleclasses: )( s: Int, val t: Int, // OK - private val z: Int // error + private val z: Int // warn ) case class AllCaseUsed( @@ -108,12 +108,12 @@ package foo.test.possibleclasses: } class AllClass( - k: Int, // error - private val y: Int // error + k: Int, // warn + private val y: Int // warn )( - s: Int, // error + s: Int, // warn val t: Int, // OK - private val z: Int // error + private val z: Int // warn ) class AllUsed( @@ -134,7 +134,7 @@ package foo.test.possibleclasses.withvar: )( s: Int, var t: Int, // OK - private var z: Int // error + private var z: Int // warn ) case class AllCaseUsed( @@ -143,27 +143,27 @@ package foo.test.possibleclasses.withvar: )( s: Int, // OK var t: Int, // OK global scope can be set somewhere else - private var z: Int // error not set + private var z: Int // warn not set ) { def a = k + y + s + t + z } class AllClass( - k: Int, // error - private var y: Int // error + k: Int, // warn + private var y: Int // warn )( - s: Int, // error + s: Int, // warn var t: Int, // OK - private var z: Int // error + private var z: Int // warn ) class AllUsed( k: Int, // OK - private var y: Int // error not set + private var y: Int // warn not set )( s: Int, // OK var t: Int, // OK global scope can be set somewhere else - private var z: Int // error not set + private var z: Int // warn not set ) { def a = k + y + s + t + z } @@ -312,4 +312,4 @@ package foo.test.i17117: val test = t1.test } - } + } \ No newline at end of file diff --git a/tests/neg/i15503j.scala b/tests/warn/i15503j.scala similarity index 90% rename from tests/neg/i15503j.scala rename to tests/warn/i15503j.scala index 66140934abc1..f5e15bb79f79 100644 --- a/tests/neg/i15503j.scala +++ b/tests/warn/i15503j.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wunused:strict-no-implicit-warn +//> using options -Wunused:strict-no-implicit-warn package foo.unused.strict.test: package a: @@ -12,8 +12,8 @@ package foo.unused.strict.test: import a.* // OK import a.x // OK import a.y // OK - import a.z // error - import a.f // error + import a.z // warn + import a.f // warn package c: import a.given // OK import a.x // OK diff --git a/tests/warn/i15661.scala b/tests/warn/i15661.scala new file mode 100644 index 000000000000..f641222efe4b --- /dev/null +++ b/tests/warn/i15661.scala @@ -0,0 +1,7 @@ +case class Composite[T](l: List[T], v: T) + +def m(composite: Composite[?]): Unit = + composite match { + case Composite(l: List[Int], v: Int) => println(v) // warn: type test for List[Int] cannot be checked at runtime + case _ => println("This is not Int") // was: warn: Unreachable case except for null + } diff --git a/tests/neg/i15662.scala b/tests/warn/i15662.scala similarity index 68% rename from tests/neg/i15662.scala rename to tests/warn/i15662.scala index c84ed6e5e341..0cf0e57ed0c3 100644 --- a/tests/neg/i15662.scala +++ b/tests/warn/i15662.scala @@ -1,10 +1,10 @@ -//> using options -Xfatal-warnings + case class Composite[T](v: T) def m(composite: Composite[?]): Unit = composite match { - case Composite[Int](v) => println(v) // error: cannot be checked at runtime + case Composite[Int](v) => println(v) // warn: cannot be checked at runtime } def m2(composite: Composite[?]): Unit = diff --git a/tests/neg/i15893.scala b/tests/warn/i15893.scala similarity index 83% rename from tests/neg/i15893.scala rename to tests/warn/i15893.scala index a62ddc3ae653..8e40964b2eca 100644 --- a/tests/neg/i15893.scala +++ b/tests/warn/i15893.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + sealed trait NatT case class Zero() extends NatT @@ -25,19 +25,19 @@ transparent inline def transparentInlineMod2(inline n: NatT): NatT = inline n m case Succ(Succ(predPredN)) => transparentInlineMod2(predPredN) def dependentlyTypedMod2[N <: NatT](n: N): Mod2[N] = n match - case Zero(): Zero => Zero() // error - case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error - case Succ(Succ(predPredN)): Succ[Succ[?]] => dependentlyTypedMod2(predPredN) // error + case Zero(): Zero => Zero() // warn + case Succ(Zero()): Succ[Zero] => Succ(Zero()) // warn + case Succ(Succ(predPredN)): Succ[Succ[?]] => dependentlyTypedMod2(predPredN) // warn inline def inlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match - case Zero(): Zero => Zero() // error - case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error - case Succ(Succ(predPredN)): Succ[Succ[?]] => inlineDependentlyTypedMod2(predPredN) // error + case Zero(): Zero => Zero() // warn + case Succ(Zero()): Succ[Zero] => Succ(Zero()) // warn + case Succ(Succ(predPredN)): Succ[Succ[?]] => inlineDependentlyTypedMod2(predPredN) // warn transparent inline def transparentInlineDependentlyTypedMod2[N <: NatT](inline n: N): Mod2[N] = inline n match - case Zero(): Zero => Zero() // error - case Succ(Zero()): Succ[Zero] => Succ(Zero()) // error - case Succ(Succ(predPredN)): Succ[Succ[?]] => transparentInlineDependentlyTypedMod2(predPredN) // error + case Zero(): Zero => Zero() // warn + case Succ(Zero()): Succ[Zero] => Succ(Zero()) // warn + case Succ(Succ(predPredN)): Succ[Succ[?]] => transparentInlineDependentlyTypedMod2(predPredN) // warn def foo(n: NatT): NatT = mod2(n) match case Succ(Zero()) => Zero() @@ -60,4 +60,4 @@ inline def transparentInlineFoo(inline n: NatT): NatT = inline transparentInline println(transparentInlineFoo(Succ(Succ(Succ(Zero()))))) // prints Zero(), as expected println(dependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // runtime error; unexpected println(inlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected - println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected + println(transparentInlineDependentlyTypedMod2(Succ(Succ(Succ(Zero()))))) // prints Succ(Zero()), as expected \ No newline at end of file diff --git a/tests/neg/i16639a.scala b/tests/warn/i16639a.scala similarity index 67% rename from tests/neg/i16639a.scala rename to tests/warn/i16639a.scala index 5b348d594f5b..9fe4efe57d7b 100644 --- a/tests/neg/i16639a.scala +++ b/tests/warn/i16639a.scala @@ -1,35 +1,35 @@ -//> using options -Xfatal-warnings -Wunused:all -source:3.3 -// +//> using options -Wunused:all -source:3.3 + class Bippy(a: Int, b: Int) { - private def this(c: Int) = this(c, c) // warn /Dotty:NoWarn - private def boop(x: Int) = x+a+b // error - private def bippy(x: Int): Int = bippy(x) // error TODO: could warn - final private val MILLIS1 = 2000 // error no warn, /Dotty:Warn - final private val MILLIS2: Int = 1000 // error + private def this(c: Int) = this(c, c) + private def boop(x: Int) = x+a+b // warn + private def bippy(x: Int): Int = bippy(x) // warn TODO: could warn + final private val MILLIS1 = 2000 // warn no warn, /Dotty:Warn + final private val MILLIS2: Int = 1000 // warn final private val HI_COMPANION: Int = 500 // no warn, accessed from companion def hi() = Bippy.HI_INSTANCE } object Bippy { def hi(x: Bippy) = x.HI_COMPANION private val HI_INSTANCE: Int = 500 // no warn, accessed from instance - private val HEY_INSTANCE: Int = 1000 // error warn - private lazy val BOOL: Boolean = true // error warn + private val HEY_INSTANCE: Int = 1000 // warn warn + private lazy val BOOL: Boolean = true // warn warn } class A(val msg: String) class B1(msg: String) extends A(msg) class B2(msg0: String) extends A(msg0) -class B3(msg0: String) extends A("msg") // error /Dotty: unused explicit parameter +class B3(msg0: String) extends A("msg") // warn /Dotty: unused explicit parameter trait Bing trait Accessors { - private var v1: Int = 0 // error warn - private var v2: Int = 0 // error warn, never set + private var v1: Int = 0 // warn warn + private var v2: Int = 0 // warn warn, never set private var v3: Int = 0 private var v4: Int = 0 // no warn - private[this] var v5 = 0 // error warn, never set + private[this] var v5 = 0 // warn warn, never set private[this] var v6 = 0 private[this] var v7 = 0 // no warn @@ -43,12 +43,12 @@ trait Accessors { } class StableAccessors { - private var s1: Int = 0 // error warn - private var s2: Int = 0 // error warn, never set - private var s3: Int = 0 // warn, never got /Dotty: no warn even if not usued + private var s1: Int = 0 // warn warn + private var s2: Int = 0 // warn warn, never set + private var s3: Int = 0 private var s4: Int = 0 // no warn - private[this] var s5 = 0 // error warn, never set + private[this] var s5 = 0 // warn warn, never set private[this] var s6 = 0 // no warn, limitation /Dotty: Why limitation ? private[this] var s7 = 0 // no warn @@ -62,7 +62,6 @@ class StableAccessors { } trait DefaultArgs { - // warn about default getters for x2 and x3 private def bippy(x1: Int, x2: Int = 10, x3: Int = 15): Int = x1 + x2 + x3 // no more warn warn since #17061 def boppy() = bippy(5, 100, 200) @@ -75,27 +74,27 @@ class Outer { trait Locals { def f0 = { - var x = 1 // error warn + var x = 1 // warn warn var y = 2 y = 3 y + y } def f1 = { val a = new Outer // no warn - val b = new Outer // error warn + val b = new Outer // warn warn new a.Inner } def f2 = { - var x = 100 // error warn about it being a var, var not set + var x = 100 // warn warn about it being a var, var not set x } } object Types { private object Dongo { def f = this } // no more warn since #17061 - private class Bar1 // error warn + private class Bar1 // warn warn private class Bar2 // no warn - private type Alias1 = String // error warn + private type Alias1 = String // warn warn private type Alias2 = String // no warn def bippo = (new Bar2).toString @@ -103,14 +102,14 @@ object Types { def l1() = { object HiObject { def f = this } // no more warn since #17061 - class Hi { // error warn + class Hi { // warn warn def f1: Hi = new Hi def f2(x: Hi) = x } - class DingDongDoobie // error warn + class DingDongDoobie // warn warn class Bippy // no warn type Something = Bippy // no warn - type OtherThing = String // error warn + type OtherThing = String // warn warn (new Bippy): Something } } @@ -126,7 +125,7 @@ trait Underwarn { class OtherNames { private def x_=(i: Int): Unit = () // no more warn since #17061 - private def x: Int = 42 // error Dotty triggers unused private member : To investigate + private def x: Int = 42 // warn Dotty triggers unused private member : To investigate private def y_=(i: Int): Unit = () // // no more warn since #17061 private def y: Int = 42 @@ -152,7 +151,7 @@ trait Forever { } trait Ignorance { - private val readResolve = 42 // error ignore /dotty triggers unused private member/ why should we ignore ? + private val readResolve = 42 // warn ignore /dotty triggers unused private member/ why should we ignore ? } trait CaseyKasem { @@ -190,7 +189,7 @@ class `no warn in patmat anonfun isDefinedAt` { class `nonprivate alias is enclosing` { class C type C2 = C - private class D extends C2 // error warn + private class D extends C2 // warn warn } object `classof something` { @@ -200,8 +199,7 @@ object `classof something` { trait `short comings` { def f: Int = { - val x = 42 // error /Dotty only triggers in dotty + val x = 42 // warn /Dotty only triggers in dotty 17 } -} - +} \ No newline at end of file diff --git a/tests/neg/i16649-refutable.check b/tests/warn/i16649-refutable.check similarity index 78% rename from tests/neg/i16649-refutable.check rename to tests/warn/i16649-refutable.check index a1325d7cfa91..a6cacfc691ee 100644 --- a/tests/neg/i16649-refutable.check +++ b/tests/warn/i16649-refutable.check @@ -1,5 +1,5 @@ --- Error: tests/neg/i16649-refutable.scala:6:6 ------------------------------------------------------------------------- -6 | val '{ ($y: Int) + ($z: Int) } = x // error +-- Warning: tests/warn/i16649-refutable.scala:6:6 ---------------------------------------------------------------------- +6 | val '{ ($y: Int) + ($z: Int) } = x // warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | pattern binding uses refutable extractor `'{...}` | diff --git a/tests/neg/i16649-refutable.scala b/tests/warn/i16649-refutable.scala similarity index 59% rename from tests/neg/i16649-refutable.scala rename to tests/warn/i16649-refutable.scala index 8caac5b2576a..5ff18b5a3633 100644 --- a/tests/neg/i16649-refutable.scala +++ b/tests/warn/i16649-refutable.scala @@ -1,9 +1,10 @@ -//> using options -Xfatal-warnings + import quoted.* def foo(using Quotes)(x: Expr[Int]) = - val '{ ($y: Int) + ($z: Int) } = x // error + val '{ ($y: Int) + ($z: Int) } = x // warn val '{ $a: Int } = x val '{ $b: Any } = x val '{ $c } = x + diff --git a/tests/neg/i16728.check b/tests/warn/i16728.check similarity index 55% rename from tests/neg/i16728.check rename to tests/warn/i16728.check index 93cc215696c2..117b2bd0c4d4 100644 --- a/tests/neg/i16728.check +++ b/tests/warn/i16728.check @@ -1,5 +1,5 @@ --- [E092] Pattern Match Error: tests/neg/i16728.scala:18:11 ------------------------------------------------------------ -18 | case tx : C[Int]#X => // error +-- [E092] Pattern Match Unchecked Warning: tests/warn/i16728.scala:18:11 ----------------------------------------------- +18 | case tx : C[Int]#X => // warn | ^ | the type test for C[Int] cannot be checked at runtime because its type arguments can't be determined from A | diff --git a/tests/neg/i16728.scala b/tests/warn/i16728.scala similarity index 87% rename from tests/neg/i16728.scala rename to tests/warn/i16728.scala index b76bb03fa14a..4d28b07c51a3 100644 --- a/tests/neg/i16728.scala +++ b/tests/warn/i16728.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + class A[T] { class X { @@ -15,7 +15,7 @@ object Test { val b0x : A[?]#X = new b0.X def test = b0x match { - case tx : C[Int]#X => // error + case tx : C[Int]#X => // warn val c : C[Int] = tx.outer c case _ => @@ -31,4 +31,4 @@ object Test { } } -} \ No newline at end of file +} diff --git a/tests/neg/i16930.scala b/tests/warn/i16930.scala similarity index 70% rename from tests/neg/i16930.scala rename to tests/warn/i16930.scala index c7af60161424..bf30fccbf601 100644 --- a/tests/neg/i16930.scala +++ b/tests/warn/i16930.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wunused:imports +//> using options -Wunused:imports trait Outer: trait Used @@ -6,7 +6,7 @@ trait Outer: object Test { val outer: Outer = ??? - import outer.{Used, Unused} // error + import outer.{Used, Unused} // warn def foo(x: Any): Used = x.asInstanceOf[Used] } @@ -17,6 +17,6 @@ trait Outer1: object Test1 { val outer1: Outer1 = ??? - import outer1.{Unused1, UnusedToo1} // error // error + import outer1.{Unused1, UnusedToo1} // warn // warn def foo() = outer1.unusedToo1 // in this case UnusedToo1 is not used explicitly, only inferred -} +} \ No newline at end of file diff --git a/tests/neg/i17266.check b/tests/warn/i17266.check similarity index 83% rename from tests/neg/i17266.check rename to tests/warn/i17266.check index 1a84d1bf5e89..716cd531dd0a 100644 --- a/tests/neg/i17266.check +++ b/tests/warn/i17266.check @@ -1,5 +1,5 @@ --- [E181] Potential Issue Error: tests/neg/i17266.scala:4:2 ------------------------------------------------------------ -4 | synchronized { // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:4:2 --------------------------------------------------------- +4 | synchronized { // warn | ^^^^^^^^^^^^ | Suspicious top-level unqualified call to synchronized |--------------------------------------------------------------------------------------------------------------------- @@ -9,8 +9,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. --------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:17:2 ----------------------------------------------------------- -17 | synchronized { // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:17:2 -------------------------------------------------------- +17 | synchronized { // warn | ^^^^^^^^^^^^ | Suspicious top-level unqualified call to synchronized |-------------------------------------------------------------------------------------------------------------------- @@ -20,8 +20,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. -------------------------------------------------------------------------------------------------------------------- --- [E187] Potential Issue Error: tests/neg/i17266.scala:22:4 ----------------------------------------------------------- -22 | 1.synchronized { // error +-- [E187] Potential Issue Warning: tests/warn/i17266.scala:22:4 -------------------------------------------------------- +22 | 1.synchronized { // warn | ^^^^^^^^^^^^^^ | Suspicious synchronized call on boxed class |-------------------------------------------------------------------------------------------------------------------- @@ -30,8 +30,8 @@ | You called the synchronized method on a boxed primitive. This might not be what | you intended. -------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:108:2 ---------------------------------------------------------- -108 | wait() // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:108:2 ------------------------------------------------------- +108 | wait() // warn | ^^^^ | Suspicious top-level unqualified call to wait |------------------------------------------------------------------------------------------------------------------- @@ -41,8 +41,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. ------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:115:2 ---------------------------------------------------------- -115 | wait() // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:115:2 ------------------------------------------------------- +115 | wait() // warn | ^^^^ | Suspicious top-level unqualified call to wait |------------------------------------------------------------------------------------------------------------------- @@ -52,8 +52,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. ------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:121:2 ---------------------------------------------------------- -121 | wait(10) // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:121:2 ------------------------------------------------------- +121 | wait(10) // warn | ^^^^ | Suspicious top-level unqualified call to wait |------------------------------------------------------------------------------------------------------------------- @@ -63,8 +63,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. ------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:128:2 ---------------------------------------------------------- -128 | wait(10) // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:128:2 ------------------------------------------------------- +128 | wait(10) // warn | ^^^^ | Suspicious top-level unqualified call to wait |------------------------------------------------------------------------------------------------------------------- @@ -74,8 +74,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. ------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:134:2 ---------------------------------------------------------- -134 | hashCode() // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:134:2 ------------------------------------------------------- +134 | hashCode() // warn | ^^^^^^^^ | Suspicious top-level unqualified call to hashCode |------------------------------------------------------------------------------------------------------------------- @@ -85,8 +85,8 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. ------------------------------------------------------------------------------------------------------------------- --- [E181] Potential Issue Error: tests/neg/i17266.scala:141:2 ---------------------------------------------------------- -141 | hashCode() // error +-- [E181] Potential Issue Warning: tests/warn/i17266.scala:141:2 ------------------------------------------------------- +141 | hashCode() // warn | ^^^^^^^^ | Suspicious top-level unqualified call to hashCode |------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i17266.scala b/tests/warn/i17266.scala similarity index 86% rename from tests/neg/i17266.scala rename to tests/warn/i17266.scala index 439abafc44a1..7e0c9f1b653b 100644 --- a/tests/neg/i17266.scala +++ b/tests/warn/i17266.scala @@ -1,7 +1,7 @@ -//> using options -Werror -explain +//> using options -explain def test1 = - synchronized { // error + synchronized { // warn println("hello") } @@ -14,12 +14,12 @@ object MyLib def test3 = import MyLib.* - synchronized { // error + synchronized { // warn println("hello") } def test4 = - 1.synchronized { // error + 1.synchronized { // warn println("hello") } @@ -105,40 +105,40 @@ trait Test15: } def test16 = - wait() // error + wait() // warn def test17 = this.wait() // not an error (should be?) def test18 = import MyLib.* - wait() // error + wait() // warn def test19 = 1.wait() // not an error (should be?) def test20 = - wait(10) // error + wait(10) // warn def test21 = this.wait(10) // not an error (should be?) def test22 = import MyLib.* - wait(10) // error + wait(10) // warn def test23 = 1.wait(10) // not an error (should be?) def test24 = - hashCode() // error + hashCode() // warn def test25 = this.hashCode() // not an error (should be?) def test26 = import MyLib.* - hashCode() // error + hashCode() // warn def test27 = - 1.hashCode()// not an error (should be? probably not) + 1.hashCode()// not an error (should be? probably not) \ No newline at end of file diff --git a/tests/neg/i17314b.scala b/tests/warn/i17314b.scala similarity index 63% rename from tests/neg/i17314b.scala rename to tests/warn/i17314b.scala index 9e89fecde935..e1500028ca93 100644 --- a/tests/neg/i17314b.scala +++ b/tests/warn/i17314b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wunused:all +//> using options -Wunused:all package foo: class Foo[T] @@ -6,9 +6,10 @@ package foo: package bar: - import foo.{given foo.Foo[Int]} // error + import foo.{given foo.Foo[Int]} // warn import foo.Foo given Foo[Int] = ??? val repro: Foo[Int] = summon[Foo[Int]] + diff --git a/tests/neg/i17612a.check b/tests/warn/i17612a.check similarity index 62% rename from tests/neg/i17612a.check rename to tests/warn/i17612a.check index 04a5b07b6e33..67b489f17a91 100644 --- a/tests/neg/i17612a.check +++ b/tests/warn/i17612a.check @@ -1,32 +1,32 @@ --- Error: tests/neg/i17612a.scala:18:15 -------------------------------------------------------------------------------- -18 | class Derived(x : Int, y: Int, z2: Int) extends Base(x, y + 1, z2): // error // error / for x, y translated to private[this] x field & shadowing var Base.x, Base.y +-- Warning: tests/warn/i17612a.scala:18:15 ----------------------------------------------------------------------------- +18 | class Derived(x : Int, y: Int, z2: Int) extends Base(x, y + 1, z2): // warn // warn / for x, y translated to private[this] x field & shadowing var Base.x, Base.y | ^ | value x in class Derived shadows field x inherited from class Base --- Error: tests/neg/i17612a.scala:18:24 -------------------------------------------------------------------------------- -18 | class Derived(x : Int, y: Int, z2: Int) extends Base(x, y + 1, z2): // error // error / for x, y translated to private[this] x field & shadowing var Base.x, Base.y +-- Warning: tests/warn/i17612a.scala:18:24 ----------------------------------------------------------------------------- +18 | class Derived(x : Int, y: Int, z2: Int) extends Base(x, y + 1, z2): // warn // warn / for x, y translated to private[this] x field & shadowing var Base.x, Base.y | ^ | value y in class Derived shadows field y inherited from class Base --- Error: tests/neg/i17612a.scala:20:2 --------------------------------------------------------------------------------- -20 | private val shadowed2 = 2 + 2 // error (In Scala 2 we cannot do that got the warning) +-- Warning: tests/warn/i17612a.scala:20:2 ------------------------------------------------------------------------------ +20 | private val shadowed2 = 2 + 2 // warn (In Scala 2 we cannot do that got the warning) | ^ | value shadowed2 in class Derived shadows field shadowed2 inherited from class Base --- Error: tests/neg/i17612a.scala:21:2 --------------------------------------------------------------------------------- -21 | private[this] val shadowed3 = 3 + 3 // error +-- Warning: tests/warn/i17612a.scala:21:2 ------------------------------------------------------------------------------ +21 | private[this] val shadowed3 = 3 + 3 // warn | ^ | value shadowed3 in class Derived shadows field shadowed3 inherited from class Base --- Error: tests/neg/i17612a.scala:23:2 --------------------------------------------------------------------------------- -23 | private val shadowed5 = 5 + 5 // error +-- Warning: tests/warn/i17612a.scala:23:2 ------------------------------------------------------------------------------ +23 | private val shadowed5 = 5 + 5 // warn | ^ | value shadowed5 in class Derived shadows field shadowed5 inherited from class Base --- Error: tests/neg/i17612a.scala:34:20 -------------------------------------------------------------------------------- -34 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // error // error // error +-- Warning: tests/warn/i17612a.scala:34:20 ----------------------------------------------------------------------------- +34 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // warn // warn // warn | ^ | value x in class UnderDerived shadows field x inherited from class Base --- Error: tests/neg/i17612a.scala:34:28 -------------------------------------------------------------------------------- -34 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // error // error // error +-- Warning: tests/warn/i17612a.scala:34:28 ----------------------------------------------------------------------------- +34 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // warn // warn // warn | ^ | value y in class UnderDerived shadows field y inherited from class Base --- Error: tests/neg/i17612a.scala:34:36 -------------------------------------------------------------------------------- -34 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // error // error // error +-- Warning: tests/warn/i17612a.scala:34:36 ----------------------------------------------------------------------------- +34 | class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // warn // warn // warn | ^ | value z in class UnderDerived shadows field z inherited from class Base diff --git a/tests/neg/i17612a.scala b/tests/warn/i17612a.scala similarity index 76% rename from tests/neg/i17612a.scala rename to tests/warn/i17612a.scala index 099b528965e1..7473d8fd9ec9 100644 --- a/tests/neg/i17612a.scala +++ b/tests/warn/i17612a.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Xlint:private-shadow -source:3.3 +//> using options -Xlint:private-shadow -source:3.3 object i17612a: class Base(var x: Int, val y: Int, var z: Int): @@ -15,12 +15,12 @@ object i17612a: def increment(): Unit = x = x + 1 - class Derived(x : Int, y: Int, z2: Int) extends Base(x, y + 1, z2): // error // error / for x, y translated to private[this] x field & shadowing var Base.x, Base.y + class Derived(x : Int, y: Int, z2: Int) extends Base(x, y + 1, z2): // warn // warn / for x, y translated to private[this] x field & shadowing var Base.x, Base.y private def hello() = 4 - private val shadowed2 = 2 + 2 // error (In Scala 2 we cannot do that got the warning) - private[this] val shadowed3 = 3 + 3 // error + private val shadowed2 = 2 + 2 // warn (In Scala 2 we cannot do that got the warning) + private[this] val shadowed3 = 3 + 3 // warn //private[Derived] val fatalOverride = 0 // value fatalOverride of type Int has weaker access privileges; it should be public - private val shadowed5 = 5 + 5 // error + private val shadowed5 = 5 + 5 // warn private val notShadowed2 = -4 //protected var shadowed6 = 6 + 6 // variable shadowed6 of type Int has weaker access privileges; it should be public @@ -31,7 +31,7 @@ object i17612a: override def toString = s"x : ${x.toString}, y : ${y.toString}" - class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // error // error // error + class UnderDerived(x: Int, y: Int, z: Int) extends Derived(x, y, z) // warn // warn // warn def main(args: Array[String]) = val derived = new Derived(1, 1, 1) diff --git a/tests/neg/i17613a.check b/tests/warn/i17613a.check similarity index 57% rename from tests/neg/i17613a.check rename to tests/warn/i17613a.check index 4721b786c82d..6e40d102b1a4 100644 --- a/tests/neg/i17613a.check +++ b/tests/warn/i17613a.check @@ -1,28 +1,28 @@ --- Error: tests/neg/i17613a.scala:8:13 --------------------------------------------------------------------------------- -8 | def foobar[D](in: D) = in.toString // error method parameter shadows some other type +-- Warning: tests/warn/i17613a.scala:8:13 ------------------------------------------------------------------------------ +8 | def foobar[D](in: D) = in.toString // warn method parameter shadows some other type | ^ | Type parameter D for method foobar shadows the type defined by trait D in class B --- Error: tests/neg/i17613a.scala:9:13 --------------------------------------------------------------------------------- -9 | type MySeq[D] = Seq[D] // error type member's parameter shadows some other type +-- Warning: tests/warn/i17613a.scala:9:13 ------------------------------------------------------------------------------ +9 | type MySeq[D] = Seq[D] // warn type member's parameter shadows some other type | ^ | Type parameter D for type MySeq shadows the type defined by trait D in class B --- Error: tests/neg/i17613a.scala:11:12 -------------------------------------------------------------------------------- -11 | class Foo[T](t: T): // error class parameter shadows some other type +-- Warning: tests/warn/i17613a.scala:11:12 ----------------------------------------------------------------------------- +11 | class Foo[T](t: T): // warn class parameter shadows some other type | ^ | Type parameter T for class Foo shadows the type defined by type T in class B --- Error: tests/neg/i17613a.scala:12:11 -------------------------------------------------------------------------------- -12 | def bar[T](w: T) = w.toString // error a type parameter shadows another type parameter +-- Warning: tests/warn/i17613a.scala:12:11 ----------------------------------------------------------------------------- +12 | def bar[T](w: T) = w.toString // warn a type parameter shadows another type parameter | ^ | Type parameter T for method bar shadows the type defined by type T in class Foo --- Error: tests/neg/i17613a.scala:15:12 -------------------------------------------------------------------------------- -15 | class C[M[List[_]]] // error +-- Warning: tests/warn/i17613a.scala:15:12 ----------------------------------------------------------------------------- +15 | class C[M[List[_]]] // warn | ^^^^^^^ | Type parameter List for class C shadows the type defined by type List in package scala --- Error: tests/neg/i17613a.scala:16:11 -------------------------------------------------------------------------------- -16 | type E[M[List[_]]] = Int // error +-- Warning: tests/warn/i17613a.scala:16:11 ----------------------------------------------------------------------------- +16 | type E[M[List[_]]] = Int // warn | ^^^^^^^ | Type parameter List for type E shadows the type defined by type List in package scala --- Error: tests/neg/i17613a.scala:17:14 -------------------------------------------------------------------------------- -17 | def foo[N[M[List[_]]]] = ??? // error +-- Warning: tests/warn/i17613a.scala:17:14 ----------------------------------------------------------------------------- +17 | def foo[N[M[List[_]]]] = ??? // warn | ^^^^^^^ | Type parameter List for method foo shadows the type defined by type List in package scala diff --git a/tests/warn/i17613a.scala b/tests/warn/i17613a.scala new file mode 100644 index 000000000000..6ee55a5cf973 --- /dev/null +++ b/tests/warn/i17613a.scala @@ -0,0 +1,23 @@ +//> using options -Xlint:type-parameter-shadow + +object i17613a: + class B: + type T = Int + trait D + + def foobar[D](in: D) = in.toString // warn method parameter shadows some other type + type MySeq[D] = Seq[D] // warn type member's parameter shadows some other type + + class Foo[T](t: T): // warn class parameter shadows some other type + def bar[T](w: T) = w.toString // warn a type parameter shadows another type parameter + + // even deeply nested... + class C[M[List[_]]] // warn + type E[M[List[_]]] = Int // warn + def foo[N[M[List[_]]]] = ??? // warn + + // ...but not between type parameters in the same list + class F[A, M[N[A]]] + type G[A, M[L[A]]] = Int + def bar[A, N[M[L[A]]]] = ??? + def main(args: Array[String]) = println("Test for type parameter shadow") \ No newline at end of file diff --git a/tests/neg/i18722.check b/tests/warn/i18722.check similarity index 89% rename from tests/neg/i18722.check rename to tests/warn/i18722.check index 539e23787752..4fae07e15204 100644 --- a/tests/neg/i18722.check +++ b/tests/warn/i18722.check @@ -1,5 +1,5 @@ --- [E190] Potential Issue Error: tests/neg/i18722.scala:3:15 ----------------------------------------------------------- -3 |def f1: Unit = null // error +-- [E190] Potential Issue Warning: tests/warn/i18722.scala:3:15 -------------------------------------------------------- +3 |def f1: Unit = null // warn | ^^^^ | Discarded non-Unit value of type Null. You may want to use `()`. |--------------------------------------------------------------------------------------------------------------------- @@ -9,8 +9,8 @@ | Here the `null` expression is a pure statement that can be discarded. | Therefore the expression is effectively equivalent to `()`. --------------------------------------------------------------------------------------------------------------------- --- [E190] Potential Issue Error: tests/neg/i18722.scala:4:15 ----------------------------------------------------------- -4 |def f2: Unit = 1 // error +-- [E190] Potential Issue Warning: tests/warn/i18722.scala:4:15 -------------------------------------------------------- +4 |def f2: Unit = 1 // warn | ^ | Discarded non-Unit value of type Int. You may want to use `()`. |--------------------------------------------------------------------------------------------------------------------- @@ -20,8 +20,8 @@ | Here the `1` expression is a pure statement that can be discarded. | Therefore the expression is effectively equivalent to `()`. --------------------------------------------------------------------------------------------------------------------- --- [E190] Potential Issue Error: tests/neg/i18722.scala:5:15 ----------------------------------------------------------- -5 |def f3: Unit = "a" // error +-- [E190] Potential Issue Warning: tests/warn/i18722.scala:5:15 -------------------------------------------------------- +5 |def f3: Unit = "a" // warn | ^^^ | Discarded non-Unit value of type String. You may want to use `()`. |--------------------------------------------------------------------------------------------------------------------- @@ -31,8 +31,8 @@ | Here the `"a"` expression is a pure statement that can be discarded. | Therefore the expression is effectively equivalent to `()`. --------------------------------------------------------------------------------------------------------------------- --- [E190] Potential Issue Error: tests/neg/i18722.scala:7:15 ----------------------------------------------------------- -7 |def f4: Unit = i // error +-- [E190] Potential Issue Warning: tests/warn/i18722.scala:7:15 -------------------------------------------------------- +7 |def f4: Unit = i // warn | ^ | Discarded non-Unit value of type Int. You may want to use `()`. |--------------------------------------------------------------------------------------------------------------------- diff --git a/tests/warn/i18722.scala b/tests/warn/i18722.scala new file mode 100644 index 000000000000..246640a349b4 --- /dev/null +++ b/tests/warn/i18722.scala @@ -0,0 +1,9 @@ +//> using options -explain + +def f1: Unit = null // warn +def f2: Unit = 1 // warn +def f3: Unit = "a" // warn +val i: Int = 1 +def f4: Unit = i // warn +val u: Unit = () +def f5: Unit = u \ No newline at end of file diff --git a/tests/neg/i18862-3.4.check b/tests/warn/i18862-3.4.check similarity index 70% rename from tests/neg/i18862-3.4.check rename to tests/warn/i18862-3.4.check index b56454feeeaa..8dd5058d305e 100644 --- a/tests/neg/i18862-3.4.check +++ b/tests/warn/i18862-3.4.check @@ -1,5 +1,5 @@ --- Error: tests/neg/i18862-3.4.scala:6:38 ------------------------------------------------------------------------------ -6 |def test(xs: List[Int]): Unit = f(xs: _*) // error: migration warning +-- Warning: tests/warn/i18862-3.4.scala:4:38 --------------------------------------------------------------------------- +4 |def test(xs: List[Int]): Unit = f(xs: _*) // warn: migration warning | ^ | The syntax `x: _*` is no longer supported for vararg splices; use `x*` instead | This construct can be rewritten automatically under -rewrite -source 3.4-migration. diff --git a/tests/warn/i18862-3.4.scala b/tests/warn/i18862-3.4.scala new file mode 100644 index 000000000000..6d9cf8c71f7b --- /dev/null +++ b/tests/warn/i18862-3.4.scala @@ -0,0 +1,4 @@ +import scala.language.`3.4` + +def f(x: Int*): Unit = () +def test(xs: List[Int]): Unit = f(xs: _*) // warn: migration warning diff --git a/tests/warn/i18862-future-migration.scala b/tests/warn/i18862-future-migration.scala new file mode 100644 index 000000000000..02225b67435a --- /dev/null +++ b/tests/warn/i18862-future-migration.scala @@ -0,0 +1,4 @@ +import scala.language.`future-migration` + +def f(x: Int*): Unit = () +def test(xs: List[Int]): Unit = f(xs: _*) // warn: migration warning diff --git a/tests/warn/i18867-3.4.scala b/tests/warn/i18867-3.4.scala new file mode 100644 index 000000000000..e2630c0cb95c --- /dev/null +++ b/tests/warn/i18867-3.4.scala @@ -0,0 +1,5 @@ +import language.`3.4` + +def foo(x: Int) = x + +def test = foo _ // warn diff --git a/tests/neg/i18867.check b/tests/warn/i18867.check similarity index 76% rename from tests/neg/i18867.check rename to tests/warn/i18867.check index 014e9e7bd92e..226496d8e74b 100644 --- a/tests/neg/i18867.check +++ b/tests/warn/i18867.check @@ -1,5 +1,5 @@ --- Error: tests/neg/i18867.scala:5:15 ---------------------------------------------------------------------------------- -5 |def test = foo _ // error +-- Warning: tests/warn/i18867.scala:3:15 ------------------------------------------------------------------------------- +3 |def test = foo _ // warn | ^^^^^ | The syntax `<function> _` is no longer supported; | you can simply leave out the trailing ` _` diff --git a/tests/warn/i18867.scala b/tests/warn/i18867.scala new file mode 100644 index 000000000000..a16d67b89919 --- /dev/null +++ b/tests/warn/i18867.scala @@ -0,0 +1,3 @@ +def foo(x: Int) = x + +def test = foo _ // warn diff --git a/tests/warn/i19002.check b/tests/warn/i19002.check new file mode 100644 index 000000000000..be26ff5e32f4 --- /dev/null +++ b/tests/warn/i19002.check @@ -0,0 +1,36 @@ +-- Deprecation Warning: tests/warn/i19002.scala:5:20 ------------------------------------------------------------------- +5 |class TBar1 extends TFoo // warn + | ^^^^ + | inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final +-- Deprecation Warning: tests/warn/i19002.scala:6:20 ------------------------------------------------------------------- +6 |trait TBar2 extends TFoo // warn + | ^^^^ + | inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final +-- Deprecation Warning: tests/warn/i19002.scala:11:20 ------------------------------------------------------------------ +11 |class CBar1 extends CFoo // warn + | ^^^^ + | inheritance from class CFoo is deprecated (since: FooLib 11.0) +-- Deprecation Warning: tests/warn/i19002.scala:12:20 ------------------------------------------------------------------ +12 |trait CBar2 extends CFoo // warn + | ^^^^ + | inheritance from class CFoo is deprecated (since: FooLib 11.0) +-- Deprecation Warning: tests/warn/i19002.scala:17:20 ------------------------------------------------------------------ +17 |class ABar1 extends AFoo // warn + | ^^^^ + | inheritance from class AFoo is deprecated: this class will be made final +-- Deprecation Warning: tests/warn/i19002.scala:18:20 ------------------------------------------------------------------ +18 |trait ABar2 extends AFoo // warn + | ^^^^ + | inheritance from class AFoo is deprecated: this class will be made final +-- Deprecation Warning: tests/warn/i19002.scala:7:16 ------------------------------------------------------------------- +7 |def TBar3 = new TFoo {} // warn + | ^^^^ + | inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final +-- Deprecation Warning: tests/warn/i19002.scala:13:16 ------------------------------------------------------------------ +13 |def CBar3 = new CFoo {} // warn + | ^^^^ + | inheritance from class CFoo is deprecated (since: FooLib 11.0) +-- Deprecation Warning: tests/warn/i19002.scala:19:16 ------------------------------------------------------------------ +19 |def ABar3 = new AFoo {} // warn + | ^^^^ + | inheritance from class AFoo is deprecated: this class will be made final diff --git a/tests/warn/i19002.scala b/tests/warn/i19002.scala new file mode 100644 index 000000000000..5242c1bfb49e --- /dev/null +++ b/tests/warn/i19002.scala @@ -0,0 +1,23 @@ +//> using options -deprecation + +@deprecatedInheritance("this class will be made final", "FooLib 12.0") +trait TFoo +class TBar1 extends TFoo // warn +trait TBar2 extends TFoo // warn +def TBar3 = new TFoo {} // warn + +@deprecatedInheritance(since = "FooLib 11.0") +class CFoo +class CBar1 extends CFoo // warn +trait CBar2 extends CFoo // warn +def CBar3 = new CFoo {} // warn + +@deprecatedInheritance(message = "this class will be made final") +abstract class AFoo +class ABar1 extends AFoo // warn +trait ABar2 extends AFoo // warn +def ABar3 = new AFoo {} // warn + +@deprecated +class DeprecatedFoo: + class Foo extends AFoo // it shoudln't warn here (in deprecated context) diff --git a/tests/pos/i19031.ci-reg1.scala b/tests/warn/i19031.ci-reg1.scala similarity index 91% rename from tests/pos/i19031.ci-reg1.scala rename to tests/warn/i19031.ci-reg1.scala index 3c15a3eb9afc..6e8c92c377ea 100644 --- a/tests/pos/i19031.ci-reg1.scala +++ b/tests/warn/i19031.ci-reg1.scala @@ -1,5 +1,3 @@ -//> using options -Werror - sealed trait Mark[T] trait Foo[T] diff --git a/tests/pos/i19031.ci-reg2.scala b/tests/warn/i19031.ci-reg2.scala similarity index 91% rename from tests/pos/i19031.ci-reg2.scala rename to tests/warn/i19031.ci-reg2.scala index e5b12cc17655..a4d5a83fa4dd 100644 --- a/tests/pos/i19031.ci-reg2.scala +++ b/tests/warn/i19031.ci-reg2.scala @@ -1,5 +1,3 @@ -//> using options -Werror - trait Outer: sealed trait Foo case class Bar1() extends Foo diff --git a/tests/pos/i19031.scala b/tests/warn/i19031.scala similarity index 80% rename from tests/pos/i19031.scala rename to tests/warn/i19031.scala index e56744017255..174f459460fd 100644 --- a/tests/pos/i19031.scala +++ b/tests/warn/i19031.scala @@ -1,5 +1,3 @@ -//> using options -Werror - sealed trait A: class B extends A diff --git a/tests/warn/i19031b.scala b/tests/warn/i19031b.scala new file mode 100644 index 000000000000..0b6eaff5df1f --- /dev/null +++ b/tests/warn/i19031b.scala @@ -0,0 +1,10 @@ +sealed trait A: + class B extends A + +class C extends A + +class Test: + def t1(a: A): Boolean = + a match + case b: A#B => true + case c: C => true diff --git a/tests/warn/i19275.scala b/tests/warn/i19275.scala new file mode 100644 index 000000000000..da17f9604ee7 --- /dev/null +++ b/tests/warn/i19275.scala @@ -0,0 +1,6 @@ +opaque type Foo[A] <: A = A + +class Test: + def t1(x: Option[Foo[List[Int]]]): Unit = x match + case Some(foo) => + case None => diff --git a/tests/warn/i19302.check b/tests/warn/i19302.check new file mode 100644 index 000000000000..8f439ad1320d --- /dev/null +++ b/tests/warn/i19302.check @@ -0,0 +1,20 @@ +-- Deprecation Warning: tests/warn/i19302.scala:8:20 ------------------------------------------------------------------- +8 | def doo(): Option[Thing] = // warn + | ^^^^^ + | class Thing is deprecated since n/a: is deprecated +-- Deprecation Warning: tests/warn/i19302.scala:9:13 ------------------------------------------------------------------- +9 | Some(new Thing(1)) // warn + | ^^^^^ + | class Thing is deprecated since n/a: is deprecated +-- Deprecation Warning: tests/warn/i19302.scala:10:23 ------------------------------------------------------------------ +10 | def wop(x: => Option[Thing]) = println(x) // warn + | ^^^^^ + | class Thing is deprecated since n/a: is deprecated +-- Deprecation Warning: tests/warn/i19302.scala:13:16 ------------------------------------------------------------------ +13 | doo().map((t: Thing) => println(t)) // warn + | ^^^^^ + | class Thing is deprecated since n/a: is deprecated +-- Deprecation Warning: tests/warn/i19302.scala:18:18 ------------------------------------------------------------------ +18 | val thing = new Thing(42) // warn + | ^^^^^ + | class Thing is deprecated since n/a: is deprecated diff --git a/tests/warn/i19302.scala b/tests/warn/i19302.scala new file mode 100644 index 000000000000..1638b44104c1 --- /dev/null +++ b/tests/warn/i19302.scala @@ -0,0 +1,23 @@ +//> using options -deprecation + +@deprecated("is deprecated", "n/a") +class Thing(val value: Int) + +object Main extends App { + + def doo(): Option[Thing] = // warn + Some(new Thing(1)) // warn + def wop(x: => Option[Thing]) = println(x) // warn + + doo().map(t => println(t)) + doo().map((t: Thing) => println(t)) // warn + doo().map(println) + doo().foreach(println) + for (x <- doo()) println(x) + + val thing = new Thing(42) // warn + println(thing) + + val something = Some(thing) + wop(something) +} \ No newline at end of file diff --git a/tests/warn/i19359.scala b/tests/warn/i19359.scala new file mode 100644 index 000000000000..db598a8095e1 --- /dev/null +++ b/tests/warn/i19359.scala @@ -0,0 +1,23 @@ +sealed trait Plan[+E <: Err, +F[+e <: E] <: Fal[e]] + +case class Err() extends Plan[Err, Nothing] +case class Fal[+E <: Err]() extends Plan[E, Fal] +case class Btw[+E <: Err, +F[+e <: E] <: Fal[e]]() extends Plan[E, F] + +class Tests: + def test1(plan: Plan[Err, Nothing]): Unit = plan match + case Err() => + case Btw() => + + def main1 = test1(Btw()) + +/* + +Previously, Plan[Err, Nothing] dropped Btw, +because it didn't instantiate ?F to Nothing + + <== decompose(Plan[Err, Nothing], [Btw[Err, Fal]]) = [Not, Err] + <== decompose(Btw[Err, Fal] & Plan[Err, Nothing]) = [] +<== simplify(Prod(Btw())) = Empty + +*/ diff --git a/tests/warn/i19416.check b/tests/warn/i19416.check new file mode 100644 index 000000000000..45ffbcd32d08 --- /dev/null +++ b/tests/warn/i19416.check @@ -0,0 +1,4 @@ +-- [E193] Syntax Warning: tests/warn/i19416.scala:2:18 ----------------------------------------------------------------- +2 | @volatile val x: Int = ??? // warn + | ^ + | values cannot be volatile diff --git a/tests/warn/i19416.scala b/tests/warn/i19416.scala new file mode 100644 index 000000000000..9d1249640b07 --- /dev/null +++ b/tests/warn/i19416.scala @@ -0,0 +1,2 @@ +class Foo: + @volatile val x: Int = ??? // warn diff --git a/tests/warn/i19505.scala b/tests/warn/i19505.scala new file mode 100644 index 000000000000..da0f859b24ad --- /dev/null +++ b/tests/warn/i19505.scala @@ -0,0 +1,8 @@ +import scala.annotation.tailrec + +object Foo: + @tailrec + def foo: Int = foo // warn: Infinite recursive call + +object Bar: + export Foo.foo // def foo here should not have `@tailrec` diff --git a/tests/warn/i2333.scala b/tests/warn/i2333.scala new file mode 100644 index 000000000000..1ac5eb314325 --- /dev/null +++ b/tests/warn/i2333.scala @@ -0,0 +1,11 @@ +//> using options -deprecation + +@deprecated("bla", "2.11.0") class Foo { + println("") + def this(x: Int) = this() +} + +object Test { + new Foo // warn: deprecated + new Foo(1) // warn: deprecated +} \ No newline at end of file diff --git a/tests/warn/i2673.scala b/tests/warn/i2673.scala new file mode 100644 index 000000000000..a04e3b370d56 --- /dev/null +++ b/tests/warn/i2673.scala @@ -0,0 +1,6 @@ + + +package Foos + +class Foo // warn +class foo diff --git a/tests/warn/i2673b.scala b/tests/warn/i2673b.scala new file mode 100644 index 000000000000..0d11317cd9e6 --- /dev/null +++ b/tests/warn/i2673b.scala @@ -0,0 +1,7 @@ + + +package Foos + +class Bar // warn +object bar + diff --git a/tests/warn/i2673c.scala b/tests/warn/i2673c.scala new file mode 100644 index 000000000000..682e4adfa2c9 --- /dev/null +++ b/tests/warn/i2673c.scala @@ -0,0 +1,9 @@ + + +package Foos + +object Outer { + case class X() // warn + object x +} + diff --git a/tests/warn/i3324.scala b/tests/warn/i3324.scala new file mode 100644 index 000000000000..ab0c24da39a5 --- /dev/null +++ b/tests/warn/i3324.scala @@ -0,0 +1,6 @@ + + +class Foo { + def foo(x: Any): Boolean = + x.isInstanceOf[List[String]] // warn +} diff --git a/tests/neg/i3561.scala b/tests/warn/i3561.scala similarity index 51% rename from tests/neg/i3561.scala rename to tests/warn/i3561.scala index 862e65f3c2f7..a64a599eafec 100644 --- a/tests/neg/i3561.scala +++ b/tests/warn/i3561.scala @@ -1,18 +1,18 @@ -//> using options -Xfatal-warnings + class Test { val Constant = 'Q' // OK if final - def tokenMe(ch: Char) = (ch: @annotation.switch) match { // error: could not emit switch + def tokenMe(ch: Char) = (ch: @annotation.switch) match { // warn: could not emit switch case ' ' => 1 case 'A' => 2 case '5' | Constant => 3 case '4' => 4 } - def test2(x: Any) = (x: @annotation.switch) match { // error: could not emit switch + def test2(x: Any) = (x: @annotation.switch) match { // warn: could not emit switch case ' ' => 1 case 'A' => 2 case '5' | Constant => 3 case '4' => 4 } -} +} \ No newline at end of file diff --git a/tests/neg/i4008.check b/tests/warn/i4008.check similarity index 80% rename from tests/neg/i4008.check rename to tests/warn/i4008.check index c1f27866d1c1..b72e7a8c20c5 100644 --- a/tests/neg/i4008.check +++ b/tests/warn/i4008.check @@ -1,40 +1,40 @@ --- [E158] Reference Error: tests/neg/i4008.scala:7:56 ------------------------------------------------------------------ -7 |@annotation.implicitNotFound("An implicit ShouldWarn1[${B}] is not in scope") // error +-- [E158] Reference Warning: tests/warn/i4008.scala:7:56 --------------------------------------------------------------- +7 |@annotation.implicitNotFound("An implicit ShouldWarn1[${B}] is not in scope") // warn | ^ | Invalid reference to a type variable `B` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `ShouldWarn1`. --- [E158] Reference Error: tests/neg/i4008.scala:11:56 ----------------------------------------------------------------- -11 |@annotation.implicitNotFound("An implicit ShouldWarn2[${A}] is not in scope") // error +-- [E158] Reference Warning: tests/warn/i4008.scala:11:56 -------------------------------------------------------------- +11 |@annotation.implicitNotFound("An implicit ShouldWarn2[${A}] is not in scope") // warn | ^ | Invalid reference to a type variable `A` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `ShouldWarn2`. --- [E158] Reference Error: tests/neg/i4008.scala:15:56 ----------------------------------------------------------------- -15 |@annotation.implicitNotFound("An implicit ShouldWarn3[${A},${B}] is not in scope") // error +-- [E158] Reference Warning: tests/warn/i4008.scala:15:56 -------------------------------------------------------------- +15 |@annotation.implicitNotFound("An implicit ShouldWarn3[${A},${B}] is not in scope") // warn | ^ | Invalid reference to a type variable `A` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `ShouldWarn3`. --- [E158] Reference Error: tests/neg/i4008.scala:19:56 ----------------------------------------------------------------- -19 |@annotation.implicitNotFound("An implicit ShouldWarn4[${A},${B}] is not in scope") // error // error +-- [E158] Reference Warning: tests/warn/i4008.scala:19:56 -------------------------------------------------------------- +19 |@annotation.implicitNotFound("An implicit ShouldWarn4[${A},${B}] is not in scope") // warn // warn | ^ | Invalid reference to a type variable `A` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `ShouldWarn4`. --- [E158] Reference Error: tests/neg/i4008.scala:19:61 ----------------------------------------------------------------- -19 |@annotation.implicitNotFound("An implicit ShouldWarn4[${A},${B}] is not in scope") // error // error +-- [E158] Reference Warning: tests/warn/i4008.scala:19:61 -------------------------------------------------------------- +19 |@annotation.implicitNotFound("An implicit ShouldWarn4[${A},${B}] is not in scope") // warn // warn | ^ | Invalid reference to a type variable `B` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `ShouldWarn4`. --- [E158] Reference Error: tests/neg/i4008.scala:23:61 ----------------------------------------------------------------- -23 |@annotation.implicitNotFound("An implicit ShouldWarn5[${C},${Abc}] is not in scope") // error +-- [E158] Reference Warning: tests/warn/i4008.scala:23:61 -------------------------------------------------------------- +23 |@annotation.implicitNotFound("An implicit ShouldWarn5[${C},${Abc}] is not in scope") // warn | ^ | Invalid reference to a type variable `Abc` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `ShouldWarn5`. --- [E158] Reference Error: tests/neg/i4008.scala:46:54 ----------------------------------------------------------------- -46 |class C[A](using @annotation.implicitNotFound("No C[${B}] found") c: Class[A]) // error +-- [E158] Reference Warning: tests/warn/i4008.scala:46:54 -------------------------------------------------------------- +46 |class C[A](using @annotation.implicitNotFound("No C[${B}] found") c: Class[A]) // warn | ^ | Invalid reference to a type variable `B` found in the annotation argument. | The variable does not occur as a parameter in the scope of the constructor of `C`. --- [E158] Reference Error: tests/neg/i4008.scala:48:62 ----------------------------------------------------------------- -48 |def someMethod1[A](using @annotation.implicitNotFound("No C[${B}] found") sc: C[A]) = 0 // error +-- [E158] Reference Warning: tests/warn/i4008.scala:48:62 -------------------------------------------------------------- +48 |def someMethod1[A](using @annotation.implicitNotFound("No C[${B}] found") sc: C[A]) = 0 // warn | ^ | Invalid reference to a type variable `B` found in the annotation argument. | The variable does not occur as a parameter in the scope of method `someMethod1`. diff --git a/tests/neg/i4008.scala b/tests/warn/i4008.scala similarity index 86% rename from tests/neg/i4008.scala rename to tests/warn/i4008.scala index 5b851c987e37..489a067bf6fd 100644 --- a/tests/neg/i4008.scala +++ b/tests/warn/i4008.scala @@ -1,26 +1,26 @@ -//> using options -Xfatal-warnings + // ===== Template annotations ===== // class, 1TP, invalid ref -@annotation.implicitNotFound("An implicit ShouldWarn1[${B}] is not in scope") // error +@annotation.implicitNotFound("An implicit ShouldWarn1[${B}] is not in scope") // warn class ShouldWarn1[A] // trait, 1TP, invalid ref -@annotation.implicitNotFound("An implicit ShouldWarn2[${A}] is not in scope") // error +@annotation.implicitNotFound("An implicit ShouldWarn2[${A}] is not in scope") // warn trait ShouldWarn2[B] // trait, 2TP, 1 invalid ref -@annotation.implicitNotFound("An implicit ShouldWarn3[${A},${B}] is not in scope") // error +@annotation.implicitNotFound("An implicit ShouldWarn3[${A},${B}] is not in scope") // warn trait ShouldWarn3[B, C] // class, 2TP, 2 invalid refs -@annotation.implicitNotFound("An implicit ShouldWarn4[${A},${B}] is not in scope") // error // error +@annotation.implicitNotFound("An implicit ShouldWarn4[${A},${B}] is not in scope") // warn // warn class ShouldWarn4[C, D] // class, 2TP, 1 invalid multi-char refs -@annotation.implicitNotFound("An implicit ShouldWarn5[${C},${Abc}] is not in scope") // error +@annotation.implicitNotFound("An implicit ShouldWarn5[${C},${Abc}] is not in scope") // warn class ShouldWarn5[C, D] // trait, 1TP, valid ref @@ -43,8 +43,8 @@ class ShouldntWarn4[Hello, World] @annotation.implicitNotFound("Hopefully you don't see this!") -class C[A](using @annotation.implicitNotFound("No C[${B}] found") c: Class[A]) // error +class C[A](using @annotation.implicitNotFound("No C[${B}] found") c: Class[A]) // warn -def someMethod1[A](using @annotation.implicitNotFound("No C[${B}] found") sc: C[A]) = 0 // error +def someMethod1[A](using @annotation.implicitNotFound("No C[${B}] found") sc: C[A]) = 0 // warn def someMethod2[A](using @annotation.implicitNotFound("No C[${A}] found") sc: C[A]) = "" \ No newline at end of file diff --git a/tests/neg-deep-subtype/i4297.scala b/tests/warn/i4297.scala similarity index 64% rename from tests/neg-deep-subtype/i4297.scala rename to tests/warn/i4297.scala index 88e66c59d1b4..a34c3a5de584 100644 --- a/tests/neg-deep-subtype/i4297.scala +++ b/tests/warn/i4297.scala @@ -1,13 +1,14 @@ -//> using options -Xfatal-warnings + class Test { def test[X <: Option[Int]](x: X) = x.isInstanceOf[Some[Int]] def test1[Y <: Int, X <: Option[Y]](x: X) = x.isInstanceOf[Some[Int]] def test2(x: Any) = x.isInstanceOf[Function1[Nothing, ?]] - def test3a(x: Any) = x.isInstanceOf[Function1[Any, ?]] // error - def test3b(x: Any) = x.isInstanceOf[Function1[Int, ?]] // error - def test4[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, ?]] // error - def test5[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Unit]] // error - def test6[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Any]] // error + def test3a(x: Any) = x.isInstanceOf[Function1[Any, ?]] // warn + def test3b(x: Any) = x.isInstanceOf[Function1[Int, ?]] // warn + def test4[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, ?]] // warn + def test5[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Unit]] // warn + def test6[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[Int, Any]] // warn def test7[Y <: Int, X <: Function1[Y, Unit]](x: X) = x.isInstanceOf[Function1[?, Unit]] } + diff --git a/tests/neg/i4364.scala b/tests/warn/i4364.scala similarity index 61% rename from tests/neg/i4364.scala rename to tests/warn/i4364.scala index 85dca443f6d4..5cfc2ed5076d 100644 --- a/tests/neg/i4364.scala +++ b/tests/warn/i4364.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + object Test { def foo(c: java.util.function.Consumer[Integer]) = c.accept(0) @@ -6,6 +6,6 @@ object Test { def main(args: Array[String]) = { foo(f) // Ok: Consumer is @FunctionalInterface - new java.io.ObjectOutputStream(f) // error: OutputStream is not @FunctionalInterface + new java.io.ObjectOutputStream(f) // warn: OutputStream is not @FunctionalInterface } } diff --git a/tests/warn/i4812.check b/tests/warn/i4812.check new file mode 100644 index 000000000000..a09e91b4c797 --- /dev/null +++ b/tests/warn/i4812.check @@ -0,0 +1,42 @@ +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:8:11 ------------------------------------------------- +8 | case prev: A => // warn: the type test for A cannot be checked at runtime + | ^ + | the type test for A cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:18:11 ------------------------------------------------ +18 | case prev: A => // warn: the type test for A cannot be checked at runtime + | ^ + | the type test for A cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:28:11 ------------------------------------------------ +28 | case prev: A => // warn: the type test for A cannot be checked at runtime + | ^ + | the type test for A cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:38:11 ------------------------------------------------ +38 | case prev: A => // warn: the type test for A cannot be checked at runtime + | ^ + | the type test for A cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:50:13 ------------------------------------------------ +50 | case prev: A => // warn: the type test for A cannot be checked at runtime + | ^ + | the type test for A cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:60:11 ------------------------------------------------ +60 | case prev: A => // warn: the type test for A cannot be checked at runtime + | ^ + | the type test for A cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` +-- [E092] Pattern Match Unchecked Warning: tests/warn/i4812.scala:96:11 ------------------------------------------------ +96 | case x: B => // warn: the type test for B cannot be checked at runtime + | ^ + | the type test for B cannot be checked at runtime because it's a local class + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i4812.scala b/tests/warn/i4812.scala similarity index 79% rename from tests/neg/i4812.scala rename to tests/warn/i4812.scala index c6f6dafc656c..520294491acd 100644 --- a/tests/neg/i4812.scala +++ b/tests/warn/i4812.scala @@ -1,11 +1,11 @@ -//> using options -Werror + object Test: var prev: Any = scala.compiletime.uninitialized def test[T](x: T): T = class A(val elem: (T, Boolean)) prev match - case prev: A => // error: the type test for A cannot be checked at runtime + case prev: A => // warn: the type test for A cannot be checked at runtime prev.elem._1 case _ => prev = new A((x, true)) @@ -15,7 +15,7 @@ object Test: abstract class Parent(_elem: T) { def elem: T = _elem } class A extends Parent(x) prev match - case prev: A => // error: the type test for A cannot be checked at runtime + case prev: A => // warn: the type test for A cannot be checked at runtime prev.elem case _ => prev = new A @@ -25,7 +25,7 @@ object Test: class Holder(val elem: T) class A(val holder: Holder) prev match - case prev: A => // error: the type test for A cannot be checked at runtime + case prev: A => // warn: the type test for A cannot be checked at runtime prev.holder.elem case _ => prev = new A(new Holder(x)) @@ -35,7 +35,7 @@ object Test: class Holder(val elem: (Int, (Unit, (T, Boolean)))) class A { var holder: Holder = null } prev match - case prev: A => // error: the type test for A cannot be checked at runtime + case prev: A => // warn: the type test for A cannot be checked at runtime prev.holder.elem._2._2._1 case _ => val a = new A @@ -47,7 +47,7 @@ object Test: def test5(x: U): U = class A(val elem: U) prev match - case prev: A => // error: the type test for A cannot be checked at runtime + case prev: A => // warn: the type test for A cannot be checked at runtime prev.elem case _ => prev = new A(x) @@ -57,7 +57,7 @@ object Test: class A { var b: B = null } class B { var a: A = null; var elem: T = scala.compiletime.uninitialized } prev match - case prev: A => // error: the type test for A cannot be checked at runtime + case prev: A => // warn: the type test for A cannot be checked at runtime prev.b.elem case _ => val a = new A @@ -93,7 +93,7 @@ object Test: val methodCallId = System.nanoTime() class B(val id: Long) extends A prevA match - case x: B => // error: the type test for B cannot be checked at runtime + case x: B => // warn: the type test for B cannot be checked at runtime x.ensuring(x.id == methodCallId, s"Method call id $methodCallId != ${x.id}") case _ => val x = new B(methodCallId) @@ -116,4 +116,4 @@ object Test: def main(args: Array[String]): Unit = test(1) - val x: String = test("") // was: ClassCastException: java.lang.Integer cannot be cast to java.lang.String + val x: String = test("") // was: ClassCastException: java.lang.Integer cannot be cast to java.lang.String \ No newline at end of file diff --git a/tests/warn/i4936b.scala b/tests/warn/i4936b.scala new file mode 100644 index 000000000000..057c90545dbd --- /dev/null +++ b/tests/warn/i4936b.scala @@ -0,0 +1,3 @@ + + +final object Foo // warn diff --git a/tests/neg/i4986b.check b/tests/warn/i4986b.check similarity index 80% rename from tests/neg/i4986b.check rename to tests/warn/i4986b.check index db30dcba8003..f20b467a295d 100644 --- a/tests/neg/i4986b.check +++ b/tests/warn/i4986b.check @@ -1,40 +1,40 @@ --- [E158] Reference Error: tests/neg/i4986b.scala:5:65 ----------------------------------------------------------------- -5 |@implicitNotFound(msg = "Cannot construct a collection of type ${Too} with elements of type ${Elem} based on a collection of type ${From}.") // error // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:5:65 -------------------------------------------------------------- +5 |@implicitNotFound(msg = "Cannot construct a collection of type ${Too} with elements of type ${Elem} based on a collection of type ${From}.") // warn // warn | ^ | Invalid reference to a type variable `Too` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `Meh`. --- [E158] Reference Error: tests/neg/i4986b.scala:5:94 ----------------------------------------------------------------- -5 |@implicitNotFound(msg = "Cannot construct a collection of type ${Too} with elements of type ${Elem} based on a collection of type ${From}.") // error // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:5:94 -------------------------------------------------------------- +5 |@implicitNotFound(msg = "Cannot construct a collection of type ${Too} with elements of type ${Elem} based on a collection of type ${From}.") // warn // warn | ^ | Invalid reference to a type variable `Elem` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `Meh`. --- [E158] Reference Error: tests/neg/i4986b.scala:8:71 ----------------------------------------------------------------- -8 |@implicitNotFound(msg = "Cannot construct a collection of type ${To} ${Elem}.") // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:8:71 -------------------------------------------------------------- +8 |@implicitNotFound(msg = "Cannot construct a collection of type ${To} ${Elem}.") // warn | ^ | Invalid reference to a type variable `Elem` found in the annotation argument. | The variable does not occur as a parameter in the scope of type `Meh2`. --- [E158] Reference Error: tests/neg/i4986b.scala:11:46 ---------------------------------------------------------------- -11 |class C[T](implicit @implicitNotFound("No C[${t}] available") t: T) // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:11:46 ------------------------------------------------------------- +11 |class C[T](implicit @implicitNotFound("No C[${t}] available") t: T) // warn | ^ | Invalid reference to a type variable `t` found in the annotation argument. | The variable does not occur as a parameter in the scope of the constructor of `C`. --- [E158] Reference Error: tests/neg/i4986b.scala:14:54 ---------------------------------------------------------------- -14 | def m[Aaa](implicit @implicitNotFound("I see no C[${Uuh}]") theC: C[Aaa]) = ??? // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:14:54 ------------------------------------------------------------- +14 | def m[Aaa](implicit @implicitNotFound("I see no C[${Uuh}]") theC: C[Aaa]) = ??? // warn | ^ | Invalid reference to a type variable `Uuh` found in the annotation argument. | The variable does not occur as a parameter in the scope of method `m`. --- [E158] Reference Error: tests/neg/i4986b.scala:20:73 ---------------------------------------------------------------- -20 | def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // error // error // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:20:73 ------------------------------------------------------------- +20 | def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // warn // warn // warn | ^ | Invalid reference to a type variable `XX` found in the annotation argument. | The variable does not occur as a parameter in the scope of method `m`. --- [E158] Reference Error: tests/neg/i4986b.scala:20:79 ---------------------------------------------------------------- -20 | def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // error // error // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:20:79 ------------------------------------------------------------- +20 | def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // warn // warn // warn | ^ | Invalid reference to a type variable `ZZ` found in the annotation argument. | The variable does not occur as a parameter in the scope of method `m`. --- [E158] Reference Error: tests/neg/i4986b.scala:20:86 ---------------------------------------------------------------- -20 | def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // error // error // error +-- [E158] Reference Warning: tests/warn/i4986b.scala:20:86 ------------------------------------------------------------- +20 | def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // warn // warn // warn | ^ | Invalid reference to a type variable `Nix` found in the annotation argument. | The variable does not occur as a parameter in the scope of method `m`. diff --git a/tests/neg/i4986b.scala b/tests/warn/i4986b.scala similarity index 75% rename from tests/neg/i4986b.scala rename to tests/warn/i4986b.scala index c726e40fd4d8..6f2a0885090b 100644 --- a/tests/neg/i4986b.scala +++ b/tests/warn/i4986b.scala @@ -1,22 +1,22 @@ -//> using options -Xfatal-warnings + import scala.annotation.implicitNotFound -@implicitNotFound(msg = "Cannot construct a collection of type ${Too} with elements of type ${Elem} based on a collection of type ${From}.") // error // error +@implicitNotFound(msg = "Cannot construct a collection of type ${Too} with elements of type ${Elem} based on a collection of type ${From}.") // warn // warn trait Meh[-From, +To] -@implicitNotFound(msg = "Cannot construct a collection of type ${To} ${Elem}.") // error +@implicitNotFound(msg = "Cannot construct a collection of type ${To} ${Elem}.") // warn trait Meh2[-From, +To] -class C[T](implicit @implicitNotFound("No C[${t}] available") t: T) // error +class C[T](implicit @implicitNotFound("No C[${t}] available") t: T) // warn trait T { - def m[Aaa](implicit @implicitNotFound("I see no C[${Uuh}]") theC: C[Aaa]) = ??? // error + def m[Aaa](implicit @implicitNotFound("I see no C[${Uuh}]") theC: C[Aaa]) = ??? // warn def n[Aaa](implicit @implicitNotFound("I see no C[${Aaa}]") theC: C[Aaa]) = ??? } trait U[X, Y[_], Z[_, ZZ]] { class I[R] { - def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // error // error // error + def m[S](implicit @implicitNotFound("${X} ${Y} ${ Z } ${R} ${S} -- ${XX} ${ZZ} ${ Nix }") i: Int) = ??? // warn // warn // warn } -} +} \ No newline at end of file diff --git a/tests/warn/i5013.scala b/tests/warn/i5013.scala new file mode 100644 index 000000000000..9fbc32967b78 --- /dev/null +++ b/tests/warn/i5013.scala @@ -0,0 +1,11 @@ + + +class Foo { + + def foo1: Unit = 2 // warn: A pure expression does nothing in statement position + + def foo2: Unit = { + 3 // warn: A pure expression does nothing in statement position + 4 // warn: A pure expression does nothing in statement position + } +} \ No newline at end of file diff --git a/tests/neg/i5013b.scala b/tests/warn/i5013b.scala similarity index 62% rename from tests/neg/i5013b.scala rename to tests/warn/i5013b.scala index 7ccaf47c12f3..09ce319e0a88 100644 --- a/tests/neg/i5013b.scala +++ b/tests/warn/i5013b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + class Foo { @@ -11,8 +11,9 @@ class Foo { val c: Unit = () - def foo1: Unit = a // error: A pure expression does nothing in statement position + def foo1: Unit = a // warn: A pure expression does nothing in statement position def foo2: Unit = b def foo3: Unit = c // Not addapted to { c; () } and hence c is not a statement } + diff --git a/tests/neg/i5077.scala b/tests/warn/i5077.scala similarity index 89% rename from tests/neg/i5077.scala rename to tests/warn/i5077.scala index d705ffe52dd9..404b2cf5a639 100644 --- a/tests/neg/i5077.scala +++ b/tests/warn/i5077.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns trait Is[A] case object IsInt extends Is[Int] case object IsString extends Is[String] @@ -12,7 +12,7 @@ def Test = { // Case 1: error c_string match { - case C(IsInt, _) => println(s"An Int") // error + case C(IsInt, _) => println(s"An Int") // warn case C(IsString, s) => println(s"A String with length ${s.length}") case _ => println("No match") } diff --git a/tests/neg/i6190b.check b/tests/warn/i6190b.check similarity index 65% rename from tests/neg/i6190b.check rename to tests/warn/i6190b.check index 5d4dbd7c24cb..eecf7bbcf13e 100644 --- a/tests/neg/i6190b.check +++ b/tests/warn/i6190b.check @@ -1,4 +1,4 @@ --- Error: tests/neg/i6190b.scala:5:29 ---------------------------------------------------------------------------------- -5 |def foo = List("1", "2").map(Rule) // error +-- Warning: tests/warn/i6190b.scala:5:29 ------------------------------------------------------------------------------- +5 |def foo = List("1", "2").map(Rule) // warn | ^^^^ | The method `apply` is inserted. The auto insertion will be deprecated, please write `Rule.apply` explicitly. diff --git a/tests/warn/i6190b.scala b/tests/warn/i6190b.scala new file mode 100644 index 000000000000..a10006516c6f --- /dev/null +++ b/tests/warn/i6190b.scala @@ -0,0 +1,6 @@ + + +case class Rule(name: String) + +def foo = List("1", "2").map(Rule) // warn + diff --git a/tests/neg/i7314.scala b/tests/warn/i7314.scala similarity index 62% rename from tests/neg/i7314.scala rename to tests/warn/i7314.scala index b865f2ad881b..4d0d525542bf 100644 --- a/tests/neg/i7314.scala +++ b/tests/warn/i7314.scala @@ -1,11 +1,11 @@ -//> using options -Xfatal-warnings -source future +//> using options -source future @main def Test = // conversion out of the opaque type: val imm1 = IArray(1,2,3) // supposedly immutable println(imm1(0)) // 1 imm1 match { - case a: Array[Int] => // error: should not be scrutinized + case a: Array[Int] => // warn: should not be scrutinized a(0) = 0 } println(imm1(0)) // 0 diff --git a/tests/neg/i7821.scala b/tests/warn/i7821.scala similarity index 75% rename from tests/neg/i7821.scala rename to tests/warn/i7821.scala index 5275c06e487f..6ac46ef730bb 100644 --- a/tests/neg/i7821.scala +++ b/tests/warn/i7821.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + object XObject { opaque type X = Int @@ -16,7 +16,7 @@ object MyXObject { def anX: MyX = XObject.anX given ops: Object with { - extension (x: MyX) def + (y: MyX): MyX = x + y // error: warring: Infinite recursive call + extension (x: MyX) def + (y: MyX): MyX = x + y // warn: warring: Infinite recursive call } } diff --git a/tests/warn/i7821b.scala b/tests/warn/i7821b.scala new file mode 100644 index 000000000000..db3de3f86e2f --- /dev/null +++ b/tests/warn/i7821b.scala @@ -0,0 +1,13 @@ + + +object Test { + + { def f(x: Int, y: Int): Int = f(x, y) } // warn + { def f(x: Int, y: Int): Int = { f(x, y) } } // warn + { def f(x: Int, y: Int): Int = f(y, x) } // warn + { def f(x: Int, y: Int): Int = f(x, x) } // warn + { def f(x: Int, y: Int): Int = f(1, 1) } // warn + { def f(x: Int, y: Int): Int = { val a = 3; f(a, 1) } } // warn + { def f(x: Int): Int = f(1) } // warn + +} \ No newline at end of file diff --git a/tests/neg/i8427.scala b/tests/warn/i8427.scala similarity index 63% rename from tests/neg/i8427.scala rename to tests/warn/i8427.scala index 3db449bed41c..61ea2eabb79a 100644 --- a/tests/neg/i8427.scala +++ b/tests/warn/i8427.scala @@ -1,6 +1,6 @@ -//> using options -Xfatal-warnings -@SerialVersionUID(1L) // error + +@SerialVersionUID(1L) // warn trait T object Test { diff --git a/tests/warn/i8781b.scala b/tests/warn/i8781b.scala new file mode 100644 index 000000000000..455cd49b927a --- /dev/null +++ b/tests/warn/i8781b.scala @@ -0,0 +1,8 @@ + + +object Test: + + println((3: Boolean | Int).isInstanceOf[Boolean]) + + println(3.isInstanceOf[Boolean]) // warn + diff --git a/tests/neg/i8922b.scala b/tests/warn/i8922b.scala similarity index 97% rename from tests/neg/i8922b.scala rename to tests/warn/i8922b.scala index 9e615a8d5b58..f167eea005c5 100644 --- a/tests/neg/i8922b.scala +++ b/tests/warn/i8922b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + case class Token(tokenType: TokenType, lexeme: StringV, line: IntV) @@ -33,7 +33,7 @@ object Interpreter { case Binary(left, op, right) => val l = eval(left) val r = eval(right) - (l, r, op.tokenType) match { // error + (l, r, op.tokenType) match { // warn case (l: DoubleV, r: DoubleV, PLUS) => ??? case (l: IntV, r: IntV, PLUS) => ??? case (l: DoubleV, r: IntV, PLUS) => ??? @@ -75,4 +75,4 @@ object Interpreter { } } -} \ No newline at end of file +} diff --git a/tests/warn/i9166.scala b/tests/warn/i9166.scala new file mode 100644 index 000000000000..34a42987f6aa --- /dev/null +++ b/tests/warn/i9166.scala @@ -0,0 +1,8 @@ +//> using options -Wimplausible-patterns +object UnitTest extends App { + def foo(m: Unit) = m match { + case runtime.BoxedUnit.UNIT => println("ok") // warn + } + foo(()) +} + diff --git a/tests/neg/i9241.scala b/tests/warn/i9241.scala similarity index 64% rename from tests/neg/i9241.scala rename to tests/warn/i9241.scala index e7c959fc9ee2..ed1db2df0c8e 100644 --- a/tests/neg/i9241.scala +++ b/tests/warn/i9241.scala @@ -1,10 +1,10 @@ -//> using options -Xfatal-warnings + class Foo { - def unary_~() : Foo = this // error - def unary_-(using Int)(): Foo = this // error - def unary_+()(implicit i: Int): Foo = this // error - def unary_![T](): Foo = this // error + def unary_~() : Foo = this // warn + def unary_-(using Int)(): Foo = this // warn + def unary_+()(implicit i: Int): Foo = this // warn + def unary_![T](): Foo = this // warn } class Bar { @@ -17,27 +17,27 @@ class Bar { final class Baz private (val x: Int) extends AnyVal { def unary_- : Baz = ??? def unary_+[T] : Baz = ??? - def unary_!() : Baz = ??? // error + def unary_!() : Baz = ??? // warn def unary_~(using Int) : Baz = ??? } extension (x: Int) def unary_- : Int = ??? def unary_+[T] : Int = ??? - def unary_!() : Int = ??? // error + def unary_!() : Int = ??? // warn def unary_~(using Int) : Int = ??? end extension extension [T](x: Short) def unary_- : Int = ??? def unary_+[U] : Int = ??? - def unary_!() : Int = ??? // error + def unary_!() : Int = ??? // warn def unary_~(using Int) : Int = ??? end extension extension (using Int)(x: Byte) def unary_- : Int = ??? def unary_+[U] : Int = ??? - def unary_!() : Int = ??? // error + def unary_!() : Int = ??? // warn def unary_~(using Int) : Int = ??? -end extension +end extension \ No newline at end of file diff --git a/tests/neg/i9266.check b/tests/warn/i9266.check similarity index 71% rename from tests/neg/i9266.check rename to tests/warn/i9266.check index bd80a017da02..90dfe43bd2b2 100644 --- a/tests/neg/i9266.check +++ b/tests/warn/i9266.check @@ -1,5 +1,5 @@ --- Error: tests/neg/i9266.scala:5:22 ----------------------------------------------------------------------------------- -5 |def test = { implicit x: Int => x + x } // error +-- Migration Warning: tests/warn/i9266.scala:5:22 ---------------------------------------------------------------------- +5 |def test = { implicit x: Int => x + x } // warn | ^ | This syntax is no longer supported; parameter needs to be enclosed in (...) | This construct can be rewritten automatically under -rewrite -source future-migration. diff --git a/tests/warn/i9266.scala b/tests/warn/i9266.scala new file mode 100644 index 000000000000..c621e9e20b99 --- /dev/null +++ b/tests/warn/i9266.scala @@ -0,0 +1,6 @@ + + +import language.`future-migration` + +def test = { implicit x: Int => x + x } // warn + diff --git a/tests/neg/i9408a.check b/tests/warn/i9408a.check similarity index 76% rename from tests/neg/i9408a.check rename to tests/warn/i9408a.check index d9deb9cddaf7..ed2e94090cae 100644 --- a/tests/neg/i9408a.check +++ b/tests/warn/i9408a.check @@ -1,24 +1,24 @@ --- Error: tests/neg/i9408a.scala:18:20 --------------------------------------------------------------------------------- -18 | val length: Int = "qwerty" // error +-- Migration Warning: tests/warn/i9408a.scala:18:20 -------------------------------------------------------------------- +18 | val length: Int = "qwerty" // warn | ^^^^^^^^ |The conversion (Test3.implicitLength : String => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. --- Error: tests/neg/i9408a.scala:23:20 --------------------------------------------------------------------------------- -23 | val length: Int = "qwerty" // error +-- Migration Warning: tests/warn/i9408a.scala:23:20 -------------------------------------------------------------------- +23 | val length: Int = "qwerty" // warn | ^^^^^^^^ |The conversion (Test4.implicitLength : => String => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. --- Error: tests/neg/i9408a.scala:28:20 --------------------------------------------------------------------------------- -28 | val length: Int = "qwerty" // error +-- Migration Warning: tests/warn/i9408a.scala:28:20 -------------------------------------------------------------------- +28 | val length: Int = "qwerty" // warn | ^^^^^^^^ |The conversion (Test5.implicitLength : [A]: String => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. --- Error: tests/neg/i9408a.scala:33:20 --------------------------------------------------------------------------------- -33 | val length: Int = "qwerty" // error +-- Migration Warning: tests/warn/i9408a.scala:33:20 -------------------------------------------------------------------- +33 | val length: Int = "qwerty" // warn | ^^^^^^^^ |The conversion (Test6.implicitLength : Map[String, Int]) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. --- Error: tests/neg/i9408a.scala:37:60 --------------------------------------------------------------------------------- -37 | implicit def a2int[A](a: A)(implicit ev: A => Int): Int = a // error +-- Migration Warning: tests/warn/i9408a.scala:37:60 -------------------------------------------------------------------- +37 | implicit def a2int[A](a: A)(implicit ev: A => Int): Int = a // warn | ^ |The conversion (ev : A => Int) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. --- Error: tests/neg/i9408a.scala:61:2 ---------------------------------------------------------------------------------- -61 | 123.foo // error +-- Migration Warning: tests/warn/i9408a.scala:61:2 --------------------------------------------------------------------- +61 | 123.foo // warn | ^^^ |The conversion (Test11.a2foo : [A]: A => Test11.Foo) will not be applied implicitly here in Scala 3 because only implicit methods and instances of Conversion class will continue to work as implicit views. diff --git a/tests/neg/i9408a.scala b/tests/warn/i9408a.scala similarity index 88% rename from tests/neg/i9408a.scala rename to tests/warn/i9408a.scala index 594417ec3215..64b58ff59550 100644 --- a/tests/neg/i9408a.scala +++ b/tests/warn/i9408a.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import language.`3.0-migration` import scala.language.implicitConversions @@ -15,26 +15,26 @@ object Test2 { object Test3 { implicit val implicitLength: String => Int = _.length - val length: Int = "qwerty" // error + val length: Int = "qwerty" // warn } object Test4 { implicit def implicitLength: String => Int = _.length - val length: Int = "qwerty" // error + val length: Int = "qwerty" // warn } object Test5 { implicit def implicitLength[A]: String => Int = _.length - val length: Int = "qwerty" // error + val length: Int = "qwerty" // warn } object Test6 { implicit val implicitLength: Map[String, Int] = Map("qwerty" -> 6) - val length: Int = "qwerty" // error + val length: Int = "qwerty" // warn } object Test7 { - implicit def a2int[A](a: A)(implicit ev: A => Int): Int = a // error + implicit def a2int[A](a: A)(implicit ev: A => Int): Int = a // warn } object Test8 { @@ -58,7 +58,7 @@ object Test11 { def foo = "foo" } implicit def a2foo[A]: A => Foo = _ => new Foo {} - 123.foo // error + 123.foo // warn } object Test12 { @@ -85,4 +85,4 @@ object Test15 { implicit def implicitSeq[A]: Seq[A] = ??? def foo(implicit ev: Seq[Int]): Unit = ??? foo -} +} \ No newline at end of file diff --git a/tests/neg/i9740.check b/tests/warn/i9740.check similarity index 76% rename from tests/neg/i9740.check rename to tests/warn/i9740.check index 359603a2863a..7d41bab8ec50 100644 --- a/tests/neg/i9740.check +++ b/tests/warn/i9740.check @@ -1,11 +1,11 @@ --- [E186] Type Error: tests/neg/i9740.scala:10:9 ----------------------------------------------------------------------- -10 | case RecoveryCompleted => println("Recovery completed") // error +-- [E186] Type Warning: tests/warn/i9740.scala:10:9 -------------------------------------------------------------------- +10 | case RecoveryCompleted => println("Recovery completed") // warn | ^^^^^^^^^^^^^^^^^ | Implausible pattern: | RecoveryCompleted could match selector of type object TypedRecoveryCompleted | only if there is an `equals` method identifying elements of the two types. --- [E186] Type Error: tests/neg/i9740.scala:15:9 ----------------------------------------------------------------------- -15 | case RecoveryCompleted => // error +-- [E186] Type Warning: tests/warn/i9740.scala:15:9 -------------------------------------------------------------------- +15 | case RecoveryCompleted => // warn | ^^^^^^^^^^^^^^^^^ | Implausible pattern: | RecoveryCompleted could match selector of type TypedRecoveryCompleted diff --git a/tests/neg/i9740.scala b/tests/warn/i9740.scala similarity index 78% rename from tests/neg/i9740.scala rename to tests/warn/i9740.scala index 6222298df48b..fc330df4d6a9 100644 --- a/tests/neg/i9740.scala +++ b/tests/warn/i9740.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns abstract class RecoveryCompleted object RecoveryCompleted extends RecoveryCompleted @@ -7,11 +7,11 @@ object TypedRecoveryCompleted extends TypedRecoveryCompleted class Test { TypedRecoveryCompleted match { - case RecoveryCompleted => println("Recovery completed") // error + case RecoveryCompleted => println("Recovery completed") // warn case TypedRecoveryCompleted => println("Typed recovery completed") } def foo(x: TypedRecoveryCompleted) = x match - case RecoveryCompleted => // error + case RecoveryCompleted => // warn case TypedRecoveryCompleted => -} +} \ No newline at end of file diff --git a/tests/neg/i9740b.scala b/tests/warn/i9740b.scala similarity index 75% rename from tests/neg/i9740b.scala rename to tests/warn/i9740b.scala index dcd9a1d6a474..632308e3322d 100644 --- a/tests/neg/i9740b.scala +++ b/tests/warn/i9740b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns enum Recovery: case RecoveryCompleted @@ -10,11 +10,11 @@ import TypedRecovery.* class Test { TypedRecoveryCompleted match { - case RecoveryCompleted => println("Recovery completed") // error + case RecoveryCompleted => println("Recovery completed") // warn case TypedRecoveryCompleted => println("Typed recovery completed") } def foo(x: TypedRecovery) = x match - case RecoveryCompleted => // error + case RecoveryCompleted => // warn case TypedRecoveryCompleted => -} +} \ No newline at end of file diff --git a/tests/neg/i9740c.scala b/tests/warn/i9740c.scala similarity index 80% rename from tests/neg/i9740c.scala rename to tests/warn/i9740c.scala index c6a3a1380f1d..8ddf87adf46b 100644 --- a/tests/neg/i9740c.scala +++ b/tests/warn/i9740c.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns sealed trait Exp[T] case class IntExp(x: Int) extends Exp[Int] case class StrExp(x: String) extends Exp[String] @@ -12,6 +12,7 @@ class Foo { def bar[A <: Txn[A]](x: Exp[A]): Unit = x match case IntExp(x) => case StrExp(x) => - case UnitExp => // error + case UnitExp => // warn case Obj(o) => } + diff --git a/tests/neg/i9740d.scala b/tests/warn/i9740d.scala similarity index 67% rename from tests/neg/i9740d.scala rename to tests/warn/i9740d.scala index 6f3cc3be02e2..87c7dc264afa 100644 --- a/tests/neg/i9740d.scala +++ b/tests/warn/i9740d.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -Wimplausible-patterns +//> using options -Wimplausible-patterns sealed trait Exp[T] case class IntExp(x: Int) extends Exp[Int] @@ -8,6 +8,6 @@ object UnitExp extends Exp[Unit] class Foo[U <: Int, T <: U] { def bar[A <: T](x: Exp[A]): Unit = x match case IntExp(x) => - case StrExp(x) => - case UnitExp => // error + case StrExp(x) => // warn + case UnitExp => // warn implausible pattern } diff --git a/tests/warn/i9751.scala b/tests/warn/i9751.scala new file mode 100644 index 000000000000..284070723474 --- /dev/null +++ b/tests/warn/i9751.scala @@ -0,0 +1,11 @@ + + +def f(): Unit = { + () // warn + () +} + +inline def g(): Unit = { + () // warn + () +} \ No newline at end of file diff --git a/tests/neg/i9776.scala b/tests/warn/i9776.scala similarity index 84% rename from tests/neg/i9776.scala rename to tests/warn/i9776.scala index b05488810416..93b7cce98fef 100644 --- a/tests/neg/i9776.scala +++ b/tests/warn/i9776.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.annotation.switch @@ -12,7 +12,7 @@ object Fruit { case object Orange extends Fruit def isCitrus(fruit: Fruit): Boolean = - (fruit: @switch) match { // error Could not emit switch for @switch annotated match + (fruit: @switch) match { // warn Could not emit switch for @switch annotated match case Orange => true case Lemon => true case Lime => true @@ -37,7 +37,7 @@ object TaggedFruit { } def isCitrus(fruit: TaggedFruit): Boolean = - (fruit.tag: @switch) match { // error Could not emit switch for @switch annotated match + (fruit.tag: @switch) match { // warn Could not emit switch for @switch annotated match case Apple.tag => true case 2 => true case 3 => true @@ -58,4 +58,4 @@ object TaggedFruit { case 2 => true case Apple.tag => true } -} +} \ No newline at end of file diff --git a/tests/neg/i9880.scala b/tests/warn/i9880.scala similarity index 81% rename from tests/neg/i9880.scala rename to tests/warn/i9880.scala index f99fae25e5dc..68775e7646a5 100644 --- a/tests/neg/i9880.scala +++ b/tests/warn/i9880.scala @@ -1,9 +1,9 @@ -//> using options -Xfatal-warnings + opaque type Bytes = Array[Byte] object Bytes: extension (self: Bytes) - def size: Int = (self: Array[Byte]).size // error + def size: Int = (self: Array[Byte]).size // warn // @@ -20,7 +20,7 @@ object Module2: object Gen: extension [A](self: Gen[A]) def map[B](f: A => B): Gen[B] = - self.map(f) // error + self.map(f) // warn // @@ -29,4 +29,4 @@ class Sym(val owner: Sym) extension (sym: Sym) def isSomething: Boolean = false def isFoo: Boolean = sym.isSomething && sym.owner.isFoo // was: Infinite loop in function body - def isBar: Boolean = sym.isSomething || sym.owner.isBar // was: Infinite loop in function body + def isBar: Boolean = sym.isSomething || sym.owner.isBar // was: Infinite loop in function body \ No newline at end of file diff --git a/tests/warn/implicit-conversions-old.scala b/tests/warn/implicit-conversions-old.scala new file mode 100644 index 000000000000..24e1124015e3 --- /dev/null +++ b/tests/warn/implicit-conversions-old.scala @@ -0,0 +1,25 @@ +//> using options -feature + +class A +class B + +object A { + + implicit def a2b(x: A): B = ??? // warn under -Xfatal-warnings -feature + + implicit def b2a(x: B): A = ??? // warn under -Xfatal-warnings -feature +} + +class C + +object D { + implicit def a2c(x: A): C = ??? // warn under -Xfatal-warnings -feature +} + +object Test { + import D.* + + val x1: A = new B + val x2: B = new A // ok, since it's an old-style comversion + val x3: C = new A // ok, since it's an old-style comversion +} \ No newline at end of file diff --git a/tests/neg/implicit-conversions.scala b/tests/warn/implicit-conversions.scala similarity index 55% rename from tests/neg/implicit-conversions.scala rename to tests/warn/implicit-conversions.scala index ead8c5ac7646..946d0c96fd5a 100644 --- a/tests/neg/implicit-conversions.scala +++ b/tests/warn/implicit-conversions.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -feature +//> using options -feature class A class B @@ -25,7 +25,7 @@ object D { object Test { import D.given - val x1: A = new B // error under -Xfatal-warnings -feature - val x2: B = new A // error under -Xfatal-warnings -feature - val x3: C = new A // error under -Xfatal-warnings -feature + val x1: A = new B // warn under -Xfatal-warnings -feature + val x2: B = new A // warn under -Xfatal-warnings -feature + val x3: C = new A // warn under -Xfatal-warnings -feature } \ No newline at end of file diff --git a/tests/neg/inline-givens.scala b/tests/warn/inline-givens.scala similarity index 57% rename from tests/neg/inline-givens.scala rename to tests/warn/inline-givens.scala index 3e388de2ce8b..5ab4fd65fdc9 100644 --- a/tests/neg/inline-givens.scala +++ b/tests/warn/inline-givens.scala @@ -1,16 +1,15 @@ -//> using options -Xfatal-warnings + class Item(x: String) inline given a: Conversion[String, Item] = - Item(_) // error + Item(_) // warn inline given b: Conversion[String, Item] = - (x => Item(x)) // error + (x => Item(x)) // warn inline given c: Conversion[String, Item] = - { x => Item(x) } // error + { x => Item(x) } // warn inline given d: Conversion[String, Item] with - def apply(x: String) = Item(x) // ok - + def apply(x: String) = Item(x) // ok \ No newline at end of file diff --git a/tests/warn/looping-givens.scala b/tests/warn/looping-givens.scala new file mode 100644 index 000000000000..6b6a32002331 --- /dev/null +++ b/tests/warn/looping-givens.scala @@ -0,0 +1,9 @@ +class A +class B + +given joint(using a: A, b: B): (A & B) = ??? + +def foo(using a: A, b: B) = + given aa: A = summon // warn + given bb: B = summon // warn + given ab: (A & B) = summon // warn diff --git a/tests/warn/main-functions-nameclash.scala b/tests/warn/main-functions-nameclash.scala new file mode 100644 index 000000000000..bc0fe64379d4 --- /dev/null +++ b/tests/warn/main-functions-nameclash.scala @@ -0,0 +1,5 @@ + + +object foo { + @main def foo(x: Int) = () // warn: class foo and object foo produce classes that overwrite one another +} diff --git a/tests/neg/manifest-summoning-b.check b/tests/warn/manifest-summoning-b.check similarity index 73% rename from tests/neg/manifest-summoning-b.check rename to tests/warn/manifest-summoning-b.check index bb63eebb555f..590b27ddbd98 100644 --- a/tests/neg/manifest-summoning-b.check +++ b/tests/warn/manifest-summoning-b.check @@ -1,12 +1,12 @@ --- Error: tests/neg/manifest-summoning-b.scala:3:34 -------------------------------------------------------------------- -3 |val foo = manifest[List[? <: Int]] // error +-- Deprecation Warning: tests/warn/manifest-summoning-b.scala:3:34 ----------------------------------------------------- +3 |val foo = manifest[List[? <: Int]] // warn | ^ | Compiler synthesis of Manifest and OptManifest is deprecated, instead | replace with the type `scala.reflect.ClassTag[List[? <: Int]]`. | Alternatively, consider using the new metaprogramming features of Scala 3, | see https://docs.scala-lang.org/scala3/reference/metaprogramming.html --- Error: tests/neg/manifest-summoning-b.scala:4:41 -------------------------------------------------------------------- -4 |val bar = optManifest[Array[? <: String]] // error +-- Deprecation Warning: tests/warn/manifest-summoning-b.scala:4:41 ----------------------------------------------------- +4 |val bar = optManifest[Array[? <: String]] // warn | ^ | Compiler synthesis of Manifest and OptManifest is deprecated, instead | replace with the type `scala.reflect.ClassTag[Array[? <: String]]`. diff --git a/tests/warn/manifest-summoning-b.scala b/tests/warn/manifest-summoning-b.scala new file mode 100644 index 000000000000..18ddec1250b5 --- /dev/null +++ b/tests/warn/manifest-summoning-b.scala @@ -0,0 +1,4 @@ +//> using options -deprecation + +val foo = manifest[List[? <: Int]] // warn +val bar = optManifest[Array[? <: String]] // warn \ No newline at end of file diff --git a/tests/warn/matchable.scala b/tests/warn/matchable.scala new file mode 100644 index 000000000000..8adcdcf1c90a --- /dev/null +++ b/tests/warn/matchable.scala @@ -0,0 +1,28 @@ +//> using options -source future + +def foo[T](x: T): Matchable = + println(x.getClass()) // ok + println(x.isInstanceOf[Int]) // ok + x match + case x: Int => // warn: should not be scrutinized + println("int") + x + case x: String => // warn: should not be scrutinized + println("string") + x + List(x) match + case (x: Int) :: Nil => // warn: should not be scrutinized + println("int") + x + case List(x: String) => // warn: should not be scrutinized + println("string") + x + case List(y :: Nil) => // warn: should not be scrutinized + y :: Nil + case _ => + x // warn: should not be scrutinized + +@main def Test = + val x: Matchable = foo(1) + val y: Matchable = foo("hello") + assert(x != y) \ No newline at end of file diff --git a/tests/neg/newline-braces.scala b/tests/warn/newline-braces.scala similarity index 55% rename from tests/neg/newline-braces.scala rename to tests/warn/newline-braces.scala index afe7731f3095..9ec2961ee30d 100644 --- a/tests/neg/newline-braces.scala +++ b/tests/warn/newline-braces.scala @@ -1,8 +1,9 @@ -//> using options -source 3.0-migration -Xfatal-warnings +//> using options -source 3.0-migration def f: List[Int] = { List(1, 2, 3).map // no newline inserted here in Scala-2 compat mode - { x => // error (migration) + { x => // warn (migration) x + 1 } } + diff --git a/tests/neg/nonunit-statement.scala b/tests/warn/nonunit-statement.scala similarity index 80% rename from tests/neg/nonunit-statement.scala rename to tests/warn/nonunit-statement.scala index 94346031077c..f90deb647d6e 100644 --- a/tests/neg/nonunit-statement.scala +++ b/tests/warn/nonunit-statement.scala @@ -1,4 +1,5 @@ -//> using options -Xfatal-warnings -Wnonunit-statement -Wvalue-discard -source:3.3 +//> using options -Wnonunit-statement -Wvalue-discard -source:3.3 + import collection.ArrayOps import collection.mutable.{ArrayBuilder, LinkedHashSet, ListBuffer} import concurrent._ @@ -9,38 +10,38 @@ class C { def c = { def improved = Future(42) def stale = Future(27) - improved // error + improved // warn stale } } class D { def d = { class E - new E().toString // error + new E().toString // warn new E().toString * 2 } } class F { import ExecutionContext.Implicits._ - Future(42) // error + Future(42) // warn } // unused template expression uses synthetic method of class case class K(s: String) { - copy() // error + copy() // warn } // mutations returning this are ok class Mutate { val b = ListBuffer.empty[Int] b += 42 // nowarn, returns this.type val xs = List(42) - 27 +: xs // error + 27 +: xs // warn def f(x: Int): this.type = this def g(): Unit = f(42) // nowarn } // some uninteresting expressions may warn for other reasons class WhoCares { - null // error for purity + null // warn for purity ??? // nowarn for impurity } // explicit Unit ascription to opt out of warning, even for funky applies @@ -50,15 +51,15 @@ class Absolution { // Future(42): Unit // nowarn { F(42)(ctx) }: Unit where annot is on F(42) // f(42): Unit // nowarn } -// warn uni-branched unless user disables it with -Wnonunit-if:false + class Boxed[A](a: A) { def isEmpty = false def foreach[U](f: A => U): Unit = - if (!isEmpty) f(a) // error (if) + if (!isEmpty) f(a) // warn (if) def forall(f: A => Boolean): Unit = if (!isEmpty) { println(".") - f(a) // error (if) + f(a) // warn (if) } def take(p: A => Boolean): Option[A] = { while (isEmpty || !p(a)) () @@ -69,20 +70,20 @@ class Unibranch[A, B] { def runWith[U](action: B => U): A => Boolean = { x => val z = null.asInstanceOf[B] val fellback = false - if (!fellback) action(z) // error (if) + if (!fellback) action(z) // warn (if) !fellback } def f(i: Int): Int = { def g = 17 if (i < 42) { - g // error block statement + g // warn block statement println("uh oh") - g // error (if) + g // warn (if) } while (i < 42) { - g // error + g // warn println("uh oh") - g // error + g // warn } 42 } @@ -92,7 +93,7 @@ class Dibranch { def j: Int = ??? def f(b: Boolean): Int = { // if-expr might have an uninteresting LUB - if (b) { // error, at least one branch looks interesting + if (b) { // warn, at least one branch looks interesting println("true") i } @@ -112,7 +113,7 @@ class Next[A] { class Setting[A] { def set = LinkedHashSet.empty[A] def f(a: A): Unit = { - set += a // error because cannot know whether the `set` was supposed to be consumed or assigned + set += a // warn because cannot know whether the `set` was supposed to be consumed or assigned println(set) } } @@ -122,27 +123,27 @@ class Strung { def iterator = Iterator.empty[String] def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = { val jsb = b.underlying - if (start.length != 0) jsb.append(start) // error (value-discard) + if (start.length != 0) jsb.append(start) // warn (value-discard) val it = iterator if (it.hasNext) { jsb.append(it.next()) while (it.hasNext) { jsb.append(sep) // nowarn (java) - jsb.append(it.next()) // error (value-discard) + jsb.append(it.next()) // warn (value-discard) } } - if (end.length != 0) jsb.append(end) // error (value-discard) + if (end.length != 0) jsb.append(end) // warn (value-discard) b } def f(b: java.lang.StringBuilder, it: Iterator[String]): String = { while (it.hasNext) { b.append("\n") // nowarn (java) - b.append(it.next()) // error (value-discard) + b.append(it.next()) // warn (value-discard) } b.toString } def g(b: java.lang.StringBuilder, it: Iterator[String]): String = { - while (it.hasNext) it.next() // error + while (it.hasNext) it.next() // warn b.toString } } @@ -195,4 +196,4 @@ class Depends { f(d) () } -} +} \ No newline at end of file diff --git a/tests/warn/old-syntax.scala b/tests/warn/old-syntax.scala new file mode 100644 index 000000000000..d584e3692a0a --- /dev/null +++ b/tests/warn/old-syntax.scala @@ -0,0 +1,5 @@ +//> using options -deprecation + +val f = (x: Int) ⇒ x + 1 // warn + +val list = for (n ← List(42)) yield n + 1 // warn \ No newline at end of file diff --git a/tests/neg/opaque-match.scala b/tests/warn/opaque-match.scala similarity index 63% rename from tests/neg/opaque-match.scala rename to tests/warn/opaque-match.scala index 59d0836fb2a3..06cca835ab91 100644 --- a/tests/neg/opaque-match.scala +++ b/tests/warn/opaque-match.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + case class C() @@ -12,17 +12,13 @@ def Test[T] = O.x match case _: C => ??? // ok C() match - case _: O.T => ??? // error + case _: O.T => ??? // warn C() match - case _: T => ??? // error + case _: T => ??? // warn (??? : Any) match - case _: List[O.T] => ??? // error + case _: List[O.T] => ??? // warn (??? : Any) match case _: List[O.T @unchecked] => ??? // OK (??? : Any) match - case _: List[T] => ??? // error - - - - + case _: List[T] => ??? // warn diff --git a/tests/neg-deep-subtype/or-type-trees.scala b/tests/warn/or-type-trees.scala similarity index 79% rename from tests/neg-deep-subtype/or-type-trees.scala rename to tests/warn/or-type-trees.scala index d0338ffe6066..0e8569576796 100644 --- a/tests/neg-deep-subtype/or-type-trees.scala +++ b/tests/warn/or-type-trees.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + object Test1 { trait Tree @@ -9,7 +9,7 @@ object Test1 { def foo2(myTree: Tree | (Context => Tree)) = myTree match - case treeFn: (Context => Tree) => // error + case treeFn: (Context => Tree) => // warn case _ => def foo3(myTree: Tree | (Context => Tree)) = @@ -25,12 +25,12 @@ object Test2 { trait Type def foo1(myTree: Tree[Type] | (Context => Tree[Type])) = - println(myTree.isInstanceOf[Tree[Type]]) // error + println(myTree.isInstanceOf[Tree[Type]]) // warn /* class DummyTree extends Tree[Nothing] with (Context => Tree[Type]) */ def foo2(myTree: Tree[Type] | (Context => Tree[Type])) = myTree match - case treeFn: (Context => Tree[Type]) => // error + case treeFn: (Context => Tree[Type]) => // warn case _ => def foo3(myTree: Tree[Type] | (Context => Tree[Type])) = diff --git a/tests/warn/ovlazy.scala b/tests/warn/ovlazy.scala new file mode 100644 index 000000000000..1dfa284a00c9 --- /dev/null +++ b/tests/warn/ovlazy.scala @@ -0,0 +1,9 @@ +//> using options -source 3.0-migration + +class A { + val x: Int = 1 +} +class B extends A { + override lazy val x: Int = 2 // warn +} + diff --git a/tests/neg/private-this-3.4.check b/tests/warn/private-this-3.4.check similarity index 52% rename from tests/neg/private-this-3.4.check rename to tests/warn/private-this-3.4.check index 29c2fe909ede..2ba2fea549d1 100644 --- a/tests/neg/private-this-3.4.check +++ b/tests/warn/private-this-3.4.check @@ -1,12 +1,14 @@ --- Error: tests/neg/private-this-3.4.scala:6:16 ------------------------------------------------------------------------ -6 | private[this] def foo: Int = ??? // error: migration warning +-- Warning: tests/warn/private-this-3.4.scala:4:16 --------------------------------------------------------------------- +4 | private[this] def foo: Int = ??? // warn: migration warning | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. --- Error: tests/neg/private-this-3.4.scala:7:18 ------------------------------------------------------------------------ -7 | protected[this] def bar: Int = ??? // error: migration warning +-- Warning: tests/warn/private-this-3.4.scala:5:18 --------------------------------------------------------------------- +5 | protected[this] def bar: Int = ??? // warn: migration warning | ^ - | The [this] qualifier will be deprecated in the future; it should be dropped. + | 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. diff --git a/tests/warn/private-this-3.4.scala b/tests/warn/private-this-3.4.scala new file mode 100644 index 000000000000..1270eba116bc --- /dev/null +++ b/tests/warn/private-this-3.4.scala @@ -0,0 +1,5 @@ +import scala.language.`3.4` + +class Foo: + private[this] def foo: Int = ??? // warn: migration warning + protected[this] def bar: Int = ??? // warn: migration warning diff --git a/tests/warn/private-this-future-migration.scala b/tests/warn/private-this-future-migration.scala new file mode 100644 index 000000000000..d719187e534a --- /dev/null +++ b/tests/warn/private-this-future-migration.scala @@ -0,0 +1,5 @@ +import scala.language.`future-migration` + +class Foo: + private[this] def foo: Int = ??? // warn: migration warning + protected[this] def bar: Int = ??? // warn: migration warning diff --git a/tests/warn/quote-simple-hole.scala b/tests/warn/quote-simple-hole.scala new file mode 100644 index 000000000000..f23d2c0535c4 --- /dev/null +++ b/tests/warn/quote-simple-hole.scala @@ -0,0 +1,17 @@ + + +import scala.quoted.Quotes + +def test(using Quotes) = { + val x = '{0} + val y = '{ // warn: Canceled splice directly inside a quote. '{ ${ XYZ } } is equivalent to XYZ. + $x + } + val z = '{ + val a = ${ // warn: Canceled quote directly inside a splice. ${ '{ XYZ } } is equivalent to XYZ. + '{ + $y + } + } + } +} \ No newline at end of file diff --git a/tests/neg-deep-subtype/refined-types.scala b/tests/warn/refined-types.scala similarity index 66% rename from tests/neg-deep-subtype/refined-types.scala rename to tests/warn/refined-types.scala index 5f5cc5a45f04..1ef0f84c00d4 100644 --- a/tests/neg-deep-subtype/refined-types.scala +++ b/tests/warn/refined-types.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + class A class B extends A @@ -18,7 +18,7 @@ def bl(x: AA) = x.isInstanceOf[BL] // was: the type test for BL cannot be checke def bu(x: AA) = x.isInstanceOf[BU] // was: the type test for BU cannot be checked at runtime // but static knowledge of only one bound makes checking against an alias unchecked: -def al_ba(x: AL) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime -def au_ba(x: AU) = x.isInstanceOf[BA] // error: the type test for BA cannot be checked at runtime -def al_bu(x: AL) = x.isInstanceOf[BU] // error: the type test for BU cannot be checked at runtime -def au_bl(x: AU) = x.isInstanceOf[BL] // error: the type test for BL cannot be checked at runtime +def al_ba(x: AL) = x.isInstanceOf[BA] // warn: the type test for BA cannot be checked at runtime +def au_ba(x: AU) = x.isInstanceOf[BA] // warn: the type test for BA cannot be checked at runtime +def al_bu(x: AL) = x.isInstanceOf[BU] // warn: the type test for BU cannot be checked at runtime +def au_bl(x: AU) = x.isInstanceOf[BL] // warn: the type test for BL cannot be checked at runtime \ No newline at end of file diff --git a/tests/warn/refinements-this.scala b/tests/warn/refinements-this.scala new file mode 100644 index 000000000000..3e4c64cf1e59 --- /dev/null +++ b/tests/warn/refinements-this.scala @@ -0,0 +1,6 @@ + + +class Outer: + type X = { type O = Outer.this.type } // ok + type Y = { type O = this.type } // warn + diff --git a/tests/neg/rewrite-messages.check b/tests/warn/rewrite-messages.check similarity index 76% rename from tests/neg/rewrite-messages.check rename to tests/warn/rewrite-messages.check index b062ab2bc732..d7147239cded 100644 --- a/tests/neg/rewrite-messages.check +++ b/tests/warn/rewrite-messages.check @@ -1,10 +1,10 @@ --- Error: tests/neg/rewrite-messages.scala:3:18 ------------------------------------------------------------------------ -3 |import scala.util._ // error +-- Migration Warning: tests/warn/rewrite-messages.scala:3:18 ----------------------------------------------------------- +3 |import scala.util._ // warn | ^ | `_` is no longer supported for a wildcard import; use `*` instead | This construct can be rewritten automatically under -rewrite -source future-migration. --- Error: tests/neg/rewrite-messages.scala:7:4 ------------------------------------------------------------------------- -7 | 2 foo 4 // error +-- Migration Warning: tests/warn/rewrite-messages.scala:7:4 ------------------------------------------------------------ +7 | 2 foo 4 // warn | ^^^ | Alphanumeric method foo is not declared infix; it should not be used as infix operator. | Instead, use method syntax .foo(...) or backticked identifier `foo`. diff --git a/tests/warn/rewrite-messages.scala b/tests/warn/rewrite-messages.scala new file mode 100644 index 000000000000..88166f8e8ac2 --- /dev/null +++ b/tests/warn/rewrite-messages.scala @@ -0,0 +1,8 @@ +//> using options -source:future-migration -deprecation + +import scala.util._ // warn + +object Test { + extension (x: Int) def foo(y: Int) = x + y + 2 foo 4 // warn +} \ No newline at end of file diff --git a/tests/neg/i15503-scala2/scala2-t11681.scala b/tests/warn/scala2-t11681.scala similarity index 90% rename from tests/neg/i15503-scala2/scala2-t11681.scala rename to tests/warn/scala2-t11681.scala index 2436668e0c9c..ae2187181ceb 100644 --- a/tests/neg/i15503-scala2/scala2-t11681.scala +++ b/tests/warn/scala2-t11681.scala @@ -1,5 +1,5 @@ -//> using options -Xfatal-warnings -Wunused:params -// +//> using options -Wunused:params + import Answers._ @@ -10,7 +10,7 @@ trait InterFace { trait BadAPI extends InterFace { private def f(a: Int, - b: String, // error + b: String, // warn c: Double): Int = { println(c) a @@ -47,10 +47,9 @@ trait BadAPI extends InterFace { // mustn't alter warnings in super trait PoorClient extends BadAPI { override def meth(x: Int) = ??? // OK - override def f(a: Int, b: String, c: Double): Int = a + b.toInt + c.toInt } -class Unusing(u: Int) { // error +class Unusing(u: Int) { // warn def f = ??? } @@ -107,4 +106,4 @@ object Answers { def answer: Int = 42 } -val a$1 = 2 \ No newline at end of file +val a$1 = 2 diff --git a/tests/warn/strict-pattern-bindings-3.2.scala b/tests/warn/strict-pattern-bindings-3.2.scala new file mode 100644 index 000000000000..e4df8e770a01 --- /dev/null +++ b/tests/warn/strict-pattern-bindings-3.2.scala @@ -0,0 +1,37 @@ + +// These tests should fail under -Xfatal-warnings with source version source version 3.2 or later +import language.`3.2` + +object Test: + // from filtering-fors.scala + val xs: List[AnyRef] = ??? + + for ((x: String) <- xs) do () // warn + for (y@ (x: String) <- xs) do () // warn + for ((x, y) <- xs) do () // warn + + for ((x: String) <- xs if x.isEmpty) do () // warn + for ((x: String) <- xs; y = x) do () // warn + for ((x: String) <- xs; (y, z) <- xs) do () // warn // warn + for (case (x: String) <- xs; (y, z) <- xs) do () // warn + for ((x: String) <- xs; case (y, z) <- xs) do () // warn + + val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) + for ((x, y) <- pairs) yield (y, x) // warn + + // from unchecked-patterns.scala + val y :: ys = List(1, 2, 3) // warn + val (1, c) = (1, 2) // warn + val 1 *: cs = 1 *: Tuple() // warn + + val (_: Int | _: AnyRef) = ??? : AnyRef // warn + + val 1 = 2 // warn + + object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } + object Always1 { def unapply(i: Int): Some[Int] = Some(i) } + object Pair { def unapply(t: (Int, Int)): t.type = t } + object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } + + val Positive(p) = 5 // warn + val Some(s1) = Option(1) // warn \ No newline at end of file diff --git a/tests/neg/supertraits-b.scala b/tests/warn/supertraits-b.scala similarity index 69% rename from tests/neg/supertraits-b.scala rename to tests/warn/supertraits-b.scala index 78854537974e..b36fcb5634b7 100644 --- a/tests/neg/supertraits-b.scala +++ b/tests/warn/supertraits-b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + transparent sealed trait TA transparent sealed trait TB @@ -16,20 +16,20 @@ object Test: choose0(a, b) match case _: TA => ??? - case _: TB => ??? // error: unreachable + case _: TB => ??? // warn: unreachable choose1(a, b) match case _: TA => ??? - case _: TB => ??? // error: unreachable + case _: TB => ??? // warn: unreachable choose2(a, b) match case _: TB => ??? - case _: TA => ??? // error: unreachable + case _: TA => ??? // warn: unreachable choose3(a, b) match case _: Product => ??? - case _: TA => ??? // error: unreachable + case _: TA => ??? // warn: unreachable choose4(a, b) match case _: (TA & TB) => ??? - case _: Product => ??? // error: unreachable \ No newline at end of file + case _: Product => ??? // warn: unreachable \ No newline at end of file diff --git a/tests/neg/switches.scala b/tests/warn/switches.scala similarity index 77% rename from tests/neg/switches.scala rename to tests/warn/switches.scala index d405f8185706..9b45e3ed0d51 100644 --- a/tests/neg/switches.scala +++ b/tests/warn/switches.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.annotation.switch @@ -38,7 +38,7 @@ object Main { // multiple annotations are processed correctly // thinks a val in an object is constant... so naive - def fail1(c: Char) = (c: @switch @unchecked) match { // error: Could not emit switch for @switch annotated match + def fail1(c: Char) = (c: @switch @unchecked) match { // warn: Could not emit switch for @switch annotated match case 'A' => true case 'B' => true case Other.C1 => true @@ -46,7 +46,7 @@ object Main { } // more naivete - def fail2(c: Char) = (c: @unchecked @switch) match { // error: Could not emit switch for @switch annotated match + def fail2(c: Char) = (c: @unchecked @switch) match { // warn: Could not emit switch for @switch annotated match case 'A' => true case 'B' => true case Other.C3 => true @@ -69,12 +69,12 @@ object Main { case _ => -1 } - def fail3(x: Any) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail3(x: Any) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case 1 | 2 | 3 => true case _ => false } - def fail4(x: AnyVal) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail4(x: AnyVal) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case 1 | 2 | 3 => true case _ => false } @@ -82,7 +82,7 @@ object Main { case class IntAnyVal(x: Int) extends AnyVal val Ten = IntAnyVal(10) - def fail5(x: IntAnyVal) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail5(x: IntAnyVal) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case IntAnyVal(1) => 0 case Ten => 1 case IntAnyVal(100) => 2 @@ -92,11 +92,11 @@ object Main { // the generated lookupswitch covers only a subset of the cases final val One = IntAnyVal(1) - def fail6(x: IntAnyVal) = (x: @switch) match { // error: Could not emit switch for @switch annotated match + def fail6(x: IntAnyVal) = (x: @switch) match { // warn: Could not emit switch for @switch annotated match case One => 0 case IntAnyVal(10) => 1 case IntAnyVal(100) => 2 case IntAnyVal(1000) => 3 case IntAnyVal(10000) => 4 } -} +} \ No newline at end of file diff --git a/tests/neg/symbolic-packages.check b/tests/warn/symbolic-packages.check similarity index 65% rename from tests/neg/symbolic-packages.check rename to tests/warn/symbolic-packages.check index 8e9b7e114829..c1d56f67eba7 100644 --- a/tests/neg/symbolic-packages.check +++ b/tests/warn/symbolic-packages.check @@ -1,16 +1,16 @@ --- Error: tests/neg/symbolic-packages.scala:3:8 ------------------------------------------------------------------------ -3 |package `with spaces` { // error +-- Warning: tests/warn/symbolic-packages.scala:3:8 --------------------------------------------------------------------- +3 |package `with spaces` { // warn | ^^^^^^^^^^^^^ | The package name `with spaces` will be encoded on the classpath, and can lead to undefined behaviour. --- Error: tests/neg/symbolic-packages.scala:7:10 ----------------------------------------------------------------------- -7 |package +.* { // error // error +-- Warning: tests/warn/symbolic-packages.scala:7:10 -------------------------------------------------------------------- +7 |package +.* { // warn // warn | ^ | The package name `*` will be encoded on the classpath, and can lead to undefined behaviour. --- Error: tests/neg/symbolic-packages.scala:7:8 ------------------------------------------------------------------------ -7 |package +.* { // error // error +-- Warning: tests/warn/symbolic-packages.scala:7:8 --------------------------------------------------------------------- +7 |package +.* { // warn // warn | ^ | The package name `+` will be encoded on the classpath, and can lead to undefined behaviour. --- Error: tests/neg/symbolic-packages.scala:11:16 ---------------------------------------------------------------------- -11 |package object `mixed_*` { // error +-- Warning: tests/warn/symbolic-packages.scala:11:16 ------------------------------------------------------------------- +11 |package object `mixed_*` { // warn | ^^^^^^^ | The package name `mixed_*` will be encoded on the classpath, and can lead to undefined behaviour. diff --git a/tests/warn/symbolic-packages.scala b/tests/warn/symbolic-packages.scala new file mode 100644 index 000000000000..6e0ef04da6bb --- /dev/null +++ b/tests/warn/symbolic-packages.scala @@ -0,0 +1,13 @@ + + +package `with spaces` { // warn + class Foo +} + +package +.* { // warn // warn + class Bar +} + +package object `mixed_*` { // warn + class Baz +} \ No newline at end of file diff --git a/tests/neg-deep-subtype/t2755.scala b/tests/warn/t2755.scala similarity index 91% rename from tests/neg-deep-subtype/t2755.scala rename to tests/warn/t2755.scala index ec3cb6aadefc..1aeb06d237d1 100644 --- a/tests/neg-deep-subtype/t2755.scala +++ b/tests/warn/t2755.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + // Test cases: the only place we can cut and paste without crying // ourself to sleep. @@ -19,7 +19,7 @@ object Test { case x: Array[String] => x.size case x: Array[AnyRef] => 5 case x: Array[?] => 6 - case _ => 7 // error: only null is matched + case _ => 7 // warn: only null is matched } def f3[T](a: Array[T]) = a match { case x: Array[Int] => x(0) @@ -28,7 +28,7 @@ object Test { case x: Array[String] => x.size case x: Array[AnyRef] => 5 case x: Array[?] => 6 - case _ => 7 // error: only null is matched + case _ => 7 // warn: only null is matched } @@ -57,4 +57,4 @@ object Test { println(f3(Array(1L))) println(f3(null)) } -} +} \ No newline at end of file diff --git a/tests/neg/t3235-minimal.check b/tests/warn/t3235-minimal.check similarity index 75% rename from tests/neg/t3235-minimal.check rename to tests/warn/t3235-minimal.check index 83c287f85bc0..dcd28466f729 100644 --- a/tests/neg/t3235-minimal.check +++ b/tests/warn/t3235-minimal.check @@ -1,16 +1,16 @@ --- Error: tests/neg/t3235-minimal.scala:5:21 --------------------------------------------------------------------------- -5 | assert(123456789.round == 123456789) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:5:21 ------------------------------------------------------------ +5 | assert(123456789.round == 123456789) // warn | ^^^^^^^^^^^^^^^ |method round in class RichInt is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? --- Error: tests/neg/t3235-minimal.scala:6:16 --------------------------------------------------------------------------- -6 | assert(math.round(123456789) == 123456789) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:6:16 ------------------------------------------------------------ +6 | assert(math.round(123456789) == 123456789) // warn | ^^^^^^^^^^ |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? --- Error: tests/neg/t3235-minimal.scala:7:32 --------------------------------------------------------------------------- -7 | assert(1234567890123456789L.round == 1234567890123456789L) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:7:32 ------------------------------------------------------------ +7 | assert(1234567890123456789L.round == 1234567890123456789L) // warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |method round in class RichLong is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? --- Error: tests/neg/t3235-minimal.scala:8:16 --------------------------------------------------------------------------- -8 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // error +-- Deprecation Warning: tests/warn/t3235-minimal.scala:8:16 ------------------------------------------------------------ +8 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // warn | ^^^^^^^^^^ |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? diff --git a/tests/neg/t3235-minimal.scala b/tests/warn/t3235-minimal.scala similarity index 51% rename from tests/neg/t3235-minimal.scala rename to tests/warn/t3235-minimal.scala index f65ee13f87f5..22e6da9f31a0 100644 --- a/tests/neg/t3235-minimal.scala +++ b/tests/warn/t3235-minimal.scala @@ -1,10 +1,10 @@ -//> using options -Xfatal-warnings -deprecation +//> using options -deprecation object Test { def main(args: Array[String]): Unit = { - assert(123456789.round == 123456789) // error - assert(math.round(123456789) == 123456789) // error - assert(1234567890123456789L.round == 1234567890123456789L) // error - assert(math.round(1234567890123456789L) == 1234567890123456789L) // error + assert(123456789.round == 123456789) // warn + assert(math.round(123456789) == 123456789) // warn + assert(1234567890123456789L.round == 1234567890123456789L) // warn + assert(math.round(1234567890123456789L) == 1234567890123456789L) // warn } -} +} \ No newline at end of file diff --git a/tests/neg/t5830.scala b/tests/warn/t5830.scala similarity index 63% rename from tests/neg/t5830.scala rename to tests/warn/t5830.scala index 947b7bac4a22..41cdfb1059a7 100644 --- a/tests/neg/t5830.scala +++ b/tests/warn/t5830.scala @@ -1,11 +1,11 @@ -//> using options -Xfatal-warnings + import scala.annotation.switch class Test { def unreachable(ch: Char) = (ch: @switch) match { case 'a' => println("b") // ok - case 'a' => println("b") // error: unreachable case + case 'a' => println("b") // warn: unreachable case case 'c' => } } diff --git a/tests/neg-deep-subtype/type-lambda.scala b/tests/warn/type-lambda.scala similarity index 71% rename from tests/neg-deep-subtype/type-lambda.scala rename to tests/warn/type-lambda.scala index 4c4627fe1cf3..788647496a4f 100644 --- a/tests/neg-deep-subtype/type-lambda.scala +++ b/tests/warn/type-lambda.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + trait A[T] trait B[T] extends A[T] @@ -10,7 +10,7 @@ object Test { } def bar(x: ([X] =>> A[X])[Any]) = x match { - case x: ([X] =>> B[Nothing])[Any] => // error + case x: ([X] =>> B[Nothing])[Any] => // warn case _ => } } diff --git a/tests/neg/type-test-paths-2.scala b/tests/warn/type-test-paths-2.scala similarity index 61% rename from tests/neg/type-test-paths-2.scala rename to tests/warn/type-test-paths-2.scala index 4bba2f87416e..79b22fa70049 100644 --- a/tests/neg/type-test-paths-2.scala +++ b/tests/warn/type-test-paths-2.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -29,15 +29,15 @@ object Test { val r2: R = RI r1.n match { - case n: r2.Nat => // error: the type test for Test.r2.Nat cannot be checked at runtime - case n: r1.Idx => // error: the type test for Test.r1.Idx cannot be checked at runtime + case n: r2.Nat => // warn: the type test for Test.r2.Nat cannot be checked at runtime + case n: r1.Idx => // warn: the type test for Test.r1.Idx cannot be checked at runtime case n: r1.Succ => // Ok case n: r1.Nat => // Ok } r1.one match { - case n: r2.Nat => // error: the type test for Test.r2.Nat cannot be checked at runtime - case n: r1.Idx => // error: the type test for Test.r1.Idx cannot be checked at runtime + case n: r2.Nat => // warn: the type test for Test.r2.Nat cannot be checked at runtime + case n: r1.Idx => // warn: the type test for Test.r1.Idx cannot be checked at runtime case n: r1.Nat => // Ok } -} +} \ No newline at end of file diff --git a/tests/neg/type-test-paths.scala b/tests/warn/type-test-paths.scala similarity index 88% rename from tests/neg/type-test-paths.scala rename to tests/warn/type-test-paths.scala index 324ed43ba7fa..03501cfd5957 100644 --- a/tests/neg/type-test-paths.scala +++ b/tests/warn/type-test-paths.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -8,7 +8,7 @@ object Test { val p2: T = T1 (p1.y: p1.X) match { - case x: p2.Y => // error: unchecked + case x: p2.Y => // warn: unchecked case x: p1.Y => case _ => } diff --git a/tests/neg/type-test-syntesize-b.scala b/tests/warn/type-test-syntesize-b.scala similarity index 74% rename from tests/neg/type-test-syntesize-b.scala rename to tests/warn/type-test-syntesize-b.scala index b5402eb92c66..ba8ffb8318b7 100644 --- a/tests/neg/type-test-syntesize-b.scala +++ b/tests/warn/type-test-syntesize-b.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings + import scala.reflect.TypeTest @@ -19,13 +19,13 @@ object Test { test[Any, Array[Int]] test[Seq[Int], List[Int]] - test[Any, Some[Int]] // error - test[Any, a.X] // error - test[a.X, a.Y] // error + test[Any, Some[Int]] // warn + test[Any, a.X] // warn + test[a.X, a.Y] // warn } class A { type X type Y <: X -} +} \ No newline at end of file diff --git a/tests/neg/uninitialized-3.4.check b/tests/warn/uninitialized-3.4.check similarity index 75% rename from tests/neg/uninitialized-3.4.check rename to tests/warn/uninitialized-3.4.check index 1c7b985072d0..ddf4bfed85ed 100644 --- a/tests/neg/uninitialized-3.4.check +++ b/tests/warn/uninitialized-3.4.check @@ -1,5 +1,5 @@ --- Error: tests/neg/uninitialized-3.4.scala:7:15 ----------------------------------------------------------------------- -7 | var a: Int = _ // error: migration warning +-- Warning: tests/warn/uninitialized-3.4.scala:5:15 -------------------------------------------------------------------- +5 | var a: Int = _ // warn | ^ | `= _` has been deprecated; use `= uninitialized` instead. | `uninitialized` can be imported with `scala.compiletime.uninitialized`. diff --git a/tests/neg/uninitialized-3.4.scala b/tests/warn/uninitialized-3.4.scala similarity index 60% rename from tests/neg/uninitialized-3.4.scala rename to tests/warn/uninitialized-3.4.scala index 174a95ae6c54..966f2e51af1c 100644 --- a/tests/neg/uninitialized-3.4.scala +++ b/tests/warn/uninitialized-3.4.scala @@ -1,8 +1,6 @@ -//> using options -Werror - import scala.language.`3.4` import scala.compiletime.uninitialized class Foo: - var a: Int = _ // error: migration warning + var a: Int = _ // warn var b: Int = uninitialized diff --git a/tests/neg/uninitialized-future-migration.scala b/tests/warn/uninitialized-future-migration.scala similarity index 62% rename from tests/neg/uninitialized-future-migration.scala rename to tests/warn/uninitialized-future-migration.scala index 05f7c6b67f38..7c24f2466221 100644 --- a/tests/neg/uninitialized-future-migration.scala +++ b/tests/warn/uninitialized-future-migration.scala @@ -1,8 +1,6 @@ -//> using options -Werror - import scala.language.`future-migration` import scala.compiletime.uninitialized class Foo: - var a: Int = _ // error: migration warning + var a: Int = _ // warn: migration warning var b: Int = uninitialized diff --git a/tests/warn/warn-value-discard.check b/tests/warn/warn-value-discard.check new file mode 100644 index 000000000000..ca6fedb29053 --- /dev/null +++ b/tests/warn/warn-value-discard.check @@ -0,0 +1,20 @@ +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:27:36 ------------------------------------------- +27 | mutable.Set.empty[String].remove("") // warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | discarded non-Unit value of type Boolean +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:39:41 ------------------------------------------- +39 | mutable.Set.empty[String].subtractOne("") // warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | discarded non-Unit value of type scala.collection.mutable.Set[String] +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:59:4 -------------------------------------------- +59 | mutable.Set.empty[String] += "" // warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | discarded non-Unit value of type scala.collection.mutable.Set[String] +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:15:35 ------------------------------------------- +15 | firstThing().map(_ => secondThing()) // warn + | ^^^^^^^^^^^^^ + | discarded non-Unit value of type Either[Failed, Unit] +-- [E175] Potential Issue Warning: tests/warn/warn-value-discard.scala:18:35 ------------------------------------------- +18 | firstThing().map(_ => secondThing()) // warn + | ^^^^^^^^^^^^^ + | discarded non-Unit value of type Either[Failed, Unit] diff --git a/tests/neg/warn-value-discard.scala b/tests/warn/warn-value-discard.scala similarity index 84% rename from tests/neg/warn-value-discard.scala rename to tests/warn/warn-value-discard.scala index fb01fdeda384..8bb9aebf515b 100644 --- a/tests/neg/warn-value-discard.scala +++ b/tests/warn/warn-value-discard.scala @@ -1,4 +1,4 @@ -//> using options -Wvalue-discard -Werror +//> using options -Wvalue-discard import scala.util.{Either, Right, Left} import scala.collection.mutable @@ -12,10 +12,10 @@ def secondThing(): Either[Failed, Unit] = Left(Failed("whoops you should have flatMapped me")) def singleExpr(): Either[Failed, Unit] = - firstThing().map(_ => secondThing()) // error + firstThing().map(_ => secondThing()) // warn def block(): Either[Failed, Unit] = { - firstThing().map(_ => secondThing()) // error + firstThing().map(_ => secondThing()) // warn } class ValueDiscardTest: @@ -24,7 +24,7 @@ class ValueDiscardTest: def remove(): Unit = // Set#remove returns a Boolean, not this.type // --> Warning - mutable.Set.empty[String].remove("") // error + mutable.Set.empty[String].remove("") // warn // TODO IMHO we don't need to support this, // as it's just as easy to add a @nowarn annotation as a Unit ascription @@ -36,7 +36,7 @@ class ValueDiscardTest: // - Set#subtractOne returns this.type // - receiver is not a field or a local variable (not quite sure what you'd call it) // --> Warning - mutable.Set.empty[String].subtractOne("") // error + mutable.Set.empty[String].subtractOne("") // warn def mutateLocalVariable(): Unit = { // - Set#subtractOne returns this.type @@ -56,11 +56,11 @@ class ValueDiscardTest: // - += returns this.type // - receiver is not a field or a local variable // --> Warning - mutable.Set.empty[String] += "" // error + mutable.Set.empty[String] += "" // warn def assignmentOperatorLocalVariable(): Unit = // - += returns this.type // - receiver is a local variable // --> No warning val s: mutable.Set[String] = mutable.Set.empty[String] - s += "" + s += "" \ No newline at end of file diff --git a/tests/neg/with-type-operator-future-migration.check b/tests/warn/with-type-operator-future-migration.check similarity index 61% rename from tests/neg/with-type-operator-future-migration.check rename to tests/warn/with-type-operator-future-migration.check index e56049880431..2842592bee64 100644 --- a/tests/neg/with-type-operator-future-migration.check +++ b/tests/warn/with-type-operator-future-migration.check @@ -1,5 +1,5 @@ --- [E003] Syntax Error: tests/neg/with-type-operator-future-migration.scala:5:13 --------------------------------------- -5 |def foo: Int with String = ??? // error +-- [E003] Syntax Migration Warning: tests/warn/with-type-operator-future-migration.scala:5:13 -------------------------- +5 |def foo: Int with String = ??? // warn | ^^^^ | with as a type operator has been deprecated; use & instead | This construct can be rewritten automatically under -rewrite -source 3.4-migration. diff --git a/tests/warn/with-type-operator-future-migration.scala b/tests/warn/with-type-operator-future-migration.scala new file mode 100644 index 000000000000..42b029665565 --- /dev/null +++ b/tests/warn/with-type-operator-future-migration.scala @@ -0,0 +1,6 @@ + + +import scala.language.`future-migration` + +def foo: Int with String = ??? // warn + diff --git a/tests/neg/xfatalWarnings.scala b/tests/warn/xfatalWarnings.scala similarity index 69% rename from tests/neg/xfatalWarnings.scala rename to tests/warn/xfatalWarnings.scala index 3f49e159cbc4..7e77ac468370 100644 --- a/tests/neg/xfatalWarnings.scala +++ b/tests/warn/xfatalWarnings.scala @@ -1,9 +1,9 @@ -//> using options -Xfatal-warnings + object xfatalWarnings { val opt:Option[String] = Some("test") - opt match { // error when running with -Xfatal-warnings + opt match { // warn case None => } @@ -11,3 +11,5 @@ object xfatalWarnings { while (true) {} // should be ok. no "pure expression does nothing in statement position" issued. } } + +// When running with fatal warnings: