diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000000..665facd6239 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,3 @@ +# hashes of reformat commits +7353a97cb8211e480ee7e740c7f0b7aa74f334ba + diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5b6c64fc76d..010be4b0746 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,10 +2,10 @@ name: Test on: push: - branches: [master, staging, trying] + branches: [master, rewrite-2023, staging, trying] paths-ignore: 'docs/**' pull_request: - branches: [master] + branches: [master, rewrite-2023] paths-ignore: 'docs/**' # Cancel previous runs in a PR when pushing new commits @@ -85,130 +85,34 @@ jobs: # Run a subset of the tests that used to fail often. # The goal here is to fail fast and give quick feedback to the developers. # This job intentionally doesn't use the verification cache. - quick-tests: - runs-on: ubuntu-latest - env: - PRUSTI_CACHE_PATH: ${{ github.workspace }}/prusti_cache.bin - steps: - - name: Check out the repo - uses: actions/checkout@v2 - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: '15' - - name: Set up the environment - run: python x.py setup - - name: Cache cargo - uses: Swatinem/rust-cache@v2 - with: - shared-key: "shared" - - name: Build with cargo - run: python x.py build --all - - name: Run quick tests - run: python x.py test --all quick - - # Run a subset of the tests with the purification optimization enabled - # to ensure that we do not introduce regressions. - purification-tests: - needs: [fmt-check, clippy-check, check-deps, smir-check, quick-tests] - runs-on: ubuntu-latest - env: - PRUSTI_ENABLE_PURIFICATION_OPTIMIZATION: true - PRUSTI_CACHE_PATH: ${{ github.workspace }}/prusti_cache.bin - steps: - - name: Check out the repo - uses: actions/checkout@v2 - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: '15' - - name: Set up the environment - run: python x.py setup - - name: Cache cargo - uses: Swatinem/rust-cache@v2 - with: - shared-key: "shared" - - name: Prepare verification cache keys - shell: bash - run: | - VER_CACHE_KEY_SHARED=prusti-cache-$(cat viper-toolchain)-$(date +%Y-%m) - echo "VER_CACHE_KEY_SHARED=$VER_CACHE_KEY_SHARED" >> $GITHUB_ENV - echo "VER_CACHE_KEY_UNIQUE=$VER_CACHE_KEY_SHARED-${RANDOM}${RANDOM}" >> $GITHUB_ENV - - name: Load verification cache - uses: actions/cache@v3 - with: - path: ${{ env.PRUSTI_CACHE_PATH }} - # Use a unique key, so that the job will always store the cache at the end of the run - key: ${{ env.VER_CACHE_KEY_UNIQUE }} - # Restore from the most recent cache that matches a shared prefix of the key - restore-keys: ${{ env.VER_CACHE_KEY_SHARED }} - - name: Build with cargo - run: python x.py build --all - - name: Run quick tests - run: | - python x.py verify-test prusti-tests/tests/verify/pass/rosetta/Knuth_shuffle.rs - # python x.py test --all pass/rosetta/Binary_search_shared.rs - # python x.py test --all pass/demos/account.rs - # python x.py test --all pass/rosetta/Knights_tour.rs - # python x.py test --all pass/quick/fold-unfold.rs - # python x.py test --all pass/quick/moves.rs - # python x.py test --all pass/quick/mut-borrows.rs - # python x.py test --all pass/quick/shared-borrows.rs - # python x.py test --all pass/quick/trait-contracts-refinement.rs - # python x.py test --all pass/quick/fibonacci.rs - # python x.py test --all pass/pure-fn/len-lookup.rs - # python x.py test --all pass/pure-fn/quantifiers.rs - # python x.py test --all pass/pure-fn/recursive-pure-fn.rs - # python x.py test --all pass/pure-fn/ref-mut-arg.rs - # python x.py test --all pass/rosetta/Ackermann_function.rs - # python x.py test --all pass/rosetta/Heapsort.rs - - name: Run with purification. - env: - PRUSTI_VIPER_BACKEND: silicon - PRUSTI_VERIFY_SPECIFICATIONS_BACKEND: silicon - PRUSTI_VERIFY_CORE_PROOF: true - PRUSTI_VERIFY_SPECIFICATIONS: true - PRUSTI_VERIFY_SPECIFICATIONS_WITH_CORE_PROOF: false - PRUSTI_INLINE_CALLER_FOR: false - run: | - python x.py test core_proof - - name: Run with purification with Carbon. - env: - PRUSTI_VIPER_BACKEND: silicon - PRUSTI_VERIFY_SPECIFICATIONS_BACKEND: carbon - PRUSTI_VERIFY_CORE_PROOF: true - PRUSTI_VERIFY_SPECIFICATIONS: true - PRUSTI_VERIFY_SPECIFICATIONS_WITH_CORE_PROOF: false - PRUSTI_INLINE_CALLER_FOR: false - run: | - python x.py test core_proof - - name: Run without purification. - env: - PRUSTI_VIPER_BACKEND: silicon - PRUSTI_VERIFY_SPECIFICATIONS_BACKEND: silicon - PRUSTI_VERIFY_CORE_PROOF: true - PRUSTI_VERIFY_SPECIFICATIONS: true - PRUSTI_VERIFY_SPECIFICATIONS_WITH_CORE_PROOF: true - PRUSTI_INLINE_CALLER_FOR: false - run: | - python x.py test core_proof - - name: Inline caller for functions - env: - PRUSTI_VIPER_BACKEND: silicon - PRUSTI_VERIFY_SPECIFICATIONS_BACKEND: silicon - PRUSTI_VERIFY_CORE_PROOF: true - PRUSTI_VERIFY_SPECIFICATIONS: true - PRUSTI_VERIFY_SPECIFICATIONS_WITH_CORE_PROOF: false - PRUSTI_INLINE_CALLER_FOR: true - run: | - python x.py test core_proof + #quick-tests: + # runs-on: ubuntu-latest + # env: + # PRUSTI_CACHE_PATH: ${{ github.workspace }}/prusti_cache.bin + # steps: + # - name: Check out the repo + # uses: actions/checkout@v2 + # - name: Set up Java + # uses: actions/setup-java@v1 + # with: + # java-version: '15' + # - name: Set up the environment + # run: python x.py setup + # - name: Cache cargo + # uses: Swatinem/rust-cache@v2 + # with: + # shared-key: "shared" + # - name: Build with cargo + # run: python x.py build --all + # - name: Run quick tests + # run: python x.py test --all quick # Run all the tests. all-tests: - needs: [fmt-check, clippy-check, check-deps, smir-check, quick-tests] + needs: [fmt-check, clippy-check, check-deps, smir-check] # , quick-tests] strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest] # , windows-latest, macos-latest] fail-fast: false runs-on: ${{ matrix.os }} env: @@ -247,83 +151,50 @@ jobs: - name: Build with cargo run: python x.py build --all - name: Run cargo tests - run: python x.py test --all - - name: Run a subset of tests with Carbon - run: | - python x.py test pass/no-annotation --all --verbose - env: - PRUSTI_VIPER_BACKEND: carbon + run: python x.py test -p prusti-tests + #run: python x.py test --all - name: Check prusti-contracts run: | cd prusti-contracts/prusti-contracts-test/ cargo +stable build - # Run Prusti on itself. - # Disabled because of a bug when compiling jni-gen - test-on-prusti: - needs: [fmt-check, clippy-check, check-deps, smir-check, quick-tests] - runs-on: ubuntu-latest - if: false - steps: - - name: Check out the repo - uses: actions/checkout@v2 - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: '15' - - name: Set up the environment - run: python x.py setup - - name: Cache cargo - uses: Swatinem/rust-cache@v2 - with: - shared-key: "shared" - - name: Build with cargo - run: python x.py build --release --all - - name: Run cargo-prusti on Prusti - run: python x.py exec target/release/cargo-prusti - env: - PRUSTI_SKIP_UNSUPPORTED_FEATURES: true - PRUSTI_FULL_COMPILATION: true - PRUSTI_CHECK_PANICS: false - PRUSTI_CHECK_OVERFLOWS: false - PRUSTI_INTERNAL_ERRORS_AS_WARNINGS: true - # Test cargo-prusti on a collection of crates. - test-crates: - needs: [fmt-check, clippy-check, check-deps, smir-check, quick-tests] - runs-on: ubuntu-22.04 - strategy: - matrix: - shard_index: [0, 1, 2, 3] - steps: - - name: Check out the repo - uses: actions/checkout@v2 - - name: Setup Python 3 - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: '15' - - name: Set up the environment - run: python x.py setup - - name: Cache cargo - uses: Swatinem/rust-cache@v2 - with: - shared-key: "shared" - - name: Build with cargo --release - run: | - python x.py build --release -p prusti - python x.py build --release -p prusti-launch - python x.py build --release -p test-crates - - name: Test Prusti on a collection of crates - run: ./target/release/test-crates --fail-fast --num-shards=4 --shard-index=${{ matrix.shard_index }} + #test-crates: + # needs: [fmt-check, clippy-check, check-deps, smir-check, quick-tests] + # runs-on: ubuntu-22.04 + # if: false # disabled for v2 for now + # strategy: + # matrix: + # shard_index: [0, 1, 2, 3] + # steps: + # - name: Check out the repo + # uses: actions/checkout@v2 + # - name: Setup Python 3 + # uses: actions/setup-python@v2 + # with: + # python-version: '3.x' + # - name: Set up Java + # uses: actions/setup-java@v1 + # with: + # java-version: '15' + # - name: Set up the environment + # run: python x.py setup + # - name: Cache cargo + # uses: Swatinem/rust-cache@v2 + # with: + # shared-key: "shared" + # - name: Build with cargo --release + # run: | + # python x.py build --release -p prusti + # python x.py build --release -p prusti-launch + # python x.py build --release -p test-crates + # - name: Test Prusti on a collection of crates + # run: ./target/release/test-crates --fail-fast --num-shards=4 --shard-index=${{ matrix.shard_index }} # Dummy job to specify the jobs that must pass before merging on master can-merge: runs-on: ubuntu-latest - needs: [all-tests, purification-tests, test-crates] + needs: [all-tests] #, test-crates] # Always run, even if the workflow was cancelled if: ${{ always() }} steps: diff --git a/Cargo.lock b/Cargo.lock index 6039cba9535..6b63e85dfa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,16 @@ dependencies = [ "libc", ] +[[package]] +name = "annotate-snippets" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e35ed54e5ea7997c14ed4c70ba043478db1112e98263b3b035907aa197d991" +dependencies = [ + "anstyle", + "unicode-width", +] + [[package]] name = "anstream" version = "0.6.11" @@ -107,6 +117,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + [[package]] name = "async-attributes" version = "1.1.2" @@ -307,7 +323,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -398,6 +414,17 @@ dependencies = [ "tracing 0.1.40", ] +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "regex-automata 0.4.8", + "serde", +] + [[package]] name = "bumpalo" version = "3.14.0" @@ -416,13 +443,45 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" -version = "1.0.83" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ - "libc", + "shlex", ] [[package]] @@ -480,7 +539,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -489,12 +548,49 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + [[package]] name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "combine" version = "4.6.6" @@ -505,6 +601,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "comma" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335" + [[package]] name = "concurrent-queue" version = "2.3.0" @@ -534,6 +636,19 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "const-random" version = "0.1.18" @@ -604,14 +719,20 @@ dependencies = [ ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-channel" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", + "crossbeam-utils", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crunchy" version = "0.2.2" @@ -709,6 +830,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -784,6 +911,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -924,7 +1061,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -1206,6 +1343,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "2.5.0" @@ -1216,6 +1359,19 @@ dependencies = [ "hashbrown 0.14.2", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "instant" version = "0.1.12" @@ -1335,6 +1491,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + [[package]] name = "libc" version = "0.2.150" @@ -1379,9 +1541,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -1557,6 +1719,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.32.1" @@ -1595,7 +1763,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -1632,6 +1800,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pad" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" +dependencies = [ + "unicode-width", +] + [[package]] name = "parking" version = "2.2.0" @@ -1681,7 +1864,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -1712,7 +1895,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -1774,12 +1957,28 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "prettydiff" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abec3fb083c10660b3854367697da94c674e9e82aa7511014dc958beeb7215e9" +dependencies = [ + "owo-colors", + "pad", +] + [[package]] name = "proc-macro-tracing" version = "0.1.0" @@ -1791,9 +1990,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -1918,6 +2117,21 @@ dependencies = [ "uuid", ] +[[package]] +name = "prusti-tests" +version = "0.2.0" +dependencies = [ + "ctrlc", + "env_logger", + "log", + "prusti", + "prusti-launch", + "prusti-server", + "regex", + "ui_test", + "ureq", +] + [[package]] name = "prusti-utils" version = "0.1.0" @@ -1947,9 +2161,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1995,14 +2209,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -2016,13 +2230,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.5", ] [[package]] @@ -2033,9 +2247,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -2137,6 +2351,18 @@ dependencies = [ "semver", ] +[[package]] +name = "rustfix" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f5b7fc8060f4f8373f9381a630304b42e1183535d9beb1d3f596b236c9106a" +dependencies = [ + "serde", + "serde_json", + "thiserror", + "tracing 0.1.40", +] + [[package]] name = "rustix" version = "0.37.27" @@ -2244,7 +2470,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -2275,34 +2501,38 @@ name = "semver" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] [[package]] name = "serde" -version = "1.0.193" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -2359,6 +2589,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2411,6 +2647,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "spanned" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86af297923fbcfd107c20a189a6e9c872160df71a7190ae4a7a6c5dce4b2feb6" +dependencies = [ + "bstr", + "color-eyre", +] + [[package]] name = "spin" version = "0.9.8" @@ -2436,9 +2682,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -2497,22 +2743,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -2715,7 +2961,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -2739,6 +2985,16 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing 0.1.40", + "tracing-subscriber", +] + [[package]] name = "tracing-log" version = "0.2.0" @@ -2805,6 +3061,32 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "ui_test" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180a1250feba0214b892e22c3a14e9f6688cc084d7b45ec4672106fcb7914641" +dependencies = [ + "annotate-snippets", + "anyhow", + "bstr", + "cargo-platform", + "cargo_metadata", + "color-eyre", + "colored", + "comma", + "crossbeam-channel", + "indicatif", + "levenshtein", + "prettydiff", + "regex", + "rustc_version", + "rustfix", + "serde", + "serde_json", + "spanned", +] + [[package]] name = "unicase" version = "2.7.0" @@ -2841,6 +3123,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "untrusted" version = "0.9.0" @@ -2980,7 +3268,7 @@ name = "vir-proc-macro" version = "0.1.0" dependencies = [ "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -3066,7 +3354,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -3100,7 +3388,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3182,7 +3470,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -3202,17 +3490,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3223,9 +3512,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3235,9 +3524,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3247,9 +3536,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3259,9 +3554,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3271,9 +3566,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3283,9 +3578,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3295,9 +3590,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -3344,5 +3639,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] diff --git a/Cargo.toml b/Cargo.toml index 8a4e4fef6f7..660a0d67191 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ members = [ "prusti", "prusti-contracts-build", "prusti-encoder", - # "prusti-tests", + "prusti-tests", "prusti-utils", "prusti-viper", "tracing", diff --git a/analysis/Cargo.toml b/analysis/Cargo.toml index 03af388fc0e..800a3449dcf 100644 --- a/analysis/Cargo.toml +++ b/analysis/Cargo.toml @@ -21,3 +21,5 @@ glob = "0.3" [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] rustc_private = true + +[workspace] diff --git a/jni-gen/src/generators/module.rs b/jni-gen/src/generators/module.rs index 7cd436e64cb..eaa500c8ae8 100644 --- a/jni-gen/src/generators/module.rs +++ b/jni-gen/src/generators/module.rs @@ -41,7 +41,7 @@ pub fn generate_module(class_names: Vec<&ClassName>) -> String { }) .unwrap_or_else(|| "// No modules".to_string()); - vec![ + [ "//! Automatically generated code\n".to_string(), "#![allow(non_snake_case)]\n".to_string(), "pub mod builtins;\n".to_string(), diff --git a/mir-state-analysis/src/free_pcs/impl/triple.rs b/mir-state-analysis/src/free_pcs/impl/triple.rs index 350f5a65bf8..f8a62e2dd4a 100644 --- a/mir-state-analysis/src/free_pcs/impl/triple.rs +++ b/mir-state-analysis/src/free_pcs/impl/triple.rs @@ -6,7 +6,7 @@ use prusti_rustc_interface::{ hir::Mutability, - middle::mir::{FakeBorrowKind, + middle::mir::{ visit::Visitor, BorrowKind, Local, Location, Operand, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, RETURN_PLACE, }, @@ -81,7 +81,7 @@ impl<'tcx> Visitor<'tcx> for Fpcs<'_, 'tcx> { | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => (), - Return | TailCall {.. } => { + Return | TailCall { .. } => { let always_live = self.repacker.always_live_locals(); for local in 0..self.repacker.local_count() { let local = Local::from_usize(local); diff --git a/mir-state-analysis/src/utils/mutable.rs b/mir-state-analysis/src/utils/mutable.rs index 555649fa831..2e84f59a2fd 100644 --- a/mir-state-analysis/src/utils/mutable.rs +++ b/mir-state-analysis/src/utils/mutable.rs @@ -114,7 +114,7 @@ impl<'tcx> Place<'tcx> { } } } - TyKind::RawPtr(t, m) => { + TyKind::RawPtr(_t, m) => { match m { // `*const` raw pointers are not mutable hir::Mutability::Not => Err(self), diff --git a/mir-state-analysis/src/utils/place.rs b/mir-state-analysis/src/utils/place.rs index 4e9fead880f..613893769f5 100644 --- a/mir-state-analysis/src/utils/place.rs +++ b/mir-state-analysis/src/utils/place.rs @@ -219,7 +219,7 @@ impl Debug for Place<'_> { write!(fmt, "(*").unwrap(); } ProjectionElem::Field(_, _) - | ProjectionElem::Subtype(_) + | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {} diff --git a/prusti-contracts/prusti-contracts/src/lib.rs b/prusti-contracts/prusti-contracts/src/lib.rs index 09450ca50af..9b60b7d7fc0 100644 --- a/prusti-contracts/prusti-contracts/src/lib.rs +++ b/prusti-contracts/prusti-contracts/src/lib.rs @@ -129,7 +129,7 @@ mod private { use core::{marker::PhantomData, ops::*}; /// A macro for defining a closure with a specification. - pub use prusti_contracts_proc_macros::{closure, pure, trusted}; + pub use prusti_contracts_proc_macros::{closure, pure}; pub fn prusti_set_union_active_field(_arg: T) { unreachable!(); @@ -342,7 +342,7 @@ pub fn old(arg: T) -> T { /// Universal quantifier. /// /// This is a Prusti-internal representation of the `forall` syntax. -#[prusti::builtin="forall"] +#[cfg_attr(feature = "prusti", prusti::builtin = "forall")] pub fn forall(_trigger_set: T, _closure: &F) -> bool { true } @@ -350,6 +350,7 @@ pub fn forall(_trigger_set: T, _closure: &F) -> bool { /// Existential quantifier. /// /// This is a Prusti-internal representation of the `exists` syntax. +#[cfg_attr(feature = "prusti", prusti::builtin = "exists")] pub fn exists(_trigger_set: T, _closure: F) -> bool { true } @@ -365,7 +366,7 @@ pub fn snap(_x: &T) -> T { /// `PartialEq` nor `Copy` implementation. The in-memory representation is /// constructed recursively: references are followed, unsafe pointers and cells /// are not. Importantly, addresses are not taken into consideration. -#[prusti::builtin="snapshot_equality"] +#[cfg_attr(feature = "prusti", prusti::builtin = "snapshot_equality")] pub fn snapshot_equality(_l: T, _r: T) -> bool { true } diff --git a/prusti-contracts/prusti-specs/src/common.rs b/prusti-contracts/prusti-specs/src/common.rs index 787eef8f21b..978cf6d27d4 100644 --- a/prusti-contracts/prusti-specs/src/common.rs +++ b/prusti-contracts/prusti-specs/src/common.rs @@ -62,57 +62,36 @@ mod syn_extensions { /// Abstraction over everything that has a [syn::Signature] pub(crate) trait HasSignature { fn sig(&self) -> &Signature; - fn sig_mut(&mut self) -> &mut Signature; } impl HasSignature for Signature { fn sig(&self) -> &Signature { self } - - fn sig_mut(&mut self) -> &mut Signature { - self - } } impl HasSignature for ImplItemMethod { fn sig(&self) -> &Signature { &self.sig } - - fn sig_mut(&mut self) -> &mut Signature { - &mut self.sig - } } impl HasSignature for ItemFn { fn sig(&self) -> &Signature { &self.sig } - - fn sig_mut(&mut self) -> &mut Signature { - &mut self.sig - } } impl HasSignature for TraitItemMethod { fn sig(&self) -> &Signature { &self.sig } - - fn sig_mut(&mut self) -> &mut Signature { - &mut self.sig - } } impl HasSignature for ForeignItemFn { fn sig(&self) -> &Signature { &self.sig } - - fn sig_mut(&mut self) -> &mut Signature { - &mut self.sig - } } /// Abstraction over everything that has a [syn::Macro] diff --git a/prusti-contracts/prusti-specs/src/lib.rs b/prusti-contracts/prusti-specs/src/lib.rs index 3403260c345..a16b21cd4dc 100644 --- a/prusti-contracts/prusti-specs/src/lib.rs +++ b/prusti-contracts/prusti-specs/src/lib.rs @@ -77,7 +77,9 @@ fn extract_prusti_attributes( // tokens identical to the ones passed by the native procedural // macro call. let mut iter = attr.tokens.into_iter(); - let TokenTree::Group(group) = iter.next().unwrap() else { unreachable!() }; + let TokenTree::Group(group) = iter.next().unwrap() else { + unreachable!() + }; assert!(iter.next().is_none(), "Unexpected shape of an attribute."); group.stream() } @@ -596,10 +598,14 @@ pub fn refine_trait_spec(_attr: TokenStream, tokens: TokenStream) -> TokenStream let parsed_predicate = handle_result!(predicate::parse_predicate_in_impl(makro.mac.tokens.clone())); - let ParsedPredicate::Impl(predicate) = parsed_predicate else { unreachable!() }; + let ParsedPredicate::Impl(predicate) = parsed_predicate else { + unreachable!() + }; // Patch spec function: Rewrite self with _self: - let syn::Item::Fn(spec_function) = predicate.spec_function else { unreachable!() }; + let syn::Item::Fn(spec_function) = predicate.spec_function else { + unreachable!() + }; generated_spec_items.push(spec_function); // Add patched predicate function to new items @@ -872,7 +878,9 @@ fn extract_prusti_attributes_for_types( // tokens identical to the ones passed by the native procedural // macro call. let mut iter = attr.tokens.into_iter(); - let TokenTree::Group(group) = iter.next().unwrap() else { unreachable!() }; + let TokenTree::Group(group) = iter.next().unwrap() else { + unreachable!() + }; group.stream() } }; diff --git a/prusti-contracts/prusti-specs/src/specifications/preparser.rs b/prusti-contracts/prusti-specs/src/specifications/preparser.rs index 9f684ce72ff..93b5c9eb0c1 100644 --- a/prusti-contracts/prusti-specs/src/specifications/preparser.rs +++ b/prusti-contracts/prusti-specs/src/specifications/preparser.rs @@ -109,75 +109,88 @@ impl PrustiTokenStream { while pos < source.len() { // no matter what tokens we see, we will consume at least one pos += 1; - tokens.push_back(match (&source[pos - 1], source.get(pos), source.get(pos + 1), source.get(pos + 2)) { - ( - TokenTree::Punct(p1), - Some(TokenTree::Punct(p2)), - Some(TokenTree::Punct(p3)), - Some(TokenTree::Punct(p4)), - ) if let Some(op) = PrustiToken::parse_op4(p1, p2, p3, p4) => { - // this was a four-character operator, consume three - // additional tokens - pos += 3; - op - } - ( - TokenTree::Punct(p1), - Some(TokenTree::Punct(p2)), - Some(TokenTree::Punct(p3)), - _ - ) if let Some(op) = PrustiToken::parse_op3(p1, p2, p3) => { - // this was a three-character operator, consume two - // additional tokens - pos += 2; - op - } - ( - TokenTree::Punct(p1), - Some(TokenTree::Punct(p2)), - _, - _, - ) if let Some(op) = PrustiToken::parse_op2(p1, p2) => { - // this was a two-character operator, consume one - // additional token - pos += 1; - op - } - (TokenTree::Ident(ident), _, _, _) if ident == "outer" => - PrustiToken::Outer(ident.span()), - (TokenTree::Ident(ident), _, _, _) if ident == "forall" => - PrustiToken::Quantifier(ident.span(), Quantifier::Forall), - (TokenTree::Ident(ident), _, _, _) if ident == "exists" => - PrustiToken::Quantifier(ident.span(), Quantifier::Exists), - (TokenTree::Punct(punct), _, _, _) - if punct.as_char() == ',' && punct.spacing() == Alone => - PrustiToken::BinOp(punct.span(), PrustiBinaryOp::Rust(RustOp::Comma)), - (TokenTree::Punct(punct), _, _, _) - if punct.as_char() == ';' && punct.spacing() == Alone => - PrustiToken::BinOp(punct.span(), PrustiBinaryOp::Rust(RustOp::Semicolon)), - (TokenTree::Punct(punct), _, _, _) - if punct.as_char() == '=' && punct.spacing() == Alone => - PrustiToken::BinOp(punct.span(), PrustiBinaryOp::Rust(RustOp::Assign)), - (token @ TokenTree::Punct(punct), _, _, _) if punct.spacing() == Joint => { - // make sure to fully consume any Rust operator - // to avoid later mis-identifying its suffix - tokens.push_back(PrustiToken::Token(token.clone())); - while let Some(token @ TokenTree::Punct(p)) = source.get(pos) { + tokens.push_back( + match ( + &source[pos - 1], + source.get(pos), + source.get(pos + 1), + source.get(pos + 2), + ) { + ( + TokenTree::Punct(p1), + Some(TokenTree::Punct(p2)), + Some(TokenTree::Punct(p3)), + Some(TokenTree::Punct(p4)), + ) if let Some(op) = PrustiToken::parse_op4(p1, p2, p3, p4) => { + // this was a four-character operator, consume three + // additional tokens + pos += 3; + op + } + ( + TokenTree::Punct(p1), + Some(TokenTree::Punct(p2)), + Some(TokenTree::Punct(p3)), + _, + ) if let Some(op) = PrustiToken::parse_op3(p1, p2, p3) => { + // this was a three-character operator, consume two + // additional tokens + pos += 2; + op + } + (TokenTree::Punct(p1), Some(TokenTree::Punct(p2)), _, _) + if let Some(op) = PrustiToken::parse_op2(p1, p2) => + { + // this was a two-character operator, consume one + // additional token pos += 1; + op + } + (TokenTree::Ident(ident), _, _, _) if ident == "outer" => { + PrustiToken::Outer(ident.span()) + } + (TokenTree::Ident(ident), _, _, _) if ident == "forall" => { + PrustiToken::Quantifier(ident.span(), Quantifier::Forall) + } + (TokenTree::Ident(ident), _, _, _) if ident == "exists" => { + PrustiToken::Quantifier(ident.span(), Quantifier::Exists) + } + (TokenTree::Punct(punct), _, _, _) + if punct.as_char() == ',' && punct.spacing() == Alone => + { + PrustiToken::BinOp(punct.span(), PrustiBinaryOp::Rust(RustOp::Comma)) + } + (TokenTree::Punct(punct), _, _, _) + if punct.as_char() == ';' && punct.spacing() == Alone => + { + PrustiToken::BinOp(punct.span(), PrustiBinaryOp::Rust(RustOp::Semicolon)) + } + (TokenTree::Punct(punct), _, _, _) + if punct.as_char() == '=' && punct.spacing() == Alone => + { + PrustiToken::BinOp(punct.span(), PrustiBinaryOp::Rust(RustOp::Assign)) + } + (token @ TokenTree::Punct(punct), _, _, _) if punct.spacing() == Joint => { + // make sure to fully consume any Rust operator + // to avoid later mis-identifying its suffix tokens.push_back(PrustiToken::Token(token.clone())); - if p.spacing() != Joint { - break; + while let Some(token @ TokenTree::Punct(p)) = source.get(pos) { + pos += 1; + tokens.push_back(PrustiToken::Token(token.clone())); + if p.spacing() != Joint { + break; + } } + continue; } - continue; - } - (TokenTree::Group(group), _, _, _) => PrustiToken::Group( - group.span(), - group.delimiter(), - Box::new(Self::new(group.stream())), - ), - (token, _, _, _) => PrustiToken::Token(token.clone()), - }); + (TokenTree::Group(group), _, _, _) => PrustiToken::Group( + group.span(), + group.delimiter(), + Box::new(Self::new(group.stream())), + ), + (token, _, _, _) => PrustiToken::Token(token.clone()), + }, + ); } Self { tokens, @@ -221,8 +234,7 @@ impl PrustiTokenStream { PrustiToken::BinOp(span, PrustiBinaryOp::Rust(op)) => Ok(op.to_tokens(span)), _ => err(token.span(), "unexpected Prusti syntax"), }) - .collect::, _>>()? - .into_iter(), + .collect::, _>>()?, )) } @@ -650,6 +662,8 @@ enum PrustiToken { Outer(Span), Quantifier(Span, Quantifier), SpecEnt(Span, bool), + #[allow(unused)] + // TODO: the "once" flag is not used since there is no calldesc translation yet CallDesc(Span, bool), } diff --git a/prusti-contracts/prusti-specs/src/specifications/untyped.rs b/prusti-contracts/prusti-specs/src/specifications/untyped.rs index 851ec94f050..62adc436567 100644 --- a/prusti-contracts/prusti-specs/src/specifications/untyped.rs +++ b/prusti-contracts/prusti-specs/src/specifications/untyped.rs @@ -89,15 +89,6 @@ impl HasSignature for AnyFnItem { Self::ForeignFn(item) => item.sig(), } } - - fn sig_mut(&mut self) -> &mut Signature { - match self { - Self::Fn(item) => item.sig_mut(), - Self::ImplMethod(item) => item.sig_mut(), - Self::TraitMethod(item) => item.sig_mut(), - Self::ForeignFn(item) => item.sig_mut(), - } - } } impl ToTokens for AnyFnItem { diff --git a/prusti-encoder/src/encoder_traits/impure_function_enc.rs b/prusti-encoder/src/encoder_traits/impure_function_enc.rs index 0eff53dce5c..7b75a880177 100644 --- a/prusti-encoder/src/encoder_traits/impure_function_enc.rs +++ b/prusti-encoder/src/encoder_traits/impure_function_enc.rs @@ -88,19 +88,10 @@ where let body = vcx .body_mut() .get_impure_fn_body(local_def_id, substs, caller_def_id); - // let body = vcx.tcx().mir_promoted(local_def_id).0.borrow(); - let fpcs_analysis = mir_state_analysis::run_free_pcs(&body, vcx.tcx()); - //let ssa_analysis = SsaAnalysis::analyse(&body); - let block_count = body.basic_blocks.len(); - // Local count for the Viper method: - // - one for each basic block; - // - one (`Ref`) for each non-argument, non-return local. - let _local_count = block_count + 1 * (body.local_decls.len() - arg_count); - let mut encoded_blocks = Vec::with_capacity( // extra blocks: Start, End 2 + block_count, @@ -133,7 +124,6 @@ where deps, def_id, local_decls: &body.local_decls, - //ssa_analysis, fpcs_analysis, local_defs, diff --git a/prusti-encoder/src/encoder_traits/pure_func_app_enc.rs b/prusti-encoder/src/encoder_traits/pure_func_app_enc.rs index 2044179b2ee..50fa9507c53 100644 --- a/prusti-encoder/src/encoder_traits/pure_func_app_enc.rs +++ b/prusti-encoder/src/encoder_traits/pure_func_app_enc.rs @@ -116,6 +116,7 @@ pub trait PureFuncAppEnc<'vir, E: TaskEncoder + 'vir + ?Sized> { /// Encodes the function application. The resulting application is casted /// to the appropriate generic/concrete type to match the type of `destination`. + #[allow(clippy::too_many_arguments)] fn encode_pure_func_app( &mut self, def_id: DefId, diff --git a/prusti-encoder/src/encoder_traits/pure_function_enc.rs b/prusti-encoder/src/encoder_traits/pure_function_enc.rs index f16cae18701..d16558e2e58 100644 --- a/prusti-encoder/src/encoder_traits/pure_function_enc.rs +++ b/prusti-encoder/src/encoder_traits/pure_function_enc.rs @@ -1,5 +1,5 @@ use prusti_rustc_interface::middle::{mir, ty::Ty}; -use task_encoder::{TaskEncoder, TaskEncoderDependencies}; +use task_encoder::{EncodeFullError, TaskEncoder, TaskEncoderDependencies}; use vir::{CallableIdent, ExprGen, FunctionIdent, Reify, UnknownArity, ViperIdent}; use crate::encoders::{ @@ -83,7 +83,7 @@ where fn encode<'vir>( task_key: Self::TaskKey<'vir>, deps: &mut TaskEncoderDependencies<'vir, Self>, - ) -> MirFunctionEncOutput<'vir> { + ) -> Result, EncodeFullError<'vir, Self>> { let def_id = Self::get_def_id(&task_key); let caller_def_id = Self::get_caller_def_id(&task_key); let trusted = crate::encoders::with_proc_spec(def_id, |def_spec| { @@ -93,13 +93,12 @@ where vir::with_vcx(|vcx| { let substs = Self::get_substs(vcx, &task_key); let local_defs = deps - .require_local::((def_id, substs, caller_def_id)) - .unwrap(); + .require_local::((def_id, substs, caller_def_id))?; tracing::debug!("encoding {def_id:?}"); let function_ident = Self::mk_function_ident(vcx, &task_key); - let ty_arg_decls = deps.require_local::(substs).unwrap(); + let ty_arg_decls = deps.require_local::(substs)?; let mut ident_args = ty_arg_decls.iter().map(|arg| arg.ty()).collect::>(); ident_args.extend( (1..=local_defs.arg_count) @@ -109,11 +108,10 @@ where let ident_args = UnknownArity::new(vcx.alloc_slice(&ident_args)); let return_type = local_defs.locals[mir::RETURN_PLACE].ty; let function_ref = FunctionIdent::new(function_ident, ident_args, return_type.snapshot); - deps.emit_output_ref(task_key, MirFunctionEncOutputRef { function_ref }); + deps.emit_output_ref(task_key, MirFunctionEncOutputRef { function_ref })?; let spec = deps - .require_local::((def_id, substs, None, true)) - .unwrap(); + .require_local::((def_id, substs, None, true))?; let mut func_args = ty_arg_decls .iter() @@ -139,8 +137,7 @@ where param_env: vcx.tcx().param_env(def_id), substs, caller_def_id, - }) - .unwrap() + })? .expr; let expr = expr.reify(vcx, (def_id, spec.pre_args)); assert!( @@ -184,7 +181,7 @@ where posts.push(pc); } - MirFunctionEncOutput { + Ok(MirFunctionEncOutput { function: vcx.mk_function( function_ident.to_str(), vcx.alloc_slice(&func_args), @@ -193,7 +190,7 @@ where vcx.alloc_slice(&posts), expr, ), - } + }) }) } } diff --git a/prusti-encoder/src/encoders/const.rs b/prusti-encoder/src/encoders/const.rs index 7b2ba184672..9940df74c98 100644 --- a/prusti-encoder/src/encoders/const.rs +++ b/prusti-encoder/src/encoders/const.rs @@ -1,8 +1,10 @@ use prusti_rustc_interface::{ - middle::{mir, ty}, + middle::{ + mir::{self, ConstValue, interpret::{Scalar, GlobalAlloc}}, + ty, + }, span::def_id::DefId, }; -use rustc_middle::mir::{ConstValue, interpret::{ Scalar, GlobalAlloc}}; use task_encoder::{ TaskEncoder, TaskEncoderDependencies, @@ -12,13 +14,6 @@ use vir::{CallableIdent, Arity}; pub struct ConstEnc; -#[derive(Clone, Debug)] -pub struct ConstEncOutputRef<'vir> { - pub base_name: String, - pub snap_inst: vir::Type<'vir>, -} -impl<'vir> task_encoder::OutputRefAny for ConstEncOutputRef<'vir> {} - use crate::encoders::{MirPureEnc, mir_pure::PureKind, MirPureEncTask}; use super::{lifted::{casters::CastTypePure, rust_ty_cast::RustTyCastersEnc}, rust_ty_snapshots::RustTySnapshotsEnc}; diff --git a/prusti-encoder/src/encoders/generic.rs b/prusti-encoder/src/encoders/generic.rs index ad562a82095..893f751969b 100644 --- a/prusti-encoder/src/encoders/generic.rs +++ b/prusti-encoder/src/encoders/generic.rs @@ -8,7 +8,7 @@ pub struct GenericEnc; #[derive(Clone, Debug)] pub enum GenericEncError { - UnsupportedType, + // UnsupportedType, } #[derive(Clone, Debug)] @@ -19,7 +19,7 @@ pub struct GenericEncOutputRef<'vir> { pub ref_to_pred: PredicateIdent<'vir, BinaryArity<'vir>>, pub ref_to_snap: FunctionIdent<'vir, BinaryArity<'vir>>, pub unreachable_to_snap: FunctionIdent<'vir, NullaryArity<'vir>>, - pub domain_type_name: DomainIdent<'vir, KnownArityAny<'vir, DomainParamData<'vir>, 0>>, + // pub domain_type_name: DomainIdent<'vir, KnownArityAny<'vir, DomainParamData<'vir>, 0>>, pub domain_param_name: DomainIdent<'vir, KnownArityAny<'vir, DomainParamData<'vir>, 0>>, } impl<'vir> task_encoder::OutputRefAny for GenericEncOutputRef<'vir> {} @@ -57,7 +57,7 @@ impl TaskEncoder for GenericEnc { ) -> EncodeFullResult<'vir, Self> { let ref_to_pred = PredicateIdent::new(ViperIdent::new("p_Param"), BinaryArity::new(&[&TypeData::Ref, &TYP_DOMAIN])); - let type_domain_ident = DomainIdent::nullary(ViperIdent::new("Type")); + // let type_domain_ident = DomainIdent::nullary(ViperIdent::new("Type")); let param_domain_ident = DomainIdent::nullary(ViperIdent::new("s_Param")); let ref_to_snap = FunctionIdent::new( ViperIdent::new("p_Param_snap"), @@ -81,7 +81,7 @@ impl TaskEncoder for GenericEnc { type_snapshot: &TYP_DOMAIN, param_snapshot: &SNAPSHOT_PARAM_DOMAIN, ref_to_pred, - domain_type_name: type_domain_ident, + // domain_type_name: type_domain_ident, domain_param_name: param_domain_ident, ref_to_snap, unreachable_to_snap, diff --git a/prusti-encoder/src/encoders/mir_builtin.rs b/prusti-encoder/src/encoders/mir_builtin.rs index d6ca1cf8fd2..5f7a7d98ce0 100644 --- a/prusti-encoder/src/encoders/mir_builtin.rs +++ b/prusti-encoder/src/encoders/mir_builtin.rs @@ -3,9 +3,7 @@ use prusti_rustc_interface::{ middle::mir, }; use task_encoder::{ - TaskEncoder, - TaskEncoderDependencies, - EncodeFullResult, + EncodeFullError, EncodeFullResult, TaskEncoder, TaskEncoderDependencies }; use vir::{UnknownArity, FunctionIdent, CallableIdent}; @@ -13,10 +11,11 @@ pub struct MirBuiltinEnc; #[derive(Clone, Debug)] pub enum MirBuiltinEncError { - Unsupported, + // Unsupported, } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] +#[allow(clippy::enum_variant_names)] pub enum MirBuiltinEncTask<'tcx> { UnOp(ty::Ty<'tcx>, mir::UnOp, ty::Ty<'tcx>), BinOp(ty::Ty<'tcx>, mir::BinOp, ty::Ty<'tcx>, ty::Ty<'tcx>), @@ -49,7 +48,7 @@ impl TaskEncoder for MirBuiltinEnc { type EncodingError = MirBuiltinEncError; fn task_to_key<'vir>(task: &Self::TaskDescription<'vir>) -> Self::TaskKey<'vir> { - task.clone() + *task } fn do_encode_full<'vir>( @@ -60,15 +59,15 @@ impl TaskEncoder for MirBuiltinEnc { match *task_key { MirBuiltinEncTask::UnOp(res_ty, op, operand_ty) => { assert_eq!(res_ty, operand_ty); - let function = Self::handle_un_op(vcx, deps, *task_key, op, operand_ty); + let function = Self::handle_un_op(vcx, deps, *task_key, op, operand_ty)?; Ok((MirBuiltinEncOutput { function }, ())) } MirBuiltinEncTask::BinOp(res_ty, op, l_ty, r_ty) => { - let function = Self::handle_bin_op(vcx, deps, *task_key, res_ty, op, l_ty, r_ty); + let function = Self::handle_bin_op(vcx, deps, *task_key, res_ty, op, l_ty, r_ty)?; Ok((MirBuiltinEncOutput { function }, ())) } MirBuiltinEncTask::CheckedBinOp(res_ty, op, l_ty, r_ty) => { - let function = Self::handle_checked_bin_op(vcx, deps, *task_key, res_ty, op, l_ty, r_ty); + let function = Self::handle_checked_bin_op(vcx, deps, *task_key, res_ty, op, l_ty, r_ty)?; Ok((MirBuiltinEncOutput { function }, ())) } } @@ -77,7 +76,7 @@ impl TaskEncoder for MirBuiltinEnc { } // TODO: this function is also useful for the type encoder, extract? -fn int_name<'tcx>(ty: ty::Ty<'tcx>) -> &'static str { +fn int_name(ty: ty::Ty<'_>) -> &'static str { match ty.kind() { ty::TyKind::Bool => "bool", ty::TyKind::Int(kind) => kind.name_str(), @@ -93,10 +92,9 @@ impl MirBuiltinEnc { key: ::TaskKey<'vir>, op: mir::UnOp, ty: ty::Ty<'vir>, - ) -> vir::Function<'vir> { + ) -> Result, EncodeFullError<'vir, Self>> { let e_ty = deps - .require_local::(ty) - .unwrap() + .require_local::(ty)? .generic_snapshot; let name = vir::vir_format_identifier!(vcx, "mir_unop_{op:?}_{}", int_name(ty)); @@ -104,7 +102,7 @@ impl MirBuiltinEnc { let function = FunctionIdent::new(name, arity, e_ty.snapshot); deps.emit_output_ref(key, MirBuiltinEncOutputRef { function, - }); + })?; let prim_res_ty = e_ty.specifics.expect_primitive(); let snap_arg = vcx.mk_local_ex("arg", e_ty.snapshot); @@ -117,7 +115,7 @@ impl MirBuiltinEnc { // before in debug mode. We should still produce the correct result in // release mode, which the code under this branch does. if op == mir::UnOp::Neg && ty.is_signed() { - let bound = vcx.get_min_int(prim_res_ty.prim_type, ty.kind()); + let bound = vcx.get_min_int(ty.kind()); // `snap_to_prim(arg) == -iN::MIN` let cond = vcx.mk_bin_op_expr(vir::BinOpKind::CmpEq, prim_arg, bound); // `snap_to_prim(arg) == -iN::MIN ? arg : @@ -125,14 +123,14 @@ impl MirBuiltinEnc { val = vcx.mk_ternary_expr(cond, snap_arg, val) } - vcx.mk_function( + Ok(vcx.mk_function( name.to_str(), vcx.alloc_slice(&[vcx.mk_local_decl("arg", e_ty.snapshot)]), e_ty.snapshot, &[], &[], Some(val) - ) + )) } fn handle_bin_op<'vir>( @@ -143,19 +141,16 @@ impl MirBuiltinEnc { op: mir::BinOp, l_ty: ty::Ty<'vir>, r_ty: ty::Ty<'vir>, - ) -> vir::Function<'vir> { + ) -> Result, EncodeFullError<'vir, Self>> { use mir::BinOp::*; let e_l_ty = deps - .require_local::(l_ty) - .unwrap() + .require_local::(l_ty)? .generic_snapshot; let e_r_ty = deps - .require_local::(r_ty) - .unwrap() + .require_local::(r_ty)? .generic_snapshot; let e_res_ty = deps - .require_local::(res_ty) - .unwrap() + .require_local::(res_ty)? .generic_snapshot; let prim_l_ty = e_l_ty.specifics.expect_primitive(); let prim_r_ty = e_r_ty.specifics.expect_primitive(); @@ -166,7 +161,7 @@ impl MirBuiltinEnc { let function = FunctionIdent::new(name, arity, e_res_ty.snapshot); deps.emit_output_ref(key, MirBuiltinEncOutputRef { function, - }); + })?; let lhs = prim_l_ty.snap_to_prim.apply(vcx, [vcx.mk_local_ex("arg1", e_l_ty.snapshot)], ); @@ -176,7 +171,7 @@ impl MirBuiltinEnc { if matches!(op, Shl | Shr) { // RHS must be smaller than the bit width of the LHS, this is // implicit in the `Shl` and `Shr` operators. - rhs = vcx.mk_bin_op_expr(vir::BinOpKind::Mod, rhs, vcx.get_bit_width_int(prim_l_ty.prim_type, l_ty.kind())); + rhs = vcx.mk_bin_op_expr(vir::BinOpKind::Mod, rhs, vcx.get_bit_width_int(l_ty.kind())); } let op_kind = vir::BinOpKind::from(op); let viper_val = vcx.mk_bin_op_expr(op_kind, lhs, rhs); @@ -185,13 +180,13 @@ impl MirBuiltinEnc { // Overflow well defined as wrapping (implicit) and for the shifts // the RHS will be masked to the bit width. Add | Sub | Mul | Shl | Shr => - (Vec::new(), Self::get_wrapped_val(vcx, val, prim_res_ty.prim_type, res_ty)), + (Vec::new(), Self::get_wrapped_val(vcx, val, res_ty)), // Undefined behavior to overflow (need precondition) AddUnchecked | SubUnchecked | MulUnchecked => { - let min = vcx.get_min_int(prim_res_ty.prim_type, res_ty.kind()); + let min = vcx.get_min_int(res_ty.kind()); // `(arg1 op arg2) >= -iN::MIN` let lower_bound = vcx.mk_bin_op_expr(vir::BinOpKind::CmpGe, val, min); - let max = vcx.get_max_int(prim_res_ty.prim_type, res_ty.kind()); + let max = vcx.get_max_int(res_ty.kind()); // `(arg1 op arg2) <= iN::MAX` let upper_bound = vcx.mk_bin_op_expr(vir::BinOpKind::CmpLe, val, max); (vec![lower_bound, upper_bound], val) @@ -202,10 +197,10 @@ impl MirBuiltinEnc { let min = vcx.mk_int::<0>(); // `arg2 >= 0` let lower_bound = vcx.mk_bin_op_expr(vir::BinOpKind::CmpGe, rhs, min); - let max = vcx.get_bit_width_int(prim_l_ty.prim_type, l_ty.kind()); + let max = vcx.get_bit_width_int(l_ty.kind()); // `arg2 < bit_width(arg1)` let upper_bound = vcx.mk_bin_op_expr(vir::BinOpKind::CmpLt, rhs, max); - (vec![lower_bound, upper_bound], Self::get_wrapped_val(vcx, val, prim_res_ty.prim_type, res_ty)) + (vec![lower_bound, upper_bound], Self::get_wrapped_val(vcx, val, res_ty)) } // Could divide by zero or overflow if divisor is `-1` Div | Rem => { @@ -214,7 +209,7 @@ impl MirBuiltinEnc { let mut pres = vec![pre]; let mut val = val; if res_ty.is_signed() { - let min = vcx.get_min_int(prim_res_ty.prim_type, res_ty.kind()); + let min = vcx.get_min_int(res_ty.kind()); // `arg1 != -iN::MIN` let arg1_cond = vcx.mk_bin_op_expr(vir::BinOpKind::CmpNe, lhs, min); // `-1 != arg2 ` @@ -249,12 +244,10 @@ impl MirBuiltinEnc { } // Cannot overflow and no undefined behavior BitXor | BitAnd | BitOr | Eq | Lt | Le | Ne | Ge | Gt | Offset => (Vec::new(), val), - AddWithOverflow => todo!(), - SubWithOverflow => todo!(), - MulWithOverflow => todo!(), Cmp => todo!(), + _ => unreachable!(), }; - vcx.mk_function( + Ok(vcx.mk_function( name.to_str(), vcx.alloc_slice(&[ vcx.mk_local_decl("arg1", e_l_ty.snapshot), @@ -264,7 +257,7 @@ impl MirBuiltinEnc { vcx.alloc_slice(&pres), &[], Some(val), - ) + )) } fn handle_checked_bin_op<'vir>( @@ -275,19 +268,18 @@ impl MirBuiltinEnc { op: mir::BinOp, l_ty: ty::Ty<'vir>, r_ty: ty::Ty<'vir>, - ) -> vir::Function<'vir> { - // `op` can only be `Add`, `Sub` or `Mul` + ) -> Result, EncodeFullError<'vir, Self>> { + // `op` can only be `Add`, `Sub` or `Mul`, or their overflowing version assert!(matches!( op, mir::BinOp::Add | mir::BinOp::Sub | mir::BinOp::Mul + | mir::BinOp::AddWithOverflow | mir::BinOp::SubWithOverflow | mir::BinOp::MulWithOverflow )); let e_l_ty = deps - .require_local::(l_ty) - .unwrap() + .require_local::(l_ty)? .generic_snapshot; let e_r_ty = deps - .require_local::(r_ty) - .unwrap() + .require_local::(r_ty)? .generic_snapshot; let name = vir::vir_format_identifier!( @@ -302,11 +294,10 @@ impl MirBuiltinEnc { .unwrap() .generic_snapshot; let function = FunctionIdent::new(name, arity, e_res_ty.snapshot); - deps.emit_output_ref(key, MirBuiltinEncOutputRef { function }); + deps.emit_output_ref(key, MirBuiltinEncOutputRef { function })?; let e_res_ty = deps - .require_local::(res_ty) - .unwrap() + .require_local::(res_ty)? .generic_snapshot; // The result of a checked add will always be `(T, bool)`, get the `T` // type @@ -315,13 +306,11 @@ impl MirBuiltinEnc { assert!(bool_ty.is_bool()); let e_rvalue_pure_ty = deps - .require_local::(rvalue_pure_ty) - .unwrap() + .require_local::(rvalue_pure_ty)? .generic_snapshot; let e_rvalue_pure_ty = e_rvalue_pure_ty.specifics.expect_primitive(); let e_bool = deps - .require_local::(bool_ty) - .unwrap() + .require_local::(bool_ty)? .generic_snapshot; let bool_cons = e_bool.specifics.expect_primitive().prim_to_snap; @@ -334,7 +323,7 @@ impl MirBuiltinEnc { let val_str = "val"; let val = vcx.mk_local_ex(val_str, e_rvalue_pure_ty.prim_type); // Wrapped value - let wrapped_val_exp = Self::get_wrapped_val(vcx, val, e_rvalue_pure_ty.prim_type, rvalue_pure_ty); + let wrapped_val_exp = Self::get_wrapped_val(vcx, val, rvalue_pure_ty); let wrapped_val_str = "wrapped_val"; let wrapped_val = vcx.mk_local_ex(wrapped_val_str, e_rvalue_pure_ty.prim_type); let wrapped_val_snap = e_rvalue_pure_ty.prim_to_snap.apply(vcx, @@ -347,14 +336,14 @@ impl MirBuiltinEnc { let ty_caster = deps.require_local::(AggregateSnapArgsCastEncTask { tys: vec![rvalue_pure_ty, bool_ty], aggregate_type: AggregateType::Tuple, - }).unwrap(); + })?; let tuple = e_res_ty.specifics.expect_structlike().field_snaps_to_snap.apply(vcx, &ty_caster.apply_casts(vcx, [wrapped_val_snap, overflowed_snap].into_iter()) ); // `let wrapped_val == (val ..) in $tuple` let inner_let = vcx.mk_let_expr(wrapped_val_str, wrapped_val_exp, tuple); - vcx.mk_function( + Ok(vcx.mk_function( name.to_str(), vcx.alloc_slice(&[ vcx.mk_local_decl("arg1", e_l_ty.snapshot), @@ -364,18 +353,19 @@ impl MirBuiltinEnc { &[], &[], Some(vcx.mk_let_expr(val_str, val_exp, inner_let)) - ) + )) } /// Wrap the value in the range of the type, e.g. `uN` is wrapped in the /// range `uN::MIN..=uN::MAX` using modulo. For signed integers, the range /// is `iN::MIN..=iN::MAX` and the value is wrapped using two's complement. - fn get_wrapped_val<'vir, 'tcx>(vcx: &'vir vir::VirCtxt<'tcx>, mut exp: &'vir vir::ExprData<'vir>, ty: vir::Type, rust_ty: ty::Ty) -> &'vir vir::ExprData<'vir> { - let shift_amount = vcx.get_signed_shift_int(ty, rust_ty.kind()); + #[allow(clippy::needless_lifetimes)] + fn get_wrapped_val<'vir, 'tcx>(vcx: &'vir vir::VirCtxt<'tcx>, mut exp: &'vir vir::ExprData<'vir>, rust_ty: ty::Ty) -> &'vir vir::ExprData<'vir> { + let shift_amount = vcx.get_signed_shift_int(rust_ty.kind()); if let Some(half) = shift_amount { exp = vcx.mk_bin_op_expr(vir::BinOpKind::Add, exp, half); } - let modulo_val = vcx.get_modulo_int(ty, rust_ty.kind()); + let modulo_val = vcx.get_modulo_int(rust_ty.kind()); exp = vcx.mk_bin_op_expr(vir::BinOpKind::Mod, exp, modulo_val); if let Some(half) = shift_amount { exp = vcx.mk_bin_op_expr(vir::BinOpKind::Sub, exp, half); diff --git a/prusti-encoder/src/encoders/mir_impure.rs b/prusti-encoder/src/encoders/mir_impure.rs index b29993925f4..9539fc7abba 100644 --- a/prusti-encoder/src/encoders/mir_impure.rs +++ b/prusti-encoder/src/encoders/mir_impure.rs @@ -15,24 +15,12 @@ use prusti_rustc_interface::{ // SsaAnalysis, //}; use task_encoder::{TaskEncoder, TaskEncoderDependencies, EncodeFullResult}; -use vir::{MethodIdent, UnknownArity}; pub struct MirImpureEnc; #[derive(Clone, Debug)] pub enum MirImpureEncError { - Unsupported, -} - -#[derive(Clone, Debug)] -pub struct MirImpureEncOutputRef<'vir> { - pub method_ref: MethodIdent<'vir, UnknownArity<'vir>>, -} -impl<'vir> task_encoder::OutputRefAny for MirImpureEncOutputRef<'vir> {} - -#[derive(Clone, Debug)] -pub struct MirImpureEncOutput<'vir> { - pub method: vir::Method<'vir>, + // Unsupported, } use crate::{ @@ -96,7 +84,7 @@ impl TaskEncoder for MirImpureEnc { } else { deps.require_ref::(task_key.def_id)? }; - deps.emit_output_ref(*task_key, output_ref); + deps.emit_output_ref(*task_key, output_ref)?; let output: ImpureFunctionEncOutput<'_> = if monomorphize { deps.require_local::(*task_key)? } else { @@ -268,7 +256,7 @@ impl<'vir, 'enc, E: TaskEncoder> ImpureEncVisitor<'vir, 'enc, E> { let ref_p = self.encode_place(place).expr; let args = place_ty_out.ref_to_args(self.vcx, ref_p); - let predicate = ref_to_pred.apply(self.vcx, &args, None); + let predicate = ref_to_pred.apply(self.vcx, args, None); if matches!( repack_op, mir_state_analysis::free_pcs::RepackOp::Expand(..) @@ -556,7 +544,7 @@ impl<'vir, 'enc, E: TaskEncoder> mir::visit::Visitor<'vir> for ImpureEncVisitor< // TODO: these should not be ignored, but should havoc the local instead // This clears up the noise a bit, making sure StorageLive and other // kinds do not show up in the comments. - let IGNORE_NOP_STMTS = true; + const IGNORE_NOP_STMTS: bool = true; if IGNORE_NOP_STMTS { match &statement.kind { mir::StatementKind::StorageLive(..) @@ -600,14 +588,14 @@ impl<'vir, 'enc, E: TaskEncoder> mir::visit::Visitor<'vir> for ImpureEncVisitor< //mir::Rvalue::Len(Place<'vir>) => {} //mir::Rvalue::Cast(CastKind, Operand<'vir>, Ty<'vir>) => {} - rv@mir::Rvalue::BinaryOp(op, box (l, r)) => { + mir::Rvalue::BinaryOp(op, box (l, r)) => { let l_ty = l.ty(self.local_decls, self.vcx.tcx()); let r_ty = r.ty(self.local_decls, self.vcx.tcx()); use crate::encoders::MirBuiltinEncTask::{BinOp, CheckedBinOp}; - let task = if matches!(rv, mir::Rvalue::BinaryOp(..)) { - BinOp(rvalue_ty, *op, l_ty, r_ty) - } else { + let task = if op.is_overflowing() { CheckedBinOp(rvalue_ty, *op, l_ty, r_ty) + } else { + BinOp(rvalue_ty, *op, l_ty, r_ty) }; let binop_function = self.deps.require_ref::( task diff --git a/prusti-encoder/src/encoders/mir_poly_impure.rs b/prusti-encoder/src/encoders/mir_poly_impure.rs index 8bd2f075518..7551bf06f13 100644 --- a/prusti-encoder/src/encoders/mir_poly_impure.rs +++ b/prusti-encoder/src/encoders/mir_poly_impure.rs @@ -1,21 +1,9 @@ use prusti_rustc_interface::span::def_id::DefId; use task_encoder::{EncodeFullResult, TaskEncoder, TaskEncoderDependencies}; -use vir::{MethodIdent, UnknownArity}; /// Encodes a Rust function as a Viper method using the polymorphic encoding of generics. pub struct MirPolyImpureEnc; -#[derive(Clone, Debug)] -pub struct MirImpureEncOutputRef<'vir> { - pub method_ref: MethodIdent<'vir, UnknownArity<'vir>>, -} -impl<'vir> task_encoder::OutputRefAny for MirImpureEncOutputRef<'vir> {} - -#[derive(Clone, Debug)] -pub struct MirImpureEncOutput<'vir> { - pub method: vir::Method<'vir>, -} - use crate::encoder_traits::impure_function_enc::{ ImpureFunctionEnc, ImpureFunctionEncError, ImpureFunctionEncOutput, ImpureFunctionEncOutputRef, }; diff --git a/prusti-encoder/src/encoders/mir_pure.rs b/prusti-encoder/src/encoders/mir_pure.rs index 60ea470c0e4..22e352a97b8 100644 --- a/prusti-encoder/src/encoders/mir_pure.rs +++ b/prusti-encoder/src/encoders/mir_pure.rs @@ -3,11 +3,10 @@ use prusti_rustc_interface::{ index::IndexVec, middle::{ mir::{self, Body}, - ty::{self, GenericArgs, TyKind}, + ty::{self, Binder, FnSig, GenericArgs, TyKind}, }, span::{def_id::DefId, source_map::Spanned}, }; -use rustc_middle::ty::{Binder, FnSig}; use task_encoder::{ TaskEncoder, TaskEncoderDependencies, @@ -37,8 +36,8 @@ pub struct MirPureEnc; #[derive(Clone, Debug)] pub enum MirPureEncError { - UnsupportedStatement, - UnsupportedTerminator, + // UnsupportedStatement, + // UnsupportedTerminator, } // TODO: does this need to be `&'vir [..]`? @@ -182,12 +181,12 @@ impl<'vir> Update<'vir> { binds: self .binds .into_iter() - .chain(newer.binds.into_iter()) + .chain(newer.binds) .collect(), versions: self .versions .into_iter() - .chain(newer.versions.into_iter()) + .chain(newer.versions) .collect(), } } @@ -207,7 +206,7 @@ struct Enc<'vir: 'enc, 'enc> { body: &'enc mir::Body<'vir>, rev_doms: rev_doms::ReverseDominators, deps: &'enc mut TaskEncoderDependencies<'vir, MirPureEnc>, - visited: IndexVec, + // visited: IndexVec, version_ctr: IndexVec, phi_ctr: usize, } @@ -268,7 +267,7 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { body, rev_doms, deps, - visited: IndexVec::from_elem_n(false, body.basic_blocks.len()), + // visited: IndexVec::from_elem_n(false, body.basic_blocks.len()), version_ctr: IndexVec::from_elem_n(0, body.local_decls.len()), phi_ctr: 0, } @@ -337,7 +336,7 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { fn reify_branch( &mut self, tuple_ref: &crate::encoders::ViperTupleEncOutput<'vir>, - mod_locals: &Vec, + mod_locals: &[mir::Local], curr_ver: &HashMap, update: Update<'vir>, ) -> ExprRet<'vir> { @@ -348,7 +347,7 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { *local, update.versions.get(local).copied().unwrap_or_else(|| { // TODO: remove (debug) - if !curr_ver.contains_key(&local) { + if !curr_ver.contains_key(local) { tracing::error!("unknown version of local! {}", local.as_usize()); return 0xff; } @@ -445,9 +444,8 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { // defined before the branch let mut mod_locals = updates .iter() - .map(|update| update.versions.keys()) - .flatten() - .filter(|local| new_curr_ver.contains_key(&local)) + .flat_map(|update| update.versions.keys()) + .filter(|local| new_curr_ver.contains_key(local)) .copied() .collect::>(); mod_locals.sort(); @@ -459,9 +457,9 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { .require_local::(mod_locals.len()) .unwrap(); let otherwise_update = updates.pop().unwrap(); - let phi_expr = targets.iter().zip(updates.into_iter()).fold( + let phi_expr = targets.iter().zip(updates).fold( self.reify_branch(&tuple_ref, &mod_locals, &new_curr_ver, otherwise_update), - |expr, ((cond_val, target), branch_update)| { + |expr, ((cond_val, _target), branch_update)| { self.vcx.mk_ternary_expr( self.vcx.mk_bin_op_expr( vir::BinOpKind::CmpEq, @@ -639,14 +637,14 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { // AddressOf // Len // Cast - rv @ mir::Rvalue::BinaryOp(op, box (l, r)) => { + mir::Rvalue::BinaryOp(op, box (l, r)) => { let l_ty = l.ty(self.body, self.vcx.tcx()); let r_ty = r.ty(self.body, self.vcx.tcx()); use crate::encoders::MirBuiltinEncTask::{BinOp, CheckedBinOp}; - let task = if matches!(rv, mir::Rvalue::BinaryOp(..)) { - BinOp(rvalue_ty, *op, l_ty, r_ty) - } else { + let task = if op.is_overflowing() { CheckedBinOp(rvalue_ty, *op, l_ty, r_ty) + } else { + BinOp(rvalue_ty, *op, l_ty, r_ty) }; let binop_function = self .deps @@ -914,8 +912,8 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { match builtin.expect("call to unknown non-pure function in pure code") { PrustiBuiltin::SnapshotEquality => { assert_eq!(args.len(), 2); - let lhs = self.encode_operand(&curr_ver, &args[0].node); - let rhs = self.encode_operand(&curr_ver, &args[1].node); + let lhs = self.encode_operand(curr_ver, &args[0].node); + let rhs = self.encode_operand(curr_ver, &args[1].node); let eq_expr = self.vcx.mk_bin_op_expr(vir::BinOpKind::CmpEq, lhs, rhs); let bool_cons = self @@ -939,7 +937,7 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { // - expression for the body assert_eq!(encoded_args.len(), 4); - let (qvar_tys, upvar_tys, cl_def_id) = match arg_tys[1].expect_ty().peel_refs().kind() { + let (qvar_tys, _upvar_tys, cl_def_id) = match arg_tys[1].expect_ty().peel_refs().kind() { TyKind::Closure(cl_def_id, cl_args) => ( match cl_args.as_closure().sig().skip_binder().inputs()[0].kind() { TyKind::Tuple(list) => list, @@ -984,7 +982,10 @@ impl<'vir: 'enc, 'enc> Enc<'vir, 'enc> { // operation, which will work like reify // but panicking on a Lazy(..)? reify_args.push(unsafe { - std::mem::transmute(encoded_args[3]) + std::mem::transmute::< + ExprRet<'_>, + vir::ExprGen<'_, !, !>, + >(encoded_args[3]) }); reify_args.extend( qvars @@ -1046,6 +1047,7 @@ mod rev_doms { pub end: mir::BasicBlock, } impl ReverseDominators { + #[allow(clippy::needless_lifetimes)] pub fn new<'a, 'vir>(blocks: &'a mir::BasicBlocks<'vir>) -> Self { let no_succ_blocks = blocks .iter_enumerated() @@ -1084,7 +1086,7 @@ mod rev_doms { } impl Predecessors for RevBasicBlocks<'_, '_> { - fn predecessors<'a>(&'a self, node: Self::Node) -> impl Iterator { + fn predecessors(&self, node: Self::Node) -> impl Iterator { if node == self.start_node() { Box::new([].into_iter()) } else if self.1.contains(&node) { @@ -1096,7 +1098,7 @@ mod rev_doms { } impl Successors for RevBasicBlocks<'_, '_> { - fn successors<'a>(&'a self, node: Self::Node) -> impl Iterator { + fn successors(&self, node: Self::Node) -> impl Iterator { if node == self.start_node() { Box::new(self.1.iter().copied()) as Box> } else { diff --git a/prusti-encoder/src/encoders/mir_pure_function.rs b/prusti-encoder/src/encoders/mir_pure_function.rs index db2074ef718..9de9aef2116 100644 --- a/prusti-encoder/src/encoders/mir_pure_function.rs +++ b/prusti-encoder/src/encoders/mir_pure_function.rs @@ -12,7 +12,7 @@ pub struct MirFunctionEnc; #[derive(Clone, Debug)] pub enum MirFunctionEncError { - Unsupported, + // Unsupported, } impl PureFunctionEnc for MirFunctionEnc { @@ -44,6 +44,6 @@ impl TaskEncoder for MirFunctionEnc { task_key: &Self::TaskKey<'vir>, deps: &mut TaskEncoderDependencies<'vir, Self>, ) -> EncodeFullResult<'vir, Self> { - Ok((::encode(*task_key, deps), ())) + Ok((::encode(*task_key, deps)?, ())) } } diff --git a/prusti-encoder/src/encoders/mod.rs b/prusti-encoder/src/encoders/mod.rs index a4e80bc1a42..fc60e20423c 100644 --- a/prusti-encoder/src/encoders/mod.rs +++ b/prusti-encoder/src/encoders/mod.rs @@ -21,7 +21,6 @@ cfg_if::cfg_if! { pub use mono::task_description::*; -pub use pure::*; pub use pure::spec::MirSpecEnc; pub use local_def::*; pub use r#type::*; @@ -40,7 +39,6 @@ pub use mir_pure::{ }; pub use spec::{ SpecEnc, - SpecEncOutput, SpecEncTask, }; pub(super) use spec::{init_def_spec, with_proc_spec}; @@ -48,7 +46,6 @@ pub use snapshot::SnapshotEnc; pub use predicate::{ PredicateEnc, PredicateEncOutputRef, - PredicateEncOutput, }; pub use domain::all_outputs as DomainEnc_all_outputs; pub use viper_tuple::{ diff --git a/prusti-encoder/src/encoders/mono/mir_impure.rs b/prusti-encoder/src/encoders/mono/mir_impure.rs index b5975a02ec5..3cdb7d8fb8d 100644 --- a/prusti-encoder/src/encoders/mono/mir_impure.rs +++ b/prusti-encoder/src/encoders/mono/mir_impure.rs @@ -1,20 +1,9 @@ use prusti_rustc_interface::{middle::ty::GenericArgs, span::def_id::DefId}; use task_encoder::{TaskEncoder, TaskEncoderDependencies, EncodeFullResult}; -use vir::{MethodIdent, UnknownArity}; + /// Encodes a Rust function as a Viper method using the monomorphic encoding of generics. pub struct MirMonoImpureEnc; -#[derive(Clone, Debug)] -pub struct MirImpureEncOutputRef<'vir> { - pub method_ref: MethodIdent<'vir, UnknownArity<'vir>>, -} -impl<'vir> task_encoder::OutputRefAny for MirImpureEncOutputRef<'vir> {} - -#[derive(Clone, Debug)] -pub struct MirImpureEncOutput<'vir> { - pub method: vir::Method<'vir>, -} - use crate::{ encoder_traits::{ function_enc::FunctionEnc, diff --git a/prusti-encoder/src/encoders/mono/mir_pure_function.rs b/prusti-encoder/src/encoders/mono/mir_pure_function.rs index e984a882fa5..d939b4bb65f 100644 --- a/prusti-encoder/src/encoders/mono/mir_pure_function.rs +++ b/prusti-encoder/src/encoders/mono/mir_pure_function.rs @@ -63,6 +63,6 @@ impl TaskEncoder for MirMonoFunctionEnc { task_key: &Self::TaskKey<'vir>, deps: &mut TaskEncoderDependencies<'vir, Self>, ) -> EncodeFullResult<'vir, Self> { - Ok((::encode(*task_key, deps), ())) + Ok((::encode(*task_key, deps)?, ())) } } diff --git a/prusti-encoder/src/encoders/pure/spec.rs b/prusti-encoder/src/encoders/pure/spec.rs index 656133e50f6..bd973b13ce3 100644 --- a/prusti-encoder/src/encoders/pure/spec.rs +++ b/prusti-encoder/src/encoders/pure/spec.rs @@ -15,6 +15,7 @@ pub struct MirSpecEncOutput<'vir> { pub pres: Vec>, pub posts: Vec>, pub pre_args: &'vir [vir::Expr<'vir>], + #[allow(dead_code)] pub post_args: &'vir [vir::Expr<'vir>], } diff --git a/prusti-encoder/src/encoders/spec.rs b/prusti-encoder/src/encoders/spec.rs index 6d2431da65b..0b8fceb977c 100644 --- a/prusti-encoder/src/encoders/spec.rs +++ b/prusti-encoder/src/encoders/spec.rs @@ -80,7 +80,7 @@ impl TaskEncoder for SpecEnc { task_key: &Self::TaskKey<'vir>, deps: &mut TaskEncoderDependencies<'vir, Self>, ) -> EncodeFullResult<'vir, Self> { - deps.emit_output_ref(task_key.clone(), ())?; + deps.emit_output_ref(*task_key, ())?; vir::with_vcx(|vcx| { with_def_spec(|def_spec| { let specs = def_spec.get_proc_spec(&task_key.0); diff --git a/prusti-encoder/src/encoders/type/domain.rs b/prusti-encoder/src/encoders/type/domain.rs index dafc5e67d1b..51e0bb1e15b 100644 --- a/prusti-encoder/src/encoders/type/domain.rs +++ b/prusti-encoder/src/encoders/type/domain.rs @@ -1,9 +1,12 @@ +// TODO: this lint is something we should fix; to address there should probably +// be an indirection in error storage somewhere, maybe even in `task-encoder`? +#![allow(clippy::result_large_err)] + use prusti_rustc_interface::{ - middle::ty::{self, TyKind, util::IntTypeExt, IntTy, UintTy}, + middle::ty::{self, ParamTy, TyKind, util::IntTypeExt, IntTy, UintTy}, target::abi, span::symbol, }; -use rustc_middle::ty::ParamTy; use task_encoder::{ EncodeFullError, EncodeFullResult, TaskEncoder, TaskEncoderDependencies }; @@ -99,7 +102,7 @@ impl <'vir> DomainEncOutputRef<'vir> { impl<'vir> task_encoder::OutputRefAny for DomainEncOutputRef<'vir> {} -use crate::encoders::{generic::GenericEncOutputRef, GenericEnc}; +use crate::encoders::GenericEnc; use super::{ lifted::{ @@ -157,7 +160,7 @@ impl TaskEncoder for DomainEnc { ); Ok((Some(enc.finalize(task_key)), specifics)) } - TyKind::Closure(def_id, args) => { + TyKind::Closure(_def_id, args) => { let cl_args = args.as_closure(); let params = cl_args.parent_args(); let generics = params @@ -303,7 +306,7 @@ struct DomainEncData<'vir, 'enc> { self_decl: &'vir [vir::LocalDecl<'vir>; 1], axioms: Vec>, functions: Vec>, - generic_enc: GenericEncOutputRef<'vir>, + // generic_enc: GenericEncOutputRef<'vir>, deps: &'enc mut TaskEncoderDependencies<'vir, DomainEnc>, } impl<'vir, 'enc> DomainEncData<'vir, 'enc> { @@ -353,7 +356,7 @@ impl<'vir, 'enc> DomainEncData<'vir, 'enc> { functions, deps, typeof_function, - generic_enc, + // generic_enc, } } @@ -397,11 +400,11 @@ impl<'vir, 'enc> DomainEncData<'vir, 'enc> { snap_to_prim, prim_to_snap: data.field_snaps_to_snap.to_known(), }; - specifics.bounds(ty).map(|(lower, upper)| { + if let Some((lower, upper)) = specifics.bounds(ty) { let exp = snap_to_prim.apply(self.vcx, [self.self_ex]); let axiom = self.mk_bounds_axiom(self.domain.name_str(), exp, lower, upper); self.axioms.push(axiom); - }); + } DomainEncSpecifics::Primitive(specifics) } pub fn mk_struct_specifics( @@ -442,7 +445,7 @@ impl<'vir, 'enc> DomainEncData<'vir, 'enc> { // Helper functions fn mk_field_functions( &mut self, - field_tys: &Vec>, + field_tys: &[FieldTy<'vir>], discr: Option<(FunctionIdent<'vir, UnaryArity<'vir>>, vir::Expr<'vir>, symbol::Symbol)>, stronger_cons_axiom: bool, ) -> DomainDataStruct<'vir> { @@ -761,7 +764,7 @@ impl<'vir> DomainDataPrim<'vir> { }; let size = abi::Size::from_bits(bit_width); let negative_value = if signed { - let value = size.sign_extend(value) as i128; + let value = size.sign_extend(value); Some(value).filter(|value| value.is_negative()) } else { None @@ -781,9 +784,9 @@ impl<'vir> DomainDataPrim<'vir> { fn bounds(&self, ty: ty::Ty<'vir>) -> Option<(vir::Expr<'vir>, vir::Expr<'vir>)> { match *self.prim_type { vir::TypeData::Bool => None, - ref int@vir::TypeData::Int { .. } => { + vir::TypeData::Int { .. } => { let rust_ty = ty.kind(); - Some(vir::with_vcx(|vcx| (vcx.get_min_int(int, rust_ty), vcx.get_max_int(int, rust_ty)))) + Some(vir::with_vcx(|vcx| (vcx.get_min_int(rust_ty), vcx.get_max_int(rust_ty)))) }, ref k => todo!("{k:?}"), } diff --git a/prusti-encoder/src/encoders/type/lifted/aggregate_cast.rs b/prusti-encoder/src/encoders/type/lifted/aggregate_cast.rs index b6f7a5ceb95..ee5a877edb8 100644 --- a/prusti-encoder/src/encoders/type/lifted/aggregate_cast.rs +++ b/prusti-encoder/src/encoders/type/lifted/aggregate_cast.rs @@ -3,7 +3,6 @@ use prusti_rustc_interface::{ middle::{mir, ty::{GenericArgs, Ty}}, span::def_id::DefId, }; -use rustc_middle::ty::ClosureArgs; use task_encoder::{TaskEncoder, EncodeFullResult}; use crate::encoders::lifted::cast::{CastArgs, CastToEnc}; @@ -40,7 +39,7 @@ impl<'tcx> From<&mir::AggregateKind<'tcx>> for AggregateType<'tcx> { mir::AggregateKind::Tuple => Self::Tuple, mir::AggregateKind::Closure(def_id, args) => Self::Closure { def_id: *def_id, - args: args, + args, }, mir::AggregateKind::Adt(def_id, variant_index, ..) => { Self::Adt { @@ -106,8 +105,8 @@ impl TaskEncoder for AggregateSnapArgsCastEnc { }) .collect::>(), AggregateType::Closure { - def_id, args, + .. } => { let cl_args = args.as_closure(); let upvar_tys = cl_args.upvar_tys(); diff --git a/prusti-encoder/src/encoders/type/lifted/casters.rs b/prusti-encoder/src/encoders/type/lifted/casters.rs index 5aa14a05fe0..f250d400134 100644 --- a/prusti-encoder/src/encoders/type/lifted/casters.rs +++ b/prusti-encoder/src/encoders/type/lifted/casters.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use task_encoder::{TaskEncoder, TaskEncoderDependencies, EncodeFullResult}; -use vir::{Arity, CallableIdent, FunctionIdent, MethodIdent, TypeData, UnaryArity, UnknownArity}; +use vir::{Arity, CallableIdent, FunctionIdent, MethodIdent, TypeData, UnknownArity}; use crate::encoders::{ domain::DomainEnc, lifted::ty_constructor::TyConstructorEnc, most_generic_ty::MostGenericTy, @@ -236,24 +236,23 @@ impl TaskEncoder for CastersEnc { deps: &mut TaskEncoderDependencies<'vir, Self>, ) -> EncodeFullResult<'vir, Self> { if ty.is_generic() { - deps.emit_output_ref(*ty, CastFunctionsOutputRef::AlreadyGeneric); + deps.emit_output_ref(*ty, CastFunctionsOutputRef::AlreadyGeneric)?; return Ok((&[], ())); } vir::with_vcx(|vcx| { - let domain_ref = deps.require_ref::(*ty).unwrap(); - let generic_ref = deps.require_ref::(()).unwrap(); + let domain_ref = deps.require_ref::(*ty)?; + let generic_ref = deps.require_ref::(())?; let self_ty = domain_ref.domain.apply(vcx, []); let base_name = &domain_ref.base_name; let ty_constructor = deps - .require_ref::(*ty) - .unwrap() + .require_ref::(*ty)? .ty_constructor; let ty_params = ty .generics() .into_iter() - .map(|g| deps.require_ref::(*g).unwrap()) - .collect::>(); + .map(|g| deps.require_ref::(*g)) + .collect::, _>>()?; let make_generic_arg_tys = std::iter::once(self_ty) .chain(ty_params.iter().map(|t| t.ty())) @@ -280,7 +279,7 @@ impl TaskEncoder for CastersEnc { make_generic: make_generic_ident, make_concrete: make_concrete_ident, }, - ); + )?; let make_generic_arg = vcx.mk_local_decl("self", self_ty); let make_generic_expr = vcx.mk_local_ex(make_generic_arg.name, make_generic_arg.ty); @@ -392,14 +391,14 @@ impl TaskEncoder for CastersEnc { deps: &mut TaskEncoderDependencies<'vir, Self>, ) -> EncodeFullResult<'vir, Self> { if ty.is_generic() { - deps.emit_output_ref(*ty, CastMethodsOutputRef::AlreadyGeneric); + deps.emit_output_ref(*ty, CastMethodsOutputRef::AlreadyGeneric)?; return Ok((&[], ())); } vir::with_vcx(|vcx| { - let predicate_ref = deps.require_ref::(*ty).unwrap(); - let generic_ref = deps.require_ref::(()).unwrap(); + let predicate_ref = deps.require_ref::(*ty)?; + let generic_ref = deps.require_ref::(())?; let base_name = predicate_ref.ref_to_pred.name(); - let ty_constructor = deps.require_ref::(*ty).unwrap(); + let ty_constructor = deps.require_ref::(*ty)?; let arg_tys = vcx.alloc_slice( &std::iter::once(&TypeData::Ref) @@ -423,10 +422,9 @@ impl TaskEncoder for CastersEnc { make_generic: make_generic_ident, make_concrete: make_concrete_ident, }, - ); + )?; let (make_generic_pure, _) = deps - .require_ref::>(*ty) - .unwrap() + .require_ref::>(*ty)? .expect_casters(); let self_decl = vcx.mk_local_decl("self", &TypeData::Ref); let self_expr = vcx.mk_local_ex(self_decl.name, self_decl.ty); @@ -477,7 +475,7 @@ impl TaskEncoder for CastersEnc { let generic_predicate = vcx.mk_predicate_app_expr(generic_predicate); let make_generic_pure_arg_exprs = std::iter::once(concrete_snap) - .chain(arg_ty_exprs.into_iter()) + .chain(arg_ty_exprs) .collect::>(); let make_generic_same_snap = vcx.mk_eq_expr( diff --git a/prusti-encoder/src/encoders/type/predicate.rs b/prusti-encoder/src/encoders/type/predicate.rs index 23d88c826b3..fe69c2dffc5 100644 --- a/prusti-encoder/src/encoders/type/predicate.rs +++ b/prusti-encoder/src/encoders/type/predicate.rs @@ -14,7 +14,7 @@ pub struct PredicateEnc; #[derive(Clone, Debug)] pub enum PredicateEncError { - UnsupportedType, + // UnsupportedType, } #[derive(Clone, Copy, Debug)] @@ -29,7 +29,7 @@ pub struct PredicateEncDataEnum<'vir> { pub discr: vir::Field<'vir>, pub discr_prim: DomainDataPrim<'vir>, pub discr_bounds: DiscrBounds<'vir>, - pub snap_to_discr_snap: FunctionIdent<'vir, UnaryArity<'vir>>, + // pub snap_to_discr_snap: FunctionIdent<'vir, UnaryArity<'vir>>, pub variants: &'vir [PredicateEncDataVariant<'vir>], } #[derive(Clone, Copy, Debug)] @@ -65,6 +65,7 @@ pub struct PredicateEncOutputRef<'vir> { /// Construct snapshot from Viper ref. pub ref_to_snap: FunctionIdent<'vir, UnknownArity<'vir>>, /// Construct snapshot from an unreachable. + #[allow(dead_code)] pub unreachable_to_snap: FunctionIdent<'vir, NullaryArity<'vir>>, /// Ref as first argument, followed by type parameters, followed by /// snapshot. Ensures predicate access to ref with snapshot value. This @@ -75,6 +76,7 @@ pub struct PredicateEncOutputRef<'vir> { pub snapshot: vir::Type<'vir>, //pub method_refold: &'vir str, pub specifics: PredicateEncData<'vir>, + #[allow(dead_code)] pub generics: &'vir [vir::LocalDecl<'vir>], } impl<'vir> task_encoder::OutputRefAny for PredicateEncOutputRef<'vir> {} @@ -230,7 +232,7 @@ impl TaskEncoder for PredicateEnc { specifics: PredicateEncData::Param, generics: &[], }, - ); + )?; let dep = deps.require_local::(())?; vir::with_vcx(|vcx| { let method_assign = mk_method_assign( @@ -256,16 +258,16 @@ impl TaskEncoder for PredicateEnc { } TyKind::Bool | TyKind::Char | TyKind::Int(_) | TyKind::Uint(_) | TyKind::Float(_) => { let specifics = PredicateEncData::Primitive(snap.specifics.expect_primitive()); - deps.emit_output_ref(*task_key, enc.output_ref(specifics)); + deps.emit_output_ref(*task_key, enc.output_ref(specifics))?; Ok((enc.mk_prim(&snap.base_name), ())) } - TyKind::Closure(def_id, args) => { + TyKind::Closure(_def_id, args) => { let snap_data = snap.specifics.expect_structlike(); let specifics = enc.mk_struct_ref(None, snap_data); deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::StructLike(specifics)), - ); + )?; let fields: Vec<_> = args .as_closure() @@ -284,7 +286,7 @@ impl TaskEncoder for PredicateEnc { deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::StructLike(specifics)), - ); + )?; let fields: Vec<_> = tys .iter() @@ -302,7 +304,7 @@ impl TaskEncoder for PredicateEnc { deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::StructLike(specifics)), - ); + )?; let fields = if !adt.is_box() { let variant = adt.non_enum_variant(); @@ -329,7 +331,7 @@ impl TaskEncoder for PredicateEnc { deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::EnumLike(specifics)), - ); + )?; let specifics = specifics.map(|specifics| { let variants: Vec<_> = specifics @@ -361,7 +363,7 @@ impl TaskEncoder for PredicateEnc { deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::EnumLike(None)), - ); + )?; Ok((enc.mk_enum(None), ())) } @@ -371,7 +373,7 @@ impl TaskEncoder for PredicateEnc { deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::Ref(specifics)), - ); + )?; let lifted_ty = deps.require_local::>(inner).unwrap(); let inner = deps @@ -385,7 +387,7 @@ impl TaskEncoder for PredicateEnc { deps.emit_output_ref( *task_key, enc.output_ref(PredicateEncData::StructLike(specifics)), - ); + )?; Ok((enc.mk_prim(&snap.base_name), ())) } unsupported_type => todo!("type not supported: {unsupported_type:?}"), @@ -585,7 +587,7 @@ impl<'vir, 'tcx> PredicateEncValues<'vir, 'tcx> { discr, discr_prim: data.discr_prim, discr_bounds: data.discr_bounds, - snap_to_discr_snap: data.snap_to_discr_snap, + // snap_to_discr_snap: data.snap_to_discr_snap, variants: self.vcx.alloc_slice(&variants), } }) @@ -719,6 +721,7 @@ impl<'vir, 'tcx> PredicateEncValues<'vir, 'tcx> { let fn_snap_body = self.vcx.mk_unfolding_expr(self.self_pred_read, snap); self.finalize(Some(fn_snap_body)) } + #[allow(clippy::type_complexity)] pub fn mk_enum( mut self, data: Option<( @@ -815,10 +818,7 @@ impl<'vir, 'tcx> PredicateEncValues<'vir, 'tcx> { let method_assign = mk_method_assign( self.vcx, self.method_assign, - self.generics - .iter() - .map(|g| (*g).into()) - .collect::>(), + self.generics.to_vec(), self.snap_inst, self.ref_to_pred, self.ref_to_snap, @@ -839,8 +839,8 @@ struct FieldApp<'vir> { self_field_snap: vir::Expr<'vir>, } -fn mk_method_assign<'vir, 'tcx>( - vcx: &'vir VirCtxt<'tcx>, +fn mk_method_assign<'vir>( + vcx: &'vir VirCtxt<'_>, ident: MethodIdent<'vir, UnknownArity<'vir>>, generics: Vec>, snapshot: vir::Type<'vir>, @@ -869,5 +869,5 @@ fn mk_method_assign<'vir, 'tcx>( vcx.mk_local_ex(self_new_local.name, snapshot), ), ]); - vcx.mk_method(ident, &assign_args, &[], &[], posts, None) + vcx.mk_method(ident, assign_args, &[], &[], posts, None) } diff --git a/prusti-encoder/src/lib.rs b/prusti-encoder/src/lib.rs index 42c08cf432d..ebb3e37858e 100644 --- a/prusti-encoder/src/lib.rs +++ b/prusti-encoder/src/lib.rs @@ -3,10 +3,6 @@ #![feature(box_patterns)] #![feature(never_type)] -extern crate rustc_middle; -extern crate rustc_serialize; -extern crate rustc_type_ir; - mod encoders; mod encoder_traits; pub mod request; @@ -159,7 +155,7 @@ pub fn test_entrypoint<'tcx>( program_methods.push(output.method_assign); } - std::fs::write("local-testing/simple.vpr", viper_code).unwrap(); + //std::fs::write("local-testing/simple.vpr", viper_code).unwrap(); let program = vir::with_vcx(|vcx| vcx.mk_program( vcx.alloc_slice(&program_fields), diff --git a/prusti-interface/src/environment/body.rs b/prusti-interface/src/environment/body.rs index 1f556529529..0c160e6728d 100644 --- a/prusti-interface/src/environment/body.rs +++ b/prusti-interface/src/environment/body.rs @@ -136,7 +136,7 @@ impl<'tcx> EnvBody<'tcx> { BodyWithBorrowckFacts { body: MirBody(Rc::new(body_with_facts.body)), - // borrowck_facts: Rc::new(facts), + // borrowck_facts: Rc::new(facts), } } @@ -174,9 +174,12 @@ impl<'tcx> EnvBody<'tcx> { { let param_env = self.tcx.param_env(caller_def_id.unwrap_or(def_id)); // TODO: figure out some other way to substitute without losing the region information - let body = self.tcx.erase_regions((&*body.0).clone()); - let monomorphised = self.tcx - .instantiate_and_normalize_erasing_regions(substs, param_env, ty::EarlyBinder::bind(body)); + let body = self.tcx.erase_regions((*body.0).clone()); + let monomorphised = self.tcx.instantiate_and_normalize_erasing_regions( + substs, + param_env, + ty::EarlyBinder::bind(body), + ); v.insert(MirBody(Rc::new(monomorphised))).clone() } else { unreachable!() @@ -195,7 +198,12 @@ impl<'tcx> EnvBody<'tcx> { /// Get the MIR body of a local impure function, monomorphised /// with the given type substitutions. - pub fn get_impure_fn_body(&self, def_id: LocalDefId, substs: GenericArgsRef<'tcx>, caller_def_id: Option) -> MirBody<'tcx> { + pub fn get_impure_fn_body( + &self, + def_id: LocalDefId, + substs: GenericArgsRef<'tcx>, + caller_def_id: Option, + ) -> MirBody<'tcx> { if let Some(body) = self.get_monomorphised(def_id.to_def_id(), substs, caller_def_id) { return body; } @@ -278,10 +286,12 @@ impl<'tcx> EnvBody<'tcx> { self.set_monomorphised(def_id, substs, caller_def_id, body) } - pub fn get_promoted_constant_body(&self, def_id: DefId, promoted: mir::Promoted) -> MirBody<'tcx> { - MirBody(Rc::new( - self.tcx.promoted_mir(def_id)[promoted].clone(), - )) + pub fn get_promoted_constant_body( + &self, + def_id: DefId, + promoted: mir::Promoted, + ) -> MirBody<'tcx> { + MirBody(Rc::new(self.tcx.promoted_mir(def_id)[promoted].clone())) } ///// Get Polonius facts of a local procedure. @@ -322,7 +332,7 @@ impl<'tcx> EnvBody<'tcx> { pub(crate) fn load_pure_fn_body(&mut self, def_id: LocalDefId) { assert!(!self.pure_fns.local.contains_key(&def_id)); - let body = Self::load_local_mir( self.tcx, def_id); + let body = Self::load_local_mir(self.tcx, def_id); self.pure_fns.local.insert(def_id, body); let bwbf = Self::load_local_mir_with_facts(self.tcx, def_id); // Also add to `impure_fns` since we'll also be encoding this as impure diff --git a/prusti-interface/src/environment/diagnostic.rs b/prusti-interface/src/environment/diagnostic.rs index be778c39ee6..6ad0bdb1f21 100644 --- a/prusti-interface/src/environment/diagnostic.rs +++ b/prusti-interface/src/environment/diagnostic.rs @@ -18,7 +18,7 @@ impl<'tcx> EnvDiagnostic<'tcx> { } fn configure_diagnostic + Clone, T: EmissionGuarantee>( - diagnostic: &mut Diag<'tcx,T>, + diagnostic: &mut Diag<'tcx, T>, sp: S, help: &Option, notes: &[(String, Option)], diff --git a/prusti-interface/src/environment/mir_storage.rs b/prusti-interface/src/environment/mir_storage.rs index 728474e9377..66e1dc59c94 100644 --- a/prusti-interface/src/environment/mir_storage.rs +++ b/prusti-interface/src/environment/mir_storage.rs @@ -1,10 +1,11 @@ -//! This module allows storing mir bodies with borrowck facts in a thread-local -//! storage. Unfortunately, thread local storage requires all data stored in it -//! to have a `'static` lifetime. Therefore, we transmute the lifetime `'tcx` -//! away when storing the data. To ensure that nothing gets meessed up, we -//! require the client to provide a witness: an instance of type `TyCtxt<'tcx>` -//! that is used to show that the lifetime that the client provided is indeed -//! `'tcx`. +//! This module allows storing mir bodies with borrowck facts in thread-local +//! storage. +//! +//! Unfortunately, thread-local storage requires all data stored in it to have +//! a `'static` lifetime. Therefore, we transmute the lifetime `'tcx` away when +//! storing the data. To ensure that nothing gets messed up, we require the +//! client to provide a witness: an instance of type `TyCtxt<'tcx>` that is +//! used to show that the lifetime that the client provided is indeed `'tcx`. use prusti_rustc_interface::{ borrowck::consumers::BodyWithBorrowckFacts, diff --git a/prusti-interface/src/environment/mod.rs b/prusti-interface/src/environment/mod.rs index 814eb9ebc25..4985f821009 100644 --- a/prusti-interface/src/environment/mod.rs +++ b/prusti-interface/src/environment/mod.rs @@ -24,9 +24,9 @@ mod name; mod query; pub use self::{ + body::EnvBody, collect_closure_defs_visitor::CollectClosureDefsVisitor, collect_prusti_spec_visitor::CollectPrustiSpecVisitor, - body::EnvBody, diagnostic::EnvDiagnostic, //loops::{LoopAnalysisError, PlaceAccess, PlaceAccessKind, ProcedureLoops}, //loops_utils::*, diff --git a/prusti-interface/src/environment/name.rs b/prusti-interface/src/environment/name.rs index 917220f2d65..59862b90cec 100644 --- a/prusti-interface/src/environment/name.rs +++ b/prusti-interface/src/environment/name.rs @@ -16,7 +16,12 @@ impl<'tcx> EnvName<'tcx> { /// Returns the path of the source that is being compiled pub fn source_path(self) -> PathBuf { - self.tcx.sess.local_crate_source_file().unwrap().into_local_path().unwrap() + self.tcx + .sess + .local_crate_source_file() + .unwrap() + .into_local_path() + .unwrap() } /// Returns the file name of the source that is being compiled diff --git a/prusti-interface/src/environment/query.rs b/prusti-interface/src/environment/query.rs index de78b150d19..76beb003120 100644 --- a/prusti-interface/src/environment/query.rs +++ b/prusti-interface/src/environment/query.rs @@ -7,7 +7,7 @@ use prusti_rustc_interface::{ hir::hir_id::HirId, middle::{ hir::map::Map, - ty::{self, GenericArgsRef, PredicatePolarity, ParamEnv, TraitPredicate, TyCtxt}, + ty::{self, GenericArgsRef, ParamEnv, PredicatePolarity, TraitPredicate, TyCtxt}, }, span::{ def_id::{DefId, LocalDefId}, diff --git a/prusti-interface/src/prusti_error.rs b/prusti-interface/src/prusti_error.rs index 505259a5761..f40c3250eac 100644 --- a/prusti-interface/src/prusti_error.rs +++ b/prusti-interface/src/prusti_error.rs @@ -6,8 +6,8 @@ use crate::environment::EnvDiagnostic; use ::log::warn; -use prusti_utils::config; use prusti_rustc_interface::{errors::MultiSpan, span::Span}; +use prusti_utils::config; /// The Prusti message that will be reported to the user. /// @@ -42,6 +42,7 @@ pub enum PrustiErrorKind { WarningOnError, } +#[allow(clippy::non_canonical_partial_ord_impl)] impl PartialOrd for PrustiError { fn partial_cmp(&self, other: &Self) -> Option { self.span diff --git a/prusti-interface/src/specs/checker/version_checks.rs b/prusti-interface/src/specs/checker/version_checks.rs index f1e6bdc124d..f54465241c7 100644 --- a/prusti-interface/src/specs/checker/version_checks.rs +++ b/prusti-interface/src/specs/checker/version_checks.rs @@ -3,8 +3,8 @@ use crate::{ environment::{EnvQuery, Environment}, utils, PrustiError, }; -use prusti_utils::config; use prusti_rustc_interface::{ast::ast::Attribute, errors::MultiSpan, hir, middle::hir::map::Map}; +use prusti_utils::config; /// Checks for mismatched version issues between `prusti` and `prusti-contracts`/`prusti-specs` pub struct MismatchedVersionsChecker; diff --git a/prusti-interface/src/specs/cross_crate.rs b/prusti-interface/src/specs/cross_crate.rs index 4d838a60913..37fb0a91eeb 100644 --- a/prusti-interface/src/specs/cross_crate.rs +++ b/prusti-interface/src/specs/cross_crate.rs @@ -1,9 +1,4 @@ -use prusti_rustc_interface::{ - metadata::creader::CStore, - serialize::{Decodable, Encodable}, - session::config::OutputType, - span::DUMMY_SP, -}; +use prusti_rustc_interface::{serialize::Decodable, session::config::OutputType, span::DUMMY_SP}; use rustc_hash::FxHashMap; use std::{fs, io, path}; @@ -44,7 +39,6 @@ impl CrossCrateSpecs { } fn import_specs(env: &mut Environment, def_spec: &mut DefSpecificationMap) { - let cstore = CStore::from_tcx(env.tcx()); // TODO: atm one needs to write `extern crate extern_spec_lib` to import the specs // from a crate which is not used in the current crate (e.g. an `#[extern_spec]` only crate) // Otherwise the crate doesn't show up in `tcx.crates()`. Is there some better way @@ -77,11 +71,11 @@ impl CrossCrateSpecs { fn write_into_file( env: &Environment, def_spec: &DefSpecificationMap, - path: &path::PathBuf, + path: &path::Path, ) -> io::Result<()> { DefSpecsEncoder::serialize( env.tcx(), - &path, + path, ( &def_spec.proc_specs, &def_spec.type_specs, diff --git a/prusti-interface/src/specs/decoder.rs b/prusti-interface/src/specs/decoder.rs index afdb3bdc570..7b7cb027c6c 100644 --- a/prusti-interface/src/specs/decoder.rs +++ b/prusti-interface/src/specs/decoder.rs @@ -1,15 +1,15 @@ use std::io; use prusti_rustc_interface::{ + ast::AttrId, hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash}, middle::{ implement_ty_decoder, ty::{codec::TyDecoder, Ty, TyCtxt}, }, - ast::AttrId, serialize::{opaque, Decodable, Decoder}, session::StableCrateId, - span::{BytePos, ExpnId, Symbol, Span, SpanDecoder, StableSourceFileId, SyntaxContext}, + span::{BytePos, ExpnId, Span, SpanDecoder, StableSourceFileId, Symbol, SyntaxContext}, }; use rustc_hash::FxHashMap; @@ -31,8 +31,8 @@ impl<'a, 'tcx> DefSpecsDecoder<'a, 'tcx> { //TODO: Unify with Encoder // Tags used for encoding Spans: -const TAG_FULL_SPAN: u8 = 0; -const TAG_PARTIAL_SPAN: u8 = 1; +//const TAG_FULL_SPAN: u8 = 0; +//const TAG_PARTIAL_SPAN: u8 = 1; // Tags for encoding Symbol's const SYMBOL_STR: u8 = 0; @@ -103,8 +103,7 @@ impl<'a, 'tcx> SpanDecoder for DefSpecsDecoder<'a, 'tcx> { // sessions, to map the old `DefId` to the new one. fn decode_def_id(&mut self) -> DefId { let def_path_hash = DefPathHash::decode(self); - self.tcx - .def_path_hash_to_def_id(def_path_hash).unwrap() + self.tcx.def_path_hash_to_def_id(def_path_hash).unwrap() } fn decode_attr_id(&mut self) -> AttrId { @@ -112,7 +111,6 @@ impl<'a, 'tcx> SpanDecoder for DefSpecsDecoder<'a, 'tcx> { } } - implement_ty_decoder!(DefSpecsDecoder<'a, 'tcx>); impl<'a, 'tcx> TyDecoder for DefSpecsDecoder<'a, 'tcx> { diff --git a/prusti-interface/src/specs/encoder.rs b/prusti-interface/src/specs/encoder.rs index c8804d1fd8a..2a202564cf4 100644 --- a/prusti-interface/src/specs/encoder.rs +++ b/prusti-interface/src/specs/encoder.rs @@ -1,5 +1,7 @@ use std::{ - collections::hash_map::Entry, io::{self, Error}, path::{Path, PathBuf} + collections::hash_map::Entry, + io::{self, Error}, + path::{Path, PathBuf}, }; use prusti_rustc_interface::{ @@ -12,7 +14,7 @@ use prusti_rustc_interface::{ serialize::{opaque, Encodable, Encoder}, span::{ hygiene::{raw_encode_syntax_context, HygieneEncodeContext}, - ExpnId, SourceFile, Span, SpanEncoder, StableSourceFileId, Symbol, SyntaxContext, + ExpnId, Span, SpanEncoder, StableSourceFileId, Symbol, SyntaxContext, }, }; @@ -28,8 +30,7 @@ pub struct DefSpecsEncoder<'a, 'tcx> { predicate_shorthands: FxHashMap, usize>, interpret_allocs: FxIndexSet, hygiene_context: &'a HygieneEncodeContext, - symbol_table: FxHashMap, - + symbol_table: FxHashMap, } impl<'a, 'tcx> DefSpecsEncoder<'a, 'tcx> { diff --git a/prusti-interface/src/specs/mod.rs b/prusti-interface/src/specs/mod.rs index cfeee99c58a..64bb9d962ba 100644 --- a/prusti-interface/src/specs/mod.rs +++ b/prusti-interface/src/specs/mod.rs @@ -65,8 +65,9 @@ struct TypeSpecRefs { countexample_print: Vec<(Option, LocalDefId)>, } -/// Specification collector, intended to be applied as a visitor over the crate -/// HIR. After the visit, [SpecCollector::build_def_specs] can be used to get back +/// Specification collector, applied as a visitor over the crate HIR. +/// +/// After the visit, [SpecCollector::build_def_specs] can be used to get back /// a mapping of DefIds (which may not be local due to extern specs) to their /// [typed::SpecificationSet], i.e. procedures, loop invariants, and structs. pub struct SpecCollector<'a, 'tcx> { diff --git a/prusti-interface/src/utils.rs b/prusti-interface/src/utils.rs index 5ed8c68e426..5a120ec0baf 100644 --- a/prusti-interface/src/utils.rs +++ b/prusti-interface/src/utils.rs @@ -47,7 +47,10 @@ pub fn expand_one_level<'tcx>( let res = current_place.expand_one_level(Place::from(guide_place), repacker); ( res.0.to_rust_place(repacker), - res.1.into_iter().map(|r| r.to_rust_place(repacker)).collect(), + res.1 + .into_iter() + .map(|r| r.to_rust_place(repacker)) + .collect(), ) } diff --git a/prusti-launch/src/bin/cargo-prusti.rs b/prusti-launch/src/bin/cargo-prusti.rs index d3ebce4ea57..0bc4e8dff2e 100644 --- a/prusti-launch/src/bin/cargo-prusti.rs +++ b/prusti-launch/src/bin/cargo-prusti.rs @@ -31,27 +31,76 @@ where // Remove the "-- -Pflag" arguments since these won't apply to `cargo check`. // They have already been loaded (and the Category B flags are used below). let args = args.take_while(|arg| arg != "--"); + let args = args.collect::>(); + + let args_manifest_path = args + .windows(2) + .filter_map(|w| { + if w[0] == "--manifest-path" { + Some(w[1].as_str()) + } else { + None + } + }) + .next(); // Category B flags (see dev-guide flags table): let cargo_path = config::cargo_path(); let command = config::cargo_command(); - let features = if launch::enable_prusti_feature(&cargo_path) && !config::be_rustc() { - ["--features", "prusti-contracts/prusti"].iter() - } else { - [].iter() - }; + let features = + if launch::enable_prusti_feature(&cargo_path, args_manifest_path) && !config::be_rustc() { + ["--features", "prusti-contracts/prusti"].iter() + } else { + [].iter() + }; let cargo_target = env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".to_string()); let cargo_target: PathBuf = [cargo_target, "verify".to_string()].into_iter().collect(); - let exit_status = Command::new(cargo_path) + + // Forward version checks directly to cargo. This is not thorough at all, + // but matches the version check performed by `ui_test` (which itself uses + // the `rustc_version` crate). + if args + .iter() + .any(|arg| arg == "-V" || arg == "-vV" || arg == "--version") + { + let exit_status = Command::new(cargo_path) + .args(args) + .env("RUST_TOOLCHAIN", launch::get_rust_toolchain_channel()) + .env("RUSTUP_TOOLCHAIN", launch::get_rust_toolchain_channel()) + .env("RUSTC", prusti_rustc_path) + .env("CARGO_TARGET_DIR", &cargo_target) + .status() + .expect("could not run cargo"); + return if exit_status.success() { + Ok(()) + } else { + Err(exit_status.code().unwrap_or(-1)) + }; + } + + let mut cargo_command = Command::new(cargo_path); + cargo_command .arg(&command) .args(features) - .args(args) + .args(&args) .env("RUST_TOOLCHAIN", launch::get_rust_toolchain_channel()) .env("RUSTUP_TOOLCHAIN", launch::get_rust_toolchain_channel()) .env("RUSTC", prusti_rustc_path) .env("PRUSTI_CARGO", "") - .env("CARGO_TARGET_DIR", &cargo_target) + .env("CARGO_TARGET_DIR", &cargo_target); + if let Some(manifest_path) = env::var("CARGO_MANIFEST_DIR").ok().or_else(|| { + args_manifest_path.and_then(|s| Some(PathBuf::from(s).parent()?.to_str()?.to_string())) + }) { + cargo_command.env("CARGO_MANIFEST_DIR", manifest_path); + } + + // TODO: the config::* calls below are an issue: they do not respect the + // manifest path, if provided through `--manifest-path` instead of + // `CARGO_MANIFEST_DIR`. As a result, `Prusti.toml` is read from the CWD + // even though the `Cargo.toml` is elsewhere. + + let exit_status = cargo_command // Category B flags (update the docs if any more are added): .env("PRUSTI_BE_RUSTC", config::be_rustc().to_string()) .env( @@ -84,7 +133,9 @@ fn copy_exported_specs(cargo_target: PathBuf) -> io::Result<()> { if build_dir.is_dir() && deps_dir.is_dir() { for entry in fs::read_dir(deps_dir)? { let entry = entry?.path(); - if let Some(ext) = entry.extension() && ext == "specs" { + if let Some(ext) = entry.extension() + && ext == "specs" + { if let Some(fname) = entry.file_name() { let pkg_name = fname.to_string_lossy(); if let Some(pkg_name) = pkg_name.split('-').next() { diff --git a/prusti-server/src/backend.rs b/prusti-server/src/backend.rs index 15270d9316f..579e19eca4e 100644 --- a/prusti-server/src/backend.rs +++ b/prusti-server/src/backend.rs @@ -1,8 +1,5 @@ use crate::dump_viper_program; -use prusti_utils::{ - config, - Stopwatch, -}; +use prusti_utils::{config, Stopwatch}; use viper::{VerificationContext, VerificationResult}; pub enum Backend<'a> { @@ -31,7 +28,7 @@ impl<'a> Backend<'a> { dump_viper_program( &ast_utils, viper_program, - &program.get_name_with_check_mode(), + program.get_name_with_check_mode(), ); } diff --git a/prusti-server/src/lib.rs b/prusti-server/src/lib.rs index bc28af57fee..d137807e962 100644 --- a/prusti-server/src/lib.rs +++ b/prusti-server/src/lib.rs @@ -1,17 +1,15 @@ #![feature(rustc_private)] - // © 2021, ETH Zurich // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. - #![warn(clippy::disallowed_types)] use log::info; +use once_cell::sync::Lazy; use prusti_utils::{config, Stopwatch}; use viper::{PersistentCache, Viper}; -use once_cell::sync::Lazy; mod client; mod process_verification; diff --git a/prusti-server/src/process_verification.rs b/prusti-server/src/process_verification.rs index 7c3480e8d02..95b2043c713 100644 --- a/prusti-server/src/process_verification.rs +++ b/prusti-server/src/process_verification.rs @@ -46,42 +46,42 @@ pub fn process_verification_request<'v, 't: 'v>( request.program.get_name(), ); /* - let build_or_dump_viper_program = || { - let mut stopwatch = Stopwatch::start("prusti-server", "construction of JVM objects"); - let ast_factory = verification_context.new_ast_factory(); - - let viper_program = prusti_viper::program_to_viper(request.program, &ast_factory); - //let viper_program = request - // .program - // .to_viper(prusti_common::vir::LoweringContext::default(), &ast_factory); - if config::dump_viper_program() { - stopwatch.start_next("dumping viper program"); - dump_viper_program( - &ast_utils, - viper_program, - &request.program.get_name_with_check_mode(), - ); - } + let build_or_dump_viper_program = || { + let mut stopwatch = Stopwatch::start("prusti-server", "construction of JVM objects"); + let ast_factory = verification_context.new_ast_factory(); + + let viper_program = prusti_viper::program_to_viper(request.program, &ast_factory); + //let viper_program = request + // .program + // .to_viper(prusti_common::vir::LoweringContext::default(), &ast_factory); + if config::dump_viper_program() { + stopwatch.start_next("dumping viper program"); + dump_viper_program( + &ast_utils, + viper_program, + &request.program.get_name_with_check_mode(), + ); + } - viper_program - }; + viper_program + }; - // Only for testing: Print the hash and skip verification. - if config::print_hash() { - println!( - "Received verification request for: {}", - request.program.get_name() - ); - println!("Hash of the request is: {hash}"); - // Some tests need the dump to report a diff of the Viper programs. - if config::dump_viper_program() { - ast_utils.with_local_frame(16, || { - let _ = build_or_dump_viper_program(); - }); + // Only for testing: Print the hash and skip verification. + if config::print_hash() { + println!( + "Received verification request for: {}", + request.program.get_name() + ); + println!("Hash of the request is: {hash}"); + // Some tests need the dump to report a diff of the Viper programs. + if config::dump_viper_program() { + ast_utils.with_local_frame(16, || { + let _ = build_or_dump_viper_program(); + }); + } + return viper::VerificationResult::Success; } - return viper::VerificationResult::Success; - } -*/ + */ // Early return in case of cache hit if config::enable_cache() { if let Some(result) = cache.get(hash) { diff --git a/prusti-server/src/server.rs b/prusti-server/src/server.rs index 3f412ffde84..086f5f1c9b4 100644 --- a/prusti-server/src/server.rs +++ b/prusti-server/src/server.rs @@ -18,7 +18,7 @@ use viper::{PersistentCache, Viper}; use warp::Filter; #[derive(Debug)] -struct BincodeReject(bincode::Error); +struct BincodeReject(#[allow(dead_code)] bincode::Error); impl warp::reject::Reject for BincodeReject {} pub fn start_server_on_port(port: u16) { diff --git a/prusti-server/src/verification_request.rs b/prusti-server/src/verification_request.rs index dc73215db10..7d3627a9912 100644 --- a/prusti-server/src/verification_request.rs +++ b/prusti-server/src/verification_request.rs @@ -13,7 +13,7 @@ pub struct VerificationRequest { pub backend_config: ViperBackendConfig, } -impl<'vir> VerificationRequest { +impl VerificationRequest { pub(crate) fn get_hash(&self) -> u64 { self.program.get_hash() } diff --git a/prusti-server/tests/basic_requests.rs b/prusti-server/tests/basic_requests.rs index 64c2ed6d388..b60fd9ce2fb 100644 --- a/prusti-server/tests/basic_requests.rs +++ b/prusti-server/tests/basic_requests.rs @@ -1,11 +1,11 @@ #![feature(rustc_private)] use lazy_static::lazy_static; -use vir::*; use prusti_server::{ spawn_server_thread, tokio::runtime::Builder, PrustiClient, VerificationRequest, ViperBackendConfig, }; use viper::VerificationResult; +use vir::*; lazy_static! { // only start the jvm & server once diff --git a/prusti-tests/Cargo.toml b/prusti-tests/Cargo.toml index 568cca9184b..1888cada9a0 100644 --- a/prusti-tests/Cargo.toml +++ b/prusti-tests/Cargo.toml @@ -5,15 +5,16 @@ authors = ["Prusti Devs "] edition = "2021" [dev-dependencies] -compiletest_rs = "0.9" prusti-server = { path = "../prusti-server" } prusti-launch = { path = "../prusti-launch", artifact = "bin" } prusti = { path = "../prusti", artifact = "bin" } -cargo-test-support = { git = "https://github.com/rust-lang/cargo.git", rev = "17f8088" } ureq = "2.1" log = { version = "0.4", features = ["release_max_level_info"] } env_logger = "0.10" +ui_test = "0.27" +ctrlc = "3.4" +regex = "1.11" -[package.metadata.rust-analyzer] -# This crate uses #[feature(rustc_private)] -rustc_private = true +[[test]] +name = "main" +harness = false diff --git a/prusti-tests/tests/cargo_verify/failing_crate/Cargo.toml b/prusti-tests/tests/cargo_verify/failing_crate/Cargo.toml deleted file mode 100644 index 0f696d00218..00000000000 --- a/prusti-tests/tests/cargo_verify/failing_crate/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "failing_crate" -version = "0.1.0" -edition = "2021" - -[dependencies] -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this - -# Declare that this crate is not part of a workspace -[workspace] diff --git a/prusti-tests/tests/cargo_verify/failing_crate/output.stderr b/prusti-tests/tests/cargo_verify/failing_crate/output.stderr deleted file mode 100644 index 99481cdb3f1..00000000000 --- a/prusti-tests/tests/cargo_verify/failing_crate/output.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: [Prusti: verification error] precondition might not hold. - --> src/main.rs:6:5 - | -6 | requires_large_number(10); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the failing assertion is here - --> src/utils.rs:3:12 - | -3 | #[requires(x > 999)] - | ^^^^^^^ - -error: could not compile `failing_crate` due to previous error diff --git a/prusti-tests/tests/cargo_verify/failing_crate_fail/Cargo.stderr b/prusti-tests/tests/cargo_verify/failing_crate_fail/Cargo.stderr new file mode 100644 index 00000000000..6e6b6db3140 --- /dev/null +++ b/prusti-tests/tests/cargo_verify/failing_crate_fail/Cargo.stderr @@ -0,0 +1,13 @@ +error: [Prusti: verification error] precondition might not hold + --> src/main.rs:6:5 + | +6 | requires_large_number(10); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the failing precondition is here + --> src/utils.rs:3:12 + | +3 | #[requires(x > 999)] + | ^^^^^^^ + +error: could not compile `failing_crate_fail` (bin "failing_crate_fail") due to 1 previous error diff --git a/prusti-tests/tests/cargo_verify/failing_crate_fail/Cargo.toml b/prusti-tests/tests/cargo_verify/failing_crate_fail/Cargo.toml new file mode 100644 index 00000000000..f8f8f1f9639 --- /dev/null +++ b/prusti-tests/tests/cargo_verify/failing_crate_fail/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "failing_crate_fail" +version = "0.1.0" +edition = "2021" + +[dependencies] +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } + +# Declare that this crate is not part of a workspace +[workspace] diff --git a/prusti-tests/tests/cargo_verify/failing_crate/src/main.rs b/prusti-tests/tests/cargo_verify/failing_crate_fail/src/main.rs similarity index 100% rename from prusti-tests/tests/cargo_verify/failing_crate/src/main.rs rename to prusti-tests/tests/cargo_verify/failing_crate_fail/src/main.rs diff --git a/prusti-tests/tests/cargo_verify/failing_crate/src/utils.rs b/prusti-tests/tests/cargo_verify/failing_crate_fail/src/utils.rs similarity index 100% rename from prusti-tests/tests/cargo_verify/failing_crate/src/utils.rs rename to prusti-tests/tests/cargo_verify/failing_crate_fail/src/utils.rs diff --git a/prusti-tests/tests/cargo_verify/failing_stable_toolchain/Cargo.toml b/prusti-tests/tests/cargo_verify/failing_stable_toolchain/Cargo.toml deleted file mode 100644 index ef738e251f5..00000000000 --- a/prusti-tests/tests/cargo_verify/failing_stable_toolchain/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "failing_stable_toolchain" -version = "0.1.0" -edition = "2021" - -[dependencies] -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this - -# Declare that this crate is not part of a workspace -[workspace] diff --git a/prusti-tests/tests/cargo_verify/failing_stable_toolchain/output.stderr b/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/Cargo.stderr similarity index 62% rename from prusti-tests/tests/cargo_verify/failing_stable_toolchain/output.stderr rename to prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/Cargo.stderr index a429ccf5f0d..6026e7194f3 100644 --- a/prusti-tests/tests/cargo_verify/failing_stable_toolchain/output.stderr +++ b/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/Cargo.stderr @@ -6,16 +6,16 @@ warning: unused variable: `unused` | = note: `#[warn(unused_variables)]` on by default -error: [Prusti: verification error] precondition might not hold. +error: [Prusti: verification error] precondition might not hold --> src/main.rs:9:5 | 9 | test(1, 0); | ^^^^^^^^^^ | -note: the failing assertion is here +note: the failing precondition is here --> src/main.rs:3:12 | 3 | #[requires(x > 123)] | ^^^^^^^ -error: could not compile `failing_stable_toolchain` due to previous error; 1 warning emitted +error: could not compile `failing_stable_toolchain_fail` (bin "failing_stable_toolchain_fail") due to 1 previous error; 1 warning emitted diff --git a/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/Cargo.toml b/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/Cargo.toml new file mode 100644 index 00000000000..d95ecf430bd --- /dev/null +++ b/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "failing_stable_toolchain_fail" +version = "0.1.0" +edition = "2021" + +[dependencies] +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } + +# Declare that this crate is not part of a workspace +[workspace] diff --git a/prusti-tests/tests/cargo_verify/failing_stable_toolchain/rust-toolchain.toml b/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/rust-toolchain.toml similarity index 100% rename from prusti-tests/tests/cargo_verify/failing_stable_toolchain/rust-toolchain.toml rename to prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/rust-toolchain.toml diff --git a/prusti-tests/tests/cargo_verify/failing_stable_toolchain/src/main.rs b/prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/src/main.rs similarity index 100% rename from prusti-tests/tests/cargo_verify/failing_stable_toolchain/src/main.rs rename to prusti-tests/tests/cargo_verify/failing_stable_toolchain_fail/src/main.rs diff --git a/prusti-tests/tests/cargo_verify/foreign_mods/Cargo.toml b/prusti-tests/tests/cargo_verify/foreign_mods/Cargo.toml index bad5c5102ce..b6018840e1c 100644 --- a/prusti-tests/tests/cargo_verify/foreign_mods/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/foreign_mods/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" build = "build.rs" [dependencies] -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } [build-dependencies] cc = "1.0" diff --git a/prusti-tests/tests/cargo_verify/library_contracts_test/Cargo.toml b/prusti-tests/tests/cargo_verify/library_contracts_test/Cargo.toml index 66fbec89b92..95de337e819 100644 --- a/prusti-tests/tests/cargo_verify/library_contracts_test/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/library_contracts_test/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] library_contracts_lib = { path = "library_contracts_lib" } library_contracts_extern_specs = { path = "library_contracts_extern_specs" } -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } # Declare that this crate is not part of a workspace [workspace] diff --git a/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_extern_specs/Cargo.toml b/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_extern_specs/Cargo.toml index fa7be29ea1d..7aabf10905c 100644 --- a/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_extern_specs/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_extern_specs/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] library_contracts_lib = { path = "../library_contracts_lib" } -prusti-contracts = { path = "../prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../../prusti-contracts/prusti-contracts" } # Declare that this crate is not part of a workspace [workspace] diff --git a/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_lib/Cargo.toml b/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_lib/Cargo.toml index fe79570e58b..2f66526317f 100644 --- a/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_lib/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/library_contracts_test/library_contracts_lib/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -prusti-contracts = { path = "../prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../../prusti-contracts/prusti-contracts" } # Declare that this crate is not part of a workspace [workspace] diff --git a/prusti-tests/tests/cargo_verify/no_deps/Cargo.toml b/prusti-tests/tests/cargo_verify/no_deps/Cargo.toml index 1250100f253..99dd5e62d47 100644 --- a/prusti-tests/tests/cargo_verify/no_deps/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/no_deps/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } bad_dependency = { path = "bad_dependency" } # Declare that this crate is not part of a workspace diff --git a/prusti-tests/tests/cargo_verify/prusti_toml/output.stderr b/prusti-tests/tests/cargo_verify/prusti_toml/Cargo.stderr similarity index 100% rename from prusti-tests/tests/cargo_verify/prusti_toml/output.stderr rename to prusti-tests/tests/cargo_verify/prusti_toml/Cargo.stderr diff --git a/prusti-tests/tests/cargo_verify/prusti_toml/output.stdout b/prusti-tests/tests/cargo_verify/prusti_toml/Cargo.stdout similarity index 100% rename from prusti-tests/tests/cargo_verify/prusti_toml/output.stdout rename to prusti-tests/tests/cargo_verify/prusti_toml/Cargo.stdout diff --git a/prusti-tests/tests/cargo_verify/prusti_toml/Cargo.toml b/prusti-tests/tests/cargo_verify/prusti_toml/Cargo.toml index 9cfd358fb2c..8e5a976bc12 100644 --- a/prusti-tests/tests/cargo_verify/prusti_toml/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/prusti_toml/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } # Declare that this crate is not part of a workspace [workspace] diff --git a/prusti-tests/tests/cargo_verify/prusti_toml_fail/output.stderr b/prusti-tests/tests/cargo_verify/prusti_toml_fail/Cargo.stderr similarity index 100% rename from prusti-tests/tests/cargo_verify/prusti_toml_fail/output.stderr rename to prusti-tests/tests/cargo_verify/prusti_toml_fail/Cargo.stderr diff --git a/prusti-tests/tests/cargo_verify/prusti_toml_fail/Cargo.toml b/prusti-tests/tests/cargo_verify/prusti_toml_fail/Cargo.toml index 9cfd358fb2c..8e5a976bc12 100644 --- a/prusti-tests/tests/cargo_verify/prusti_toml_fail/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/prusti_toml_fail/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } # Declare that this crate is not part of a workspace [workspace] diff --git a/prusti-tests/tests/cargo_verify/simple_assert_false_fail/Cargo.stderr b/prusti-tests/tests/cargo_verify/simple_assert_false_fail/Cargo.stderr new file mode 100644 index 00000000000..86a0567554e --- /dev/null +++ b/prusti-tests/tests/cargo_verify/simple_assert_false_fail/Cargo.stderr @@ -0,0 +1,9 @@ +error: [Prusti: verification error] unreachable statement might be reached + --> src/main.rs:2:5 + | +2 | assert!(false); + | ^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: could not compile `simple_assert_false_fail` (bin "simple_assert_false_fail") due to 1 previous error diff --git a/prusti-tests/tests/cargo_verify/simple_assert_false_fail/Cargo.toml b/prusti-tests/tests/cargo_verify/simple_assert_false_fail/Cargo.toml new file mode 100644 index 00000000000..e07e8fb598e --- /dev/null +++ b/prusti-tests/tests/cargo_verify/simple_assert_false_fail/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "simple_assert_false_fail" +version = "0.1.0" +edition = "2021" + +[dependencies] +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } + +# Declare that this crate is not part of a workspace +[workspace] diff --git a/prusti-tests/tests/cargo_verify/simple_assert_false_fail/src/main.rs b/prusti-tests/tests/cargo_verify/simple_assert_false_fail/src/main.rs new file mode 100644 index 00000000000..8a709d5b862 --- /dev/null +++ b/prusti-tests/tests/cargo_verify/simple_assert_false_fail/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + assert!(false); +} diff --git a/prusti-tests/tests/cargo_verify/simple_assert_true/Cargo.toml b/prusti-tests/tests/cargo_verify/simple_assert_true/Cargo.toml new file mode 100644 index 00000000000..d40d6ca9b6f --- /dev/null +++ b/prusti-tests/tests/cargo_verify/simple_assert_true/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "simple_assert_true" +version = "0.1.0" +edition = "2021" + +[dependencies] +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } + +# Declare that this crate is not part of a workspace +[workspace] diff --git a/prusti-tests/tests/cargo_verify/simple_assert_true/src/main.rs b/prusti-tests/tests/cargo_verify/simple_assert_true/src/main.rs new file mode 100644 index 00000000000..432fe8cce7c --- /dev/null +++ b/prusti-tests/tests/cargo_verify/simple_assert_true/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + assert!(true); +} diff --git a/prusti-tests/tests/cargo_verify/test_no_std/Cargo.toml b/prusti-tests/tests/cargo_verify/test_no_std/Cargo.toml index 1785eb1d4b5..8767bf5b61c 100644 --- a/prusti-tests/tests/cargo_verify/test_no_std/Cargo.toml +++ b/prusti-tests/tests/cargo_verify/test_no_std/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] libc = { version = "0.2", default-features = false } -prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this +prusti-contracts = { path = "../../../../prusti-contracts/prusti-contracts" } [profile.dev] panic = "abort" diff --git a/prusti-tests/tests/cargotest.rs b/prusti-tests/tests/cargotest.rs deleted file mode 100644 index 19d9f1c9a9c..00000000000 --- a/prusti-tests/tests/cargotest.rs +++ /dev/null @@ -1,241 +0,0 @@ -// © 2021, ETH Zurich -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -use cargo_test_support::{cargo_test, project, symlink_supported}; -use std::{ - fs, - path::{Path, PathBuf}, -}; - -fn cargo_prusti_path() -> PathBuf { - let target_directory = if cfg!(debug_assertions) { - "debug" - } else { - "release" - }; - let executable_name = if cfg!(windows) { - "cargo-prusti.exe" - } else { - "cargo-prusti" - }; - let local_prusti_rustc_path: PathBuf = ["target", target_directory, executable_name] - .iter() - .collect(); - if local_prusti_rustc_path.exists() { - return fs::canonicalize(&local_prusti_rustc_path).unwrap_or_else(|_| { - panic!("Failed to canonicalize the path {local_prusti_rustc_path:?}") - }); - } - let workspace_prusti_rustc_path: PathBuf = ["..", "target", target_directory, executable_name] - .iter() - .collect(); - if workspace_prusti_rustc_path.exists() { - return fs::canonicalize(&workspace_prusti_rustc_path).unwrap_or_else(|_| { - panic!("Failed to canonicalize the path {workspace_prusti_rustc_path:?}") - }); - } - panic!( - "Could not find the {target_directory:?} cargo-prusti binary to be used in tests. \ - It might be that Prusti has not been compiled correctly." - ); -} - -#[cargo_test] -fn simple_assert_true() { - let p = project() - .file("src/main.rs", "fn main() { assert!(true); }") - .build(); - p.process(cargo_prusti_path()).run(); -} - -#[cargo_test] -fn simple_assert_false() { - let p = project() - .file("src/main.rs", "fn main() { assert!(false); }") - .build(); - p.process(cargo_prusti_path()) - .with_status(101) - .with_stderr( - "\ -[CHECKING] foo v0.0.1 ([..]) -[WARNING] Prusti specifications are supported only from 2018 edition. Please specify the edition with adding a command line argument `--edition=2018` or `--edition=2021`. - -[ERROR] [Prusti: verification error] the asserted expression might not hold - --> src/main.rs:1:13 - | -1 | fn main() { assert!(false); } - | ^^^^^^^^^^^^^^ - | - = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: `foo` (bin \"foo\") generated 1 warning -error: could not compile `foo` due to previous error; 1 warning emitted -", - ) - .run(); -} - -/// Test `cargo-prusti` on one of the crates in `test/cargo_verify`. -/// -/// Special files and folders in the root of the test crate: -/// * `output.stdout` and `output.stderr`: if present, they are used to check the output of -/// `cargo-prusti`. -/// * `prusti-contracts` and related Prusti crates: during the test they will link to the -/// corresponding Prusti crate. -/// -/// This function requires symlinks to be supported. -/// -/// For more details on the special syntax allowed in the `output.*` files, check the documentation -/// of `cargo_test_support`: . -fn test_local_project>(project_name: T) { - let mut project_builder = project().no_manifest(); - let relative_project_path = Path::new("tests/cargo_verify").join(project_name.into()); - let project_path = fs::canonicalize(&relative_project_path).unwrap_or_else(|_| { - panic!( - "Failed to canonicalize the path {}", - relative_project_path.display() - ) - }); - - // Populate the test project with symlinks to the local project - let project_path_content = fs::read_dir(&project_path) - .unwrap_or_else(|_| panic!("Failed to read directory {}", project_path.display())); - for entry in project_path_content { - let entry = entry - .unwrap_or_else(|_| panic!("Failed to read content of {}", project_path.display())); - let path = entry.path(); - let file_name = path - .as_path() - .file_name() - .unwrap_or_else(|| panic!("Failed to obtain the name of {}", path.display())); - if file_name == "target" { - continue; - } - if path.is_dir() { - project_builder = project_builder.symlink_dir(path.as_path(), Path::new(file_name)); - } else { - project_builder = project_builder.symlink(path.as_path(), Path::new(file_name)); - } - } - - // Create a special symlink for prusti_contract and related Prusti crates - let prusti_dev_path = project_path - .parent() - .and_then(|p| p.parent()) - .and_then(|p| p.parent()) - .and_then(|p| p.parent()) - .unwrap_or_else(|| { - panic!( - "Failed to obtain parent folders of {}", - project_path.display() - ) - }); - project_builder = project_builder.symlink_dir( - prusti_dev_path.join("prusti-contracts").as_path(), - Path::new("prusti-contracts"), - ); - - // Fetch dependencies using the same target folder of cargo-prusti - let project = project_builder.build(); - project - .process("cargo") - .arg("--config") - .arg("net.retry=5") - .arg("build") - .env("CARGO_TARGET_DIR", "target/verify") - .run(); - - // Set the expected exit status, stdout and stderr - let mut test_builder = project.process(cargo_prusti_path()); - test_builder.arg("--quiet"); - let opt_expected_stdout = fs::read_to_string(project_path.join("output.stdout")).ok(); - let opt_expected_stderr = fs::read_to_string(project_path.join("output.stderr")).ok(); - if let Some(ref expected_stdout) = opt_expected_stdout { - // In some cases, Prusti outputs more macro definitions than needed. - // See: https://github.com/viperproject/prusti-dev/pull/762 - test_builder.with_stdout_contains(expected_stdout); - } - if let Some(ref expected_stderr) = opt_expected_stderr { - test_builder.with_status(101).with_stderr(expected_stderr); - } - - // Run the test - test_builder.run(); -} - -#[cargo_test] -fn test_symlinks() { - // Required by `test_local_project` - assert!(symlink_supported()); -} - -// TODO: automatically create a test for each folder in `test/cargo_verify`. -// Each of the following functions, listed in alphabetic order, test a crate in `cargo_verify/`. - -#[cargo_test] -fn test_failing_crate() { - test_local_project("failing_crate"); -} - -#[cargo_test] -fn test_failing_stable_toolchain() { - test_local_project("failing_stable_toolchain"); -} - -#[cargo_test] -fn test_foreign_mods() { - test_local_project("foreign_mods"); -} - -#[cargo_test] -fn test_library_contracts_test() { - test_local_project("library_contracts_test"); -} - -#[cargo_test] -fn test_no_deps() { - test_local_project("no_deps"); -} - -#[cargo_test] -fn test_overflow_checks() { - test_local_project("overflow_checks"); -} - -#[cargo_test] -fn test_prusti_toml() { - test_local_project("prusti_toml"); -} - -#[cargo_test] -fn test_prusti_toml_fail() { - let old_value = if let Ok(value) = std::env::var("RUST_BACKTRACE") { - // We need to remove this environment variable because it affects the - // compiler output. - std::env::remove_var("RUST_BACKTRACE"); - Some(value) - } else { - None - }; - test_local_project("prusti_toml_fail"); - if let Some(value) = old_value { - std::env::set_var("RUST_BACKTRACE", value) - } -} - -// `#![no_std]` binaries on Windows are not a thing yet, -// see . -#[cfg_attr(windows, ignore)] -#[cargo_test] -fn test_no_std() { - test_local_project("test_no_std"); -} - -#[ignore] // Currently broken -#[cargo_test] -fn test_veribetrfs() { - test_local_project("veribetrfs"); -} diff --git a/prusti-tests/tests/compiletest.rs b/prusti-tests/tests/compiletest.rs deleted file mode 100644 index c1dafc5a37b..00000000000 --- a/prusti-tests/tests/compiletest.rs +++ /dev/null @@ -1,219 +0,0 @@ -// © 2020, ETH Zurich -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#![feature(custom_test_frameworks)] -// Custom test runner, to avoid libtest being wrapped around compiletest which -// wraps libtest. -#![test_runner(test_runner)] - -use compiletest_rs::{common::Mode, run_tests, Config}; -use log::{error, info}; -use prusti_server::spawn_server_thread; -use std::{env, path::PathBuf}; - -fn find_prusti_rustc_path() -> PathBuf { - let target_directory = if cfg!(debug_assertions) { - "debug" - } else { - "release" - }; - let executable_name = if cfg!(windows) { - "prusti-rustc.exe" - } else { - "prusti-rustc" - }; - let local_prusti_rustc_path: PathBuf = ["target", target_directory, executable_name] - .iter() - .collect(); - if local_prusti_rustc_path.exists() { - return local_prusti_rustc_path; - } - let workspace_prusti_rustc_path: PathBuf = ["..", "target", target_directory, executable_name] - .iter() - .collect(); - if workspace_prusti_rustc_path.exists() { - return workspace_prusti_rustc_path; - } - panic!( - "Could not find the {target_directory:?} prusti-rustc binary to be used in tests. \ - It might be that Prusti has not been compiled correctly." - ); -} - -/// This type allows to temporary modify an environment variable. -/// When this structure is dropped (falls out of scope), the original value will be restored. -struct TemporaryEnvVar { - name: String, - original: Option, -} - -impl TemporaryEnvVar { - /// Temporarily set an environment variable, until the returned value is dropped. - fn set(name: &str, value: &str) -> Self { - let original: Option = env::var(name).ok(); - env::set_var(name, value); - TemporaryEnvVar { - name: name.to_string(), - original, - } - } -} - -impl Drop for TemporaryEnvVar { - fn drop(&mut self) { - match self.original { - Some(ref old_value) => env::set_var(&self.name, old_value), - None => env::remove_var(&self.name), - } - } -} - -fn run_prusti_tests(group_name: &str, filter: &Option, rustc_flags: Option<&str>) { - let mut config = Config { - rustc_path: find_prusti_rustc_path(), - ..Config::default() - }; - - // Filter the tests to run - if let Some(filter) = filter { - config.filters.push(filter.clone()); - } - - // Add compilation flags - config.target_rustcflags = Some(format!("--edition=2018 {}", rustc_flags.unwrap_or(""))); - - let path: PathBuf = ["tests", group_name, "ui"].iter().collect(); - if path.exists() { - config.target_rustcflags = Some(format!( - "--color=never {}", - config.target_rustcflags.unwrap_or_default() - )); - config.mode = Mode::Ui; - config.src_base = path; - run_tests(&config); - } - - let path: PathBuf = ["tests", group_name, "pass"].iter().collect(); - if path.exists() { - config.mode = Mode::RunPass; - config.src_base = path; - run_tests(&config); - } - - let path: PathBuf = ["tests", group_name, "fail"].iter().collect(); - if path.exists() { - config.mode = Mode::CompileFail; - config.src_base = path; - run_tests(&config); - } -} - -fn run_no_verification(group_name: &str, filter: &Option) { - let _temporary_env_vars = ( - TemporaryEnvVar::set("PRUSTI_FULL_COMPILATION", "true"), - TemporaryEnvVar::set("PRUSTI_NO_VERIFY", "true"), - TemporaryEnvVar::set("PRUSTI_QUIET", "true"), - ); - - run_prusti_tests(group_name, filter, None); -} - -fn run_verification_base(group_name: &str, filter: &Option) { - let _temporary_env_vars = ( - TemporaryEnvVar::set("PRUSTI_FULL_COMPILATION", "true"), - TemporaryEnvVar::set("PRUSTI_QUIET", "true"), - ); - - run_prusti_tests(group_name, filter, Some("-A warnings")); -} - -fn run_verification_no_overflow(group_name: &str, filter: &Option) { - let _temporary_env_vars = (TemporaryEnvVar::set("PRUSTI_CHECK_OVERFLOWS", "false"),); - - run_verification_base(group_name, filter); -} - -fn run_verification_overflow(group_name: &str, filter: &Option) { - run_verification_base(group_name, filter); -} - -fn run_verification_core_proof(group_name: &str, filter: &Option) { - let _temporary_env_vars = ( - TemporaryEnvVar::set("PRUSTI_CHECK_PANICS", "false"), - TemporaryEnvVar::set("PRUSTI_CHECK_OVERFLOWS", "false"), - ); - - run_verification_base(group_name, filter); -} - -fn run_lifetimes_dump(group_name: &str, filter: &Option) { - let _temporary_env_vars = ( - TemporaryEnvVar::set("PRUSTI_NO_VERIFY", "true"), - TemporaryEnvVar::set("PRUSTI_DUMP_BORROWCK_INFO", "true"), - TemporaryEnvVar::set("PRUSTI_QUIET", "true"), - ); - - run_prusti_tests(group_name, filter, None); -} - -fn test_runner(_tests: &[&()]) { - env_logger::init_from_env(env_logger::Env::new().filter_or("PRUSTI_LOG", "warn")); - - // Spawn server process as child (so it stays around until main function terminates) - let server_address = spawn_server_thread(); - env::set_var("PRUSTI_SERVER_ADDRESS", server_address.to_string()); - let save_verification_cache = - || match ureq::post(&format!("http://{server_address}/save")).call() { - Ok(response) => { - info!("Saving verification cache: {}", response.status_text()); - } - Err(ureq::Error::Status(_code, response)) => { - error!("Error while saving verification cache: {response:?}"); - } - Err(err) => error!("Error while saving verification cache: {err}"), - }; - - // Filter the tests to run - let filter = env::args().nth(1); - - // Test the parsing of specifications. This doesn't run the verifier. - println!("[parse]"); - run_no_verification("parse", &filter); - - // Test the type-checking of specifications. This doesn't run the verifier. - println!("[typecheck]"); - run_no_verification("typecheck", &filter); - - // Test the verifier. - println!("[verify]"); - run_verification_no_overflow("verify", &filter); - save_verification_cache(); - - // Test the verifier with overflow checks enabled. - println!("[verify_overflow]"); - run_verification_overflow("verify_overflow", &filter); - save_verification_cache(); - - // Test the verifier with test cases that only partially verify due to known open issues. - // The purpose of these tests is two-fold: 1. these tests help prevent potential further - // regressions, because the tests also test code paths not covered by other tests; and - // 2. a failing test without any errors notifies the developer when a proper fix is in - // place. In this case, these test can be moved to the `verify/pass/` or - // `verify_overflow/pass` folders. - println!("[verify_partial]"); - run_verification_overflow("verify_partial", &filter); - save_verification_cache(); - - // Test the verifier with panic checks disabled (i.e. verify only the core proof). - println!("[core_proof]"); - run_verification_core_proof("core_proof", &filter); - save_verification_cache(); - - // Test the verifier with panic checks disabled (i.e. verify only the core proof). - println!("[lifetimes_dump]"); - run_lifetimes_dump("lifetimes_dump", &filter); - save_verification_cache(); -} diff --git a/prusti-tests/tests/harnesses/cargotest.rs b/prusti-tests/tests/harnesses/cargotest.rs new file mode 100644 index 00000000000..4754392ef34 --- /dev/null +++ b/prusti-tests/tests/harnesses/cargotest.rs @@ -0,0 +1,149 @@ +// © 2021, ETH Zurich +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use std::{ + fs, + path::PathBuf, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Mutex, + }, +}; +use ui_test::{default_any_file_filter, run_tests_generic, spanned::Spanned, Args, Config}; + +fn find_cargo_prusti_path() -> PathBuf { + let target_directory = if cfg!(debug_assertions) { + "debug" + } else { + "release" + }; + let executable_name = if cfg!(windows) { + "cargo-prusti.exe" + } else { + "cargo-prusti" + }; + let local_prusti_rustc_path: PathBuf = ["target", target_directory, executable_name] + .iter() + .collect(); + if local_prusti_rustc_path.exists() { + return fs::canonicalize(&local_prusti_rustc_path).unwrap_or_else(|_| { + panic!("Failed to canonicalize the path {local_prusti_rustc_path:?}") + }); + } + let workspace_prusti_rustc_path: PathBuf = ["..", "target", target_directory, executable_name] + .iter() + .collect(); + if workspace_prusti_rustc_path.exists() { + return fs::canonicalize(&workspace_prusti_rustc_path).unwrap_or_else(|_| { + panic!("Failed to canonicalize the path {workspace_prusti_rustc_path:?}") + }); + } + panic!( + "Could not find the {target_directory:?} cargo-prusti binary to be used in tests. \ + It might be that Prusti has not been compiled correctly." + ); +} + +fn run_cargo_tests(root_dir: &str, cargo_flags: &[&str], cargo_env: &[(&str, &str)]) { + static ABORT_CHECK: Mutex>> = Mutex::new(None); + _ = ctrlc::try_set_handler(move || { + if let Some(flag) = &*ABORT_CHECK.lock().unwrap() { + flag.store(true, Ordering::Relaxed); + } + }); + + // This setup for testing with `cargo` is loosely based on `ui_test`'s; + // see https://github.com/oli-obk/ui_test/blob/main/tests/integration.rs + + let mut config = Config::cargo(&root_dir); + + let args = Args::test().unwrap(); + config.with_args(&args); + + *ABORT_CHECK.lock().unwrap() = Some(config.abort_check.clone()); + config.program.program = find_cargo_prusti_path(); + assert_eq!(config.program.args.remove(0), "build"); + config + .program + .args + .extend(cargo_flags.iter().map(|s| s.into())); + config + .program + .envs + .push(("RUSTC_ICE".into(), Some("0".into()))); // suppress rustc-ice*.txt files + config + .program + .envs + .extend(cargo_env.iter().map(|(k, v)| (k.into(), Some(v.into())))); + + config.comment_defaults.base().require_annotations = Some(Spanned::dummy(false)).into(); + + let mut config_pass = config.clone(); + config_pass.comment_defaults.base().exit_status = Some(Spanned::dummy(0)).into(); + + let mut config_fail = config; + config_fail.comment_defaults.base().exit_status = Some(Spanned::dummy(101)).into(); + + let text = ui_test::status_emitter::Text::from(args.format); + run_tests_generic( + vec![config_pass, config_fail], + |path, config| { + // TODO: only these tests are currently enabled. The rest have + // issues that need to be fixed: + // - foreign_mods: "no MIR body for external fn" + // - library_contracts_test: AliasTy problem due to Fn type + // - no_deps: Prusti.toml is not taken from manifest dir + // - overflow_checks: missing span for overflow check + // - prusti_toml: Prusti.toml is not taken from manifest dir + // - prusti_toml_fail: Prusti.toml is not taken from manifest dir + // - test_no_std: needs to be updated for toolchain + // also: `#![no_std]` binaries on Windows are not a thing yet, + // see . + // - veribetrfs: currently broken (?) + if !(path.ends_with("failing_crate_fail/Cargo.toml") + || path.ends_with("failing_stable_toolchain_fail/Cargo.toml") + || path.ends_with("simple_assert_false_fail/Cargo.toml") + || path.ends_with("simple_assert_true/Cargo.toml")) + { + return None; + } + + if !path.ends_with("Cargo.toml") { + return None; + } + let file_is_fail = path + .parent() + .unwrap() + .file_name() + .unwrap() + .to_str() + .unwrap() + .ends_with("fail"); + let config_is_fail = match config + .comment_defaults + .base_immut() + .exit_status + .as_deref() + .unwrap() + { + 0 => false, + 101 => true, + _ => unreachable!(), + }; + if file_is_fail != config_is_fail { + return None; + } + Some(default_any_file_filter(path, config)) + }, + |_, _| {}, + (text,), + ) + .unwrap(); +} + +pub(crate) fn run() { + run_cargo_tests("tests/cargo_verify", &[], &[]); +} diff --git a/prusti-tests/tests/harnesses/compiletest.rs b/prusti-tests/tests/harnesses/compiletest.rs new file mode 100644 index 00000000000..f4f5976e690 --- /dev/null +++ b/prusti-tests/tests/harnesses/compiletest.rs @@ -0,0 +1,232 @@ +// © 2020, ETH Zurich +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#![allow(dead_code)] + +// use log::{error, info}; +use prusti_server::spawn_server_thread; +use std::{ + env, + path::PathBuf, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Mutex, + }, +}; +use ui_test::{run_tests, spanned::Spanned, Config}; + +fn find_prusti_rustc_path() -> PathBuf { + let target_directory = if cfg!(debug_assertions) { + "debug" + } else { + "release" + }; + let executable_name = if cfg!(windows) { + "prusti-rustc.exe" + } else { + "prusti-rustc" + }; + let local_prusti_rustc_path: PathBuf = ["target", target_directory, executable_name] + .iter() + .collect(); + if local_prusti_rustc_path.exists() { + return local_prusti_rustc_path; + } + let workspace_prusti_rustc_path: PathBuf = ["..", "target", target_directory, executable_name] + .iter() + .collect(); + if workspace_prusti_rustc_path.exists() { + return workspace_prusti_rustc_path; + } + panic!( + "Could not find the {target_directory:?} prusti-rustc binary to be used in tests. \ + It might be that Prusti has not been compiled correctly." + ); +} + +fn run_prusti_tests( + group_name: &str, + rustc_flags: &[&str], + rustc_env: &[(&str, &str)], +) -> ui_test::color_eyre::Result<()> { + static ABORT_CHECK: Mutex>> = Mutex::new(None); + _ = ctrlc::try_set_handler(move || { + if let Some(flag) = &*ABORT_CHECK.lock().unwrap() { + flag.store(true, Ordering::Relaxed); + } + }); + + let prusti_config = |path| { + let mut config = Config::rustc(&path); + *ABORT_CHECK.lock().unwrap() = Some(config.abort_check.clone()); + config.program.program = find_prusti_rustc_path(); + config + .program + .args + .extend(rustc_flags.iter().map(|s| s.into())); + config + .program + .envs + .push(("RUSTC_ICE".into(), Some("0".into()))); // suppress rustc-ice*.txt files + config + .program + .envs + .extend(rustc_env.iter().map(|(k, v)| (k.into(), Some(v.into())))); + config + }; + + // UI + { + let config = prusti_config(format!("tests/{group_name}/ui")); + // "--color=never {}" + run_tests(config)?; + } + + // fail + { + let mut config = prusti_config(format!("tests/{group_name}/fail")); + config.comment_defaults.base().normalize_stderr.push(( + ui_test::Match::Regex(regex::bytes::Regex::new(".*\n").unwrap()), + b"".into(), + )); + run_tests(config)?; + } + + // pass + { + let mut config = prusti_config(format!("tests/{group_name}/pass")); + config.comment_defaults.base().exit_status = Spanned::dummy(0).into(); + config.comment_defaults.base().require_annotations = Spanned::dummy(false).into(); + run_tests(config)?; + } + + Ok(()) +} + +fn run_no_verification(group_name: &str) { + run_prusti_tests( + group_name, + &[], + &[ + ("PRUSTI_FULL_COMPILATION", "true"), + ("PRUSTI_NO_VERIFY", "true"), + ("PRUSTI_QUIET", "true"), + ], + ) + .unwrap(); +} + +fn run_verification_no_overflow(group_name: &str) { + run_prusti_tests( + group_name, + &["-Awarnings"], + &[ + ("PRUSTI_FULL_COMPILATION", "true"), + ("PRUSTI_QUIET", "true"), + ("PRUSTI_CHECK_OVERFLOWS", "false"), + ], + ) + .unwrap(); +} + +fn run_verification_overflow(group_name: &str) { + run_prusti_tests( + group_name, + &["-Awarnings"], + &[ + ("PRUSTI_FULL_COMPILATION", "true"), + ("PRUSTI_QUIET", "true"), + ], + ) + .unwrap(); +} + +fn run_verification_core_proof(group_name: &str) { + run_prusti_tests( + group_name, + &["-Awarnings"], + &[ + ("PRUSTI_FULL_COMPILATION", "true"), + ("PRUSTI_QUIET", "true"), + ("PRUSTI_CHECK_PANICS", "false"), + ("PRUSTI_CHECK_OVERFLOWS", "false"), + ], + ) + .unwrap(); +} + +fn run_lifetimes_dump(group_name: &str) { + run_prusti_tests( + group_name, + &[], + &[ + ("PRUSTI_NO_VERIFY", "true"), + ("PRUSTI_DUMP_BORROWCK_INFO", "true"), + ("PRUSTI_QUIET", "true"), + ], + ) + .unwrap(); +} + +pub(crate) fn run() { + // Spawn server process as child (so it stays around until main function terminates) + let server_address = spawn_server_thread(); + env::set_var("PRUSTI_SERVER_ADDRESS", server_address.to_string()); + + // Run (temporary) tests specific to Prusti v2. + println!("[v2]"); + run_verification_no_overflow("v2"); + /* + let save_verification_cache = + || match ureq::post(&format!("http://{server_address}/save")).call() { + Ok(response) => { + info!("Saving verification cache: {}", response.status_text()); + } + Err(ureq::Error::Status(_code, response)) => { + error!("Error while saving verification cache: {response:?}"); + } + Err(err) => error!("Error while saving verification cache: {err}"), + }; + + // Test the parsing of specifications. This doesn't run the verifier. + println!("[parse]"); + run_no_verification("parse"); + + // Test the type-checking of specifications. This doesn't run the verifier. + println!("[typecheck]"); + run_no_verification("typecheck"); + + // Test the verifier. + println!("[verify]"); + run_verification_no_overflow("verify"); + save_verification_cache(); + + // Test the verifier with overflow checks enabled. + println!("[verify_overflow]"); + run_verification_overflow("verify_overflow"); + save_verification_cache(); + + // Test the verifier with test cases that only partially verify due to known open issues. + // The purpose of these tests is two-fold: 1. these tests help prevent potential further + // regressions, because the tests also test code paths not covered by other tests; and + // 2. a failing test without any errors notifies the developer when a proper fix is in + // place. In this case, these test can be moved to the `verify/pass/` or + // `verify_overflow/pass` folders. + println!("[verify_partial]"); + run_verification_overflow("verify_partial"); + save_verification_cache(); + + // Test the verifier with panic checks disabled (i.e. verify only the core proof). + println!("[core_proof]"); + run_verification_core_proof("core_proof"); + save_verification_cache(); + + // Test the verifier with panic checks disabled (i.e. verify only the core proof). + println!("[lifetimes_dump]"); + run_lifetimes_dump("lifetimes_dump"); + save_verification_cache(); + */ +} diff --git a/prusti-tests/tests/harnesses/mod.rs b/prusti-tests/tests/harnesses/mod.rs new file mode 100644 index 00000000000..33e8f29fd9a --- /dev/null +++ b/prusti-tests/tests/harnesses/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod cargotest; +pub(crate) mod compiletest; diff --git a/prusti-tests/tests/main.rs b/prusti-tests/tests/main.rs new file mode 100644 index 00000000000..9bb6045f33b --- /dev/null +++ b/prusti-tests/tests/main.rs @@ -0,0 +1,14 @@ +// © 2020, ETH Zurich +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +#![feature(rustc_private)] + +mod harnesses; + +fn main() { + env_logger::init_from_env(env_logger::Env::new().filter_or("PRUSTI_LOG", "warn")); + harnesses::compiletest::run(); + harnesses::cargotest::run(); +} diff --git a/prusti-tests/tests/parse/fail/wrong_attribute.rs b/prusti-tests/tests/parse/fail/wrong_attribute.rs index 322069491fc..a35d51b32bc 100644 --- a/prusti-tests/tests/parse/fail/wrong_attribute.rs +++ b/prusti-tests/tests/parse/fail/wrong_attribute.rs @@ -1,6 +1,6 @@ use prusti_contracts::*; -#[require(x!=0)] //~ ERROR cannot find attribute +#[require(x!=0)] //~ERROR: cannot find attribute #[ensures(result!=0)] fn wrong(x: i32) -> i32 { x diff --git a/prusti-tests/tests/typecheck/fail/move_to_pure.rs b/prusti-tests/tests/typecheck/fail/move_to_pure.rs index 5f4ea72b2fd..a91f3222268 100644 --- a/prusti-tests/tests/typecheck/fail/move_to_pure.rs +++ b/prusti-tests/tests/typecheck/fail/move_to_pure.rs @@ -25,7 +25,7 @@ fn get_ok_bool(x: Result) -> bool { } } -#[ensures(is_ok(result) && get_ok_bool(result))] //~ ERROR use of moved value +#[ensures(is_ok(result) && get_ok_bool(result))] //~ERROR: use of moved value fn test(i: u32) -> Result { Ok(true) } diff --git a/prusti-tests/tests/typecheck/fail/specification_result_precondition.rs b/prusti-tests/tests/typecheck/fail/specification_result_precondition.rs index 7f7971690f7..d5a7881b899 100644 --- a/prusti-tests/tests/typecheck/fail/specification_result_precondition.rs +++ b/prusti-tests/tests/typecheck/fail/specification_result_precondition.rs @@ -2,7 +2,7 @@ use prusti_contracts::*; -#[requires(result > 0)] //~ ERROR cannot find value `result` +#[requires(result > 0)] //~ERROR: cannot find value `result` pub fn fun() -> i32 { 42 } diff --git a/prusti-tests/tests/typecheck/fail/specification_type_error.rs b/prusti-tests/tests/typecheck/fail/specification_type_error.rs index 75350c9d756..d0dd41d16f2 100644 --- a/prusti-tests/tests/typecheck/fail/specification_type_error.rs +++ b/prusti-tests/tests/typecheck/fail/specification_type_error.rs @@ -2,15 +2,15 @@ use prusti_contracts::*; -#[ensures(x != true)] //~ ERROR mismatched types +#[ensures(x != true)] //~ERROR: mismatched types pub fn first_1(x: i32, y: i32) -> i32 { - if x != true { //~ ERROR mismatched types + if x != true { //~ERROR: mismatched types } x } pub fn test_error_reporting(x: i32) -> bool { - x //~ ERROR mismatched types + x //~ERROR: mismatched types } fn main() {} diff --git a/local-testing/generics/add.rs b/prusti-tests/tests/v2/pass/generics/add.rs similarity index 100% rename from local-testing/generics/add.rs rename to prusti-tests/tests/v2/pass/generics/add.rs diff --git a/local-testing/generics/aurel.rs b/prusti-tests/tests/v2/pass/generics/aurel.rs similarity index 100% rename from local-testing/generics/aurel.rs rename to prusti-tests/tests/v2/pass/generics/aurel.rs diff --git a/local-testing/generics/container.rs b/prusti-tests/tests/v2/pass/generics/container.rs similarity index 100% rename from local-testing/generics/container.rs rename to prusti-tests/tests/v2/pass/generics/container.rs diff --git a/local-testing/generics/impure.rs b/prusti-tests/tests/v2/pass/generics/impure.rs similarity index 100% rename from local-testing/generics/impure.rs rename to prusti-tests/tests/v2/pass/generics/impure.rs diff --git a/local-testing/generics/mono.rs b/prusti-tests/tests/v2/pass/generics/mono.rs similarity index 100% rename from local-testing/generics/mono.rs rename to prusti-tests/tests/v2/pass/generics/mono.rs diff --git a/local-testing/generics/nested.rs b/prusti-tests/tests/v2/pass/generics/nested.rs similarity index 100% rename from local-testing/generics/nested.rs rename to prusti-tests/tests/v2/pass/generics/nested.rs diff --git a/local-testing/generics/nested2.rs b/prusti-tests/tests/v2/pass/generics/nested2.rs similarity index 100% rename from local-testing/generics/nested2.rs rename to prusti-tests/tests/v2/pass/generics/nested2.rs diff --git a/local-testing/generics/nested_simple.rs b/prusti-tests/tests/v2/pass/generics/nested_simple.rs similarity index 100% rename from local-testing/generics/nested_simple.rs rename to prusti-tests/tests/v2/pass/generics/nested_simple.rs diff --git a/local-testing/generics/pair.rs b/prusti-tests/tests/v2/pass/generics/pair.rs similarity index 100% rename from local-testing/generics/pair.rs rename to prusti-tests/tests/v2/pass/generics/pair.rs diff --git a/local-testing/generics/pair2.rs b/prusti-tests/tests/v2/pass/generics/pair2.rs similarity index 100% rename from local-testing/generics/pair2.rs rename to prusti-tests/tests/v2/pass/generics/pair2.rs diff --git a/local-testing/generics/point.rs b/prusti-tests/tests/v2/pass/generics/point.rs similarity index 100% rename from local-testing/generics/point.rs rename to prusti-tests/tests/v2/pass/generics/point.rs diff --git a/local-testing/generics/structs.rs b/prusti-tests/tests/v2/pass/generics/structs.rs similarity index 100% rename from local-testing/generics/structs.rs rename to prusti-tests/tests/v2/pass/generics/structs.rs diff --git a/prusti-tests/tests/verify/fail/arrays-slices/array-mut-loop.rs b/prusti-tests/tests/verify/fail/arrays-slices/array-mut-loop.rs index 74be1d3fc35..b6c34dee69a 100644 --- a/prusti-tests/tests/verify/fail/arrays-slices/array-mut-loop.rs +++ b/prusti-tests/tests/verify/fail/arrays-slices/array-mut-loop.rs @@ -17,5 +17,5 @@ fn looping() { // NOTE: this seems true, but we can't prove it without a proper invariant // also this testcase is to error if we accidentally can verify the state from before the loop // afterwards without a proper invariant - assert!(a[0] == 0); //~ ERROR the asserted expression might not hold + assert!(a[0] == 0); //~ERROR: the asserted expression might not hold } diff --git a/prusti-tests/tests/verify/fail/arrays-slices/complex-array-rhs.rs b/prusti-tests/tests/verify/fail/arrays-slices/complex-array-rhs.rs index 94959933d22..3ba75a3600b 100644 --- a/prusti-tests/tests/verify/fail/arrays-slices/complex-array-rhs.rs +++ b/prusti-tests/tests/verify/fail/arrays-slices/complex-array-rhs.rs @@ -1,4 +1,4 @@ fn main() { let mut a = [0; 3]; - a[0] += 1; //~ ERROR array indexing is not supported in arbitrary operand positions + a[0] += 1; //~ERROR: array indexing is not supported in arbitrary operand positions } diff --git a/prusti-tests/tests/verify/fail/arrays-slices/out-of-bounds.rs b/prusti-tests/tests/verify/fail/arrays-slices/out-of-bounds.rs index e9caabb57bb..ae1b53948bc 100644 --- a/prusti-tests/tests/verify/fail/arrays-slices/out-of-bounds.rs +++ b/prusti-tests/tests/verify/fail/arrays-slices/out-of-bounds.rs @@ -5,9 +5,9 @@ fn main() {} #[pure] fn pure_oob(s: &[i32]) -> i32 { - s[0] //~ ERROR the array or slice index may be out of bounds + s[0] //~ERROR: the array or slice index may be out of bounds } fn third(s: &[i32]) -> i32 { - s[2] //~ ERROR the array or slice index may be out of bounds + s[2] //~ERROR: the array or slice index may be out of bounds } diff --git a/prusti-tests/tests/verify/fail/arrays-slices/wrong-value.rs b/prusti-tests/tests/verify/fail/arrays-slices/wrong-value.rs index a5893faed2c..810f9148fc6 100644 --- a/prusti-tests/tests/verify/fail/arrays-slices/wrong-value.rs +++ b/prusti-tests/tests/verify/fail/arrays-slices/wrong-value.rs @@ -4,5 +4,5 @@ fn main() {} fn all_equal(a: [i32; 2]) { - assert!(a[0] == a[1]); //~ ERROR asserted expression might not hold + assert!(a[0] == a[1]); //~ERROR: asserted expression might not hold } diff --git a/prusti-tests/tests/verify/fail/assert-false/compute-sound.rs b/prusti-tests/tests/verify/fail/assert-false/compute-sound.rs index b7ac576ffd0..d072b457480 100644 --- a/prusti-tests/tests/verify/fail/assert-false/compute-sound.rs +++ b/prusti-tests/tests/verify/fail/assert-false/compute-sound.rs @@ -44,7 +44,7 @@ fn compute(expr: Expr) -> i32 { Expr::Constant(IntBox { val }) => val }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold value } diff --git a/prusti-tests/tests/verify/fail/assert-false/error-position.rs b/prusti-tests/tests/verify/fail/assert-false/error-position.rs index b919befa2c5..0127a72272e 100644 --- a/prusti-tests/tests/verify/fail/assert-false/error-position.rs +++ b/prusti-tests/tests/verify/fail/assert-false/error-position.rs @@ -1,46 +1,46 @@ use prusti_contracts::*; -#[ensures(false)] //~ ERROR postcondition might not hold +#[ensures(false)] //~ERROR: postcondition might not hold fn foo1(x: bool) {} -#[ensures(false && false)] //~ ERROR postcondition might not hold +#[ensures(false && false)] //~ERROR: postcondition might not hold fn foo2(x: bool) {} -#[ensures(!true)] //~ ERROR postcondition might not hold +#[ensures(!true)] //~ERROR: postcondition might not hold fn foo3(x: bool) {} -#[ensures(!(true || x))] //~ ERROR postcondition might not hold +#[ensures(!(true || x))] //~ERROR: postcondition might not hold fn foo4(x: bool) {} -#[ensures(!(false || true))] //~ ERROR postcondition might not hold +#[ensures(!(false || true))] //~ERROR: postcondition might not hold fn foo5(x: bool) {} -#[ensures(!(x || !false))] //~ ERROR postcondition might not hold +#[ensures(!(x || !false))] //~ERROR: postcondition might not hold fn foo6(x: bool) {} -#[ensures(!(x || !x))] //~ ERROR postcondition might not hold +#[ensures(!(x || !x))] //~ERROR: postcondition might not hold fn foo7(x: bool) {} -#[ensures(true ==> false)] //~ ERROR postcondition might not hold +#[ensures(true ==> false)] //~ERROR: postcondition might not hold fn foo8(x: bool) {} -#[ensures(x || true ==> !(x || !x))] //~ ERROR postcondition might not hold +#[ensures(x || true ==> !(x || !x))] //~ERROR: postcondition might not hold fn foo9(x: bool) {} #[ensures(x == x)] -#[ensures(false)] //~ ERROR postcondition might not hold +#[ensures(false)] //~ERROR: postcondition might not hold fn foo10(x: bool) {} -#[ensures(false)] //~ ERROR postcondition might not hold +#[ensures(false)] //~ERROR: postcondition might not hold #[ensures(x == x)] fn foo11(x: bool) {} #[ensures(x == x)] -#[ensures(!true)] //~ ERROR postcondition might not hold +#[ensures(!true)] //~ERROR: postcondition might not hold #[ensures(x == x)] fn foo12(x: bool) {} -#[ensures(false)] //~ ERROR postcondition might not hold +#[ensures(false)] //~ERROR: postcondition might not hold #[ensures(result == x)] pub fn foo13(x: u32) -> u32 { x diff --git a/prusti-tests/tests/verify/fail/assert-false/int-option-sound.rs b/prusti-tests/tests/verify/fail/assert-false/int-option-sound.rs index aaeec99cd6a..04e59a9469f 100644 --- a/prusti-tests/tests/verify/fail/assert-false/int-option-sound.rs +++ b/prusti-tests/tests/verify/fail/assert-false/int-option-sound.rs @@ -13,7 +13,7 @@ fn foo(x: IntOption) -> i32 { IntOption::Some(y) => y, IntOption::None => 456 }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } diff --git a/prusti-tests/tests/verify/fail/assert-false/list-sound.rs b/prusti-tests/tests/verify/fail/assert-false/list-sound.rs index 3bc19a46cc5..b0367c63fd2 100644 --- a/prusti-tests/tests/verify/fail/assert-false/list-sound.rs +++ b/prusti-tests/tests/verify/fail/assert-false/list-sound.rs @@ -17,7 +17,7 @@ fn head(list: List) -> Option { List::Nil => None, List::Const { val, box next } => Some(val), }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } @@ -26,7 +26,7 @@ fn tail(list: List) -> Option { List::Nil => None, List::Const { val, box next } => Some(next), }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } @@ -35,7 +35,7 @@ fn length(list: List) -> u32 { List::Nil => 0, List::Const { val, box next } => 1 + length(next), }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } @@ -47,12 +47,12 @@ fn last_value(list: List) -> Option { Some(last) => Some(last), } }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } fn empty_list(val: i32) -> List { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold List::Nil } @@ -61,7 +61,7 @@ fn singleton_list(val: i32) -> List { val, next: box List::Nil }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } @@ -70,7 +70,7 @@ fn prepend(val: i32, list: List) -> List { val, next: box list }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } @@ -85,7 +85,7 @@ fn append(new_val: i32, list: List) -> List { next: box append(new_val, next) }, }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } @@ -94,7 +94,7 @@ fn revert(list: List) -> List { List::Nil => List::Nil, List::Const { val, box next } => append(val, revert(next)) }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } diff --git a/prusti-tests/tests/verify/fail/assert-false/tree-sound.rs b/prusti-tests/tests/verify/fail/assert-false/tree-sound.rs index ee2de5ebb22..9ff3f6ed738 100644 --- a/prusti-tests/tests/verify/fail/assert-false/tree-sound.rs +++ b/prusti-tests/tests/verify/fail/assert-false/tree-sound.rs @@ -14,7 +14,7 @@ fn take_left(tree: Tree) -> Option { Some(box left) => Some(left), None => None, }; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold ret } diff --git a/prusti-tests/tests/verify/fail/closures/basic.rs b/prusti-tests/tests/verify/fail/closures/basic.rs index 583b17307e3..12fc53ee722 100644 --- a/prusti-tests/tests/verify/fail/closures/basic.rs +++ b/prusti-tests/tests/verify/fail/closures/basic.rs @@ -8,5 +8,5 @@ fn main() { #[ensures(true)] |i: i32| -> i32 { i } ); - f(0); //~ ERROR precondition might not hold + f(0); //~ERROR: precondition might not hold } diff --git a/prusti-tests/tests/verify/fail/crates/wrong-081-mio.rs b/prusti-tests/tests/verify/fail/crates/wrong-081-mio.rs index 58a35cdb0ce..afc1155fa06 100644 --- a/prusti-tests/tests/verify/fail/crates/wrong-081-mio.rs +++ b/prusti-tests/tests/verify/fail/crates/wrong-081-mio.rs @@ -12,13 +12,13 @@ pub struct Event { pub struct UnixReady(Ready); -#[ensures(false)] //~ ERROR postcondition +#[ensures(false)] //~ERROR: postcondition pub fn kind_mut(event: &mut Event) -> &mut Ready { &mut event.kind } impl UnixReady { - #[ensures(false)] //~ ERROR postcondition + #[ensures(false)] //~ERROR: postcondition fn deref_mut(&mut self) -> &mut Ready { &mut self.0 } diff --git a/prusti-tests/tests/verify/fail/crates/wrong-122-same-file.rs b/prusti-tests/tests/verify/fail/crates/wrong-122-same-file.rs index 09fb65658b8..99c4633e665 100644 --- a/prusti-tests/tests/verify/fail/crates/wrong-122-same-file.rs +++ b/prusti-tests/tests/verify/fail/crates/wrong-122-same-file.rs @@ -34,7 +34,7 @@ impl UnixImplHandle { pub struct Handle(UnixImplHandle); impl Handle { - #[ensures(false)] //~ ERROR postcondition + #[ensures(false)] //~ERROR: postcondition pub fn as_file_mut(&mut self) -> &mut StdFsFile { self.0.as_file_mut() } diff --git a/prusti-tests/tests/verify/fail/demos/account-error-1.rs b/prusti-tests/tests/verify/fail/demos/account-error-1.rs index 7c5758df405..83665961b36 100644 --- a/prusti-tests/tests/verify/fail/demos/account-error-1.rs +++ b/prusti-tests/tests/verify/fail/demos/account-error-1.rs @@ -24,7 +24,7 @@ impl Account { } #[requires(amount <= self.balance())] - #[ensures(self.balance() == old(self.balance()) + amount)] //~ ERROR postcondition might not hold + #[ensures(self.balance() == old(self.balance()) + amount)] //~ERROR: postcondition might not hold fn transfer(&mut self, other: &mut Account, amount: u32) { self.withdraw(amount); other.deposit(amount); diff --git a/prusti-tests/tests/verify/fail/demos/account-error-2.rs b/prusti-tests/tests/verify/fail/demos/account-error-2.rs index 7db5b7085da..889855b144f 100644 --- a/prusti-tests/tests/verify/fail/demos/account-error-2.rs +++ b/prusti-tests/tests/verify/fail/demos/account-error-2.rs @@ -25,7 +25,7 @@ impl Account { #[ensures(self.balance() == old(self.balance()) - amount)] fn transfer(&mut self, other: &mut Account, amount: u32) { - self.withdraw(amount); //~ ERROR precondition might not hold + self.withdraw(amount); //~ERROR: precondition might not hold other.deposit(amount); } } diff --git a/prusti-tests/tests/verify/fail/demos/append-sorted-error-3.rs b/prusti-tests/tests/verify/fail/demos/append-sorted-error-3.rs index 62a8ae6e32d..67cab3c65f5 100644 --- a/prusti-tests/tests/verify/fail/demos/append-sorted-error-3.rs +++ b/prusti-tests/tests/verify/fail/demos/append-sorted-error-3.rs @@ -43,7 +43,7 @@ impl List { #[requires(a.sorted() && a.get(a.len() - 1) <= v)] #[ensures(a.len() == old(a.len()) + 1)] // #[ensures(a.get(0) == old(a.get(0)))] // missing -#[ensures(a.sorted())] //~ ERROR postcondition might not hold +#[ensures(a.sorted())] //~ERROR: postcondition might not hold fn append(a: &mut List, v: i32) { if let Some(box ref mut tail) = a.next { append(tail, v); diff --git a/prusti-tests/tests/verify/fail/equality/pure-post-1.rs b/prusti-tests/tests/verify/fail/equality/pure-post-1.rs index 891d72736dc..e3b32264582 100644 --- a/prusti-tests/tests/verify/fail/equality/pure-post-1.rs +++ b/prusti-tests/tests/verify/fail/equality/pure-post-1.rs @@ -8,7 +8,7 @@ struct A { #[pure] #[requires(_x == _y)] #[ensures(old(_x) == old(_y))] -fn get_value(_x: A, _y: A) -> A { //~ ERROR return type of pure function does not implement Copy +fn get_value(_x: A, _y: A) -> A { //~ERROR: return type of pure function does not implement Copy _x } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/assert-on-expiry.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/assert-on-expiry.rs index fc7a3c3bcd8..dfb8c7388b5 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/assert-on-expiry.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/assert-on-expiry.rs @@ -30,7 +30,7 @@ impl Example { #[ensures(*result == old(self.m3))] #[assert_on_expiry( true, - self.valid() //~ ERROR pledge in the postcondition might not hold + self.valid() //~ERROR: pledge in the postcondition might not hold )] fn m3_mut_fail(&mut self) -> &mut u32 { &mut self.m3 @@ -47,7 +47,7 @@ fn test(arg: &mut Example) { #[requires(arg.valid())] #[ensures(arg.valid())] fn test_fail(arg: &mut Example) { - let m3 = arg.m3_mut(); //~ ERROR obligation might not hold on borrow expiry + let m3 = arg.m3_mut(); //~ERROR: obligation might not hold on borrow expiry *m3 += 5; // mistake } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-1.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-1.rs index 11c982c3cff..ba0a3885d34 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-1.rs @@ -7,7 +7,7 @@ fn must_answer(location: &mut i32) -> &mut i32 { fn test() { let mut x = 0; - let y = must_answer(&mut x); //~ ERROR obligation might not hold on borrow expiry + let y = must_answer(&mut x); //~ERROR: obligation might not hold on borrow expiry //*y = 42; } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-1.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-1.rs index 6aca87478df..ed088c7a77c 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-1.rs @@ -14,7 +14,7 @@ impl Nonsense { //#[requires(self.valid())] #[ensures(*result == old(self.m3))] - #[assert_on_expiry(*result % 3 == 0, self.valid())] //~ ERROR might not hold + #[assert_on_expiry(*result % 3 == 0, self.valid())] //~ERROR: might not hold fn m3_mut(&mut self) -> &mut u32 { &mut self.m3 } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-2.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-2.rs index 78f80a336a0..93b17345caa 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-2.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-2.rs @@ -26,7 +26,7 @@ impl Nonsense { #[requires(arg.valid())] #[ensures(arg.valid())] fn test(arg: &mut Nonsense) { - let m3 = arg.m3_mut(); //~ ERROR obligation might not hold on borrow expiry + let m3 = arg.m3_mut(); //~ERROR: obligation might not hold on borrow expiry *m3 += 3; } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-3.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-3.rs index 0af13de014c..5522ca77273 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-3.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-3.rs @@ -14,7 +14,7 @@ impl Nonsense { #[requires(self.valid())] #[ensures(*result == old(self.m3))] - #[assert_on_expiry(true, self.valid())] //~ ERROR might not hold + #[assert_on_expiry(true, self.valid())] //~ERROR: might not hold fn m3_mut(&mut self) -> &mut u32 { &mut self.m3 } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-4.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-4.rs index f244df89da8..e613da8c1de 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-4.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-4.rs @@ -24,7 +24,7 @@ impl Nonsense { } #[requires(arg.valid())] -#[ensures(arg.valid())] //~ ERROR postcondition might not hold +#[ensures(arg.valid())] //~ERROR: postcondition might not hold fn test(arg: &mut Nonsense) { let m3 = arg.m3_mut(); *m3 += 3; diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-5.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-5.rs index a15cdf9e42a..387833d39b4 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-5.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-5.rs @@ -14,7 +14,7 @@ impl Nonsense { #[requires(self.valid())] #[ensures(*result == old(self.m3))] - #[assert_on_expiry(*result % 3 == 0, self.valid())] //~ ERROR might not hold + #[assert_on_expiry(*result % 3 == 0, self.valid())] //~ERROR: might not hold fn m3_mut(&mut self) -> &mut u32 { &mut self.m5 // mistake } diff --git a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-6.rs b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-6.rs index e37648aeb8f..bc2d3bc115f 100644 --- a/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-6.rs +++ b/prusti-tests/tests/verify/fail/erdinm/erdinm/pledges-basic-2-6.rs @@ -26,7 +26,7 @@ impl Nonsense { #[requires(arg.valid())] #[ensures(arg.valid())] fn test(arg: &mut Nonsense) { - let m3 = arg.m3_mut(); //~ ERROR obligation might not hold on borrow expiry + let m3 = arg.m3_mut(); //~ERROR: obligation might not hold on borrow expiry *m3 += 5; // mistake } diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-1.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-1.rs index a9ac05fca68..8e8634af8b2 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-1.rs @@ -7,7 +7,7 @@ struct Pair { //#[requires(pair.a == 42)] fn test2(pair: &mut Pair) { - assert!(pair.a == 42); //~ ERROR the asserted expression might not hold + assert!(pair.a == 42); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-2.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-2.rs index eb1cd522f66..bbd868b4947 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-2.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-2.rs @@ -20,7 +20,7 @@ fn test(u: &mut U) { read(u); assert!(valid(u)); write(u); - assert!(valid(u)); //~ ERROR the asserted expression might not hold + assert!(valid(u)); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-1.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-1.rs index 66e5e4e59da..a2d509694b2 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-1.rs @@ -17,7 +17,7 @@ fn test1(arg: &mut Number) { #[ensures(arg.i >= 8000)] fn test2(arg: &mut Number) { // using specs with a *different* typaram - test1(arg); //~ ERROR precondition might not hold + test1(arg); //~ERROR: precondition might not hold } #[requires(arg.i >= 9000)] diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-2.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-2.rs index 0c7433b374b..7ee0dbc2eda 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-2.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-2.rs @@ -8,7 +8,7 @@ struct Number { } #[requires(arg.i >= 9000)] -#[ensures(arg.i >= 8001)] //~ ERROR postcondition might not hold +#[ensures(arg.i >= 8001)] //~ERROR: postcondition might not hold fn test1(arg: &mut Number) { arg.i -= 1000; } diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-3.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-3.rs index bcce72c5856..46aad4e7f54 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-3.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-3.rs @@ -24,7 +24,7 @@ fn test2(arg: &mut Number) { #[ensures(arg.i >= 8000)] fn test3(arg: &mut Number) { // using specs with a typaram in a non-generic function - test2(arg); //~ ERROR precondition might not hold + test2(arg); //~ERROR: precondition might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-4.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-4.rs index d259c876afc..2a4c0fc8f37 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-4.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-4.rs @@ -14,7 +14,7 @@ fn test1(arg: &mut Number) { } #[requires(arg.i >= 9000)] -#[ensures(arg.i >= 8001)] //~ ERROR postcondition might not hold +#[ensures(arg.i >= 8001)] //~ERROR: postcondition might not hold fn test2(arg: &mut Number) { // using specs with a *different* typaram test1(arg); diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-5.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-5.rs index 08db939e39a..93cf328484d 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-5.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-5.rs @@ -24,7 +24,7 @@ fn test2(arg: &mut Number) { #[ensures(arg.i >= 8000)] fn test3(arg: &mut Number) { // using specs with a typaram in a non-generic function - test2(arg); //~ ERROR precondition might not hold + test2(arg); //~ERROR: precondition might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-6.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-6.rs index 316cd4646a6..037aa948a8e 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-6.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-3-6.rs @@ -21,7 +21,7 @@ fn test2(arg: &mut Number) { } #[requires(arg.i >= 9000)] -#[ensures(arg.i >= 8001)] //~ ERROR postcondition might not hold +#[ensures(arg.i >= 8001)] //~ERROR: postcondition might not hold fn test3(arg: &mut Number) { // using specs with a typaram in a non-generic function test2(arg); diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-1.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-1.rs index fd0deb184c1..b5ea16df98e 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-1.rs @@ -18,13 +18,13 @@ fn test1(arg: &mut Number) { } #[requires(arg.i >= 9000)] -#[ensures(arg.i >= 8000)] //~ ERROR postcondition might not hold +#[ensures(arg.i >= 8000)] //~ERROR: postcondition might not hold fn test2a(arg: &mut Number) { test1(arg); } #[requires(arg.i >= 8000)] -#[ensures(arg.i >= 7000)] //~ ERROR postcondition might not hold +#[ensures(arg.i >= 7000)] //~ERROR: postcondition might not hold fn test2b(arg: &mut Number) { test1(arg); } diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-2.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-2.rs index 779d3666705..ab77ea793ea 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-2.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-4-2.rs @@ -33,7 +33,7 @@ fn test2b(arg: &mut Number) { #[ensures(arg.i >= 7000)] fn test3(arg: &mut Number) { test2a(arg); - test2b(arg); //~ ERROR precondition might not hold + test2b(arg); //~ERROR: precondition might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-1.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-1.rs index 6e10d5523c6..fe3860186db 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-1.rs @@ -26,7 +26,7 @@ fn test3(arg: &mut Number, Number, Number< assert!(arg.b.b == 5000); assert!(arg.c.b == 6000); test2(arg); - assert!(arg.a.b == 2000); //~ ERROR the asserted expression might not hold + assert!(arg.a.b == 2000); //~ERROR: the asserted expression might not hold assert!(arg.b.b == 4000); //assert!(arg.c.b == 6000); } diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-2.rs b/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-2.rs index 9e0b01e5359..adf3e57e70e 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-2.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-basic-5-2.rs @@ -28,7 +28,7 @@ fn test3(arg: &mut Number, Number, Number< test2(arg); //assert!(arg.a.b == 2000); assert!(arg.b.b == 4000); - assert!(arg.c.b == 6000); //~ ERROR the asserted expression might not hold + assert!(arg.c.b == 6000); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-combined.rs b/prusti-tests/tests/verify/fail/erdinm/generics-combined.rs index 51eda4880ea..8e6d23d9d7e 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-combined.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-combined.rs @@ -41,7 +41,7 @@ fn test2(arg: &mut Number, Number, Number< assert!(arg.b.b == 5000); assert!(arg.c.b == 6000); decr2(arg); - assert!(arg.a.b == 2000); //~ ERROR the asserted expression might not hold + assert!(arg.a.b == 2000); //~ERROR: the asserted expression might not hold assert!(arg.b.b == 4000); //assert!(arg.c.b == 6000); } @@ -58,7 +58,7 @@ fn test3(arg: &mut Number, Number, Numbe decr2(arg); //assert!(arg.a.b == 2000); assert!(arg.b.b == 4000); - assert!(arg.c.b == 6000); //~ ERROR the asserted expression might not hold + assert!(arg.c.b == 6000); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/generics-special-1.rs b/prusti-tests/tests/verify/fail/erdinm/generics-special-1.rs index 237188f1195..4a07516a394 100644 --- a/prusti-tests/tests/verify/fail/erdinm/generics-special-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/generics-special-1.rs @@ -20,7 +20,7 @@ fn test(u: &mut U) { read(u); assert!(valid(u)); write(u); - assert!(valid(u)); //~ ERROR the asserted expression might not hold + assert!(valid(u)); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/invariants-basic-1.rs b/prusti-tests/tests/verify/fail/erdinm/invariants-basic-1.rs index 303cf3b0cf6..4bbe57b92f3 100644 --- a/prusti-tests/tests/verify/fail/erdinm/invariants-basic-1.rs +++ b/prusti-tests/tests/verify/fail/erdinm/invariants-basic-1.rs @@ -9,7 +9,7 @@ struct Percentage { impl Percentage { fn incr(&mut self) { - assert!(self.value <= 100); //~ ERROR the asserted expression might not hold + assert!(self.value <= 100); //~ERROR: the asserted expression might not hold if self.value < 100 { self.value += 1; } diff --git a/prusti-tests/tests/verify/fail/erdinm/invariants-basic-3.rs b/prusti-tests/tests/verify/fail/erdinm/invariants-basic-3.rs index 8d4ebdd32ee..de43019a23b 100644 --- a/prusti-tests/tests/verify/fail/erdinm/invariants-basic-3.rs +++ b/prusti-tests/tests/verify/fail/erdinm/invariants-basic-3.rs @@ -19,7 +19,7 @@ impl Percentage { fn test(x: u8) { let mut perc = Percentage { value: x }; perc.incr(); - assert!(perc.value <= 100); //~ ERROR the asserted expression might not hold + assert!(perc.value <= 100); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/invariants-basic-5.rs b/prusti-tests/tests/verify/fail/erdinm/invariants-basic-5.rs index 3c2bf5ea3ea..c3ce04cd2db 100644 --- a/prusti-tests/tests/verify/fail/erdinm/invariants-basic-5.rs +++ b/prusti-tests/tests/verify/fail/erdinm/invariants-basic-5.rs @@ -19,7 +19,7 @@ impl Percentage { #[requires(x <= 100)] fn test(x: u8) { let perc = Percentage::new(x); - assert!(perc.value <= 100); //~ ERROR the asserted expression might not hold + assert!(perc.value <= 100); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-post.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-post.rs index dcb49ebbecc..57d787395b1 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-post.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-post.rs @@ -9,7 +9,7 @@ trait Percentage { fn test(t: &T) { let p = t.get(); - assert!(p <= 99); //~ ERROR the asserted expression might not hold + assert!(p <= 99); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-pre.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-pre.rs index 4819f518f81..aabe2aeeb46 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-pre.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-call-pre.rs @@ -8,7 +8,7 @@ trait Percentage { } fn test(t: &mut T) { - t.set(123); //~ ERROR precondition might not hold + t.set(123); //~ERROR: precondition might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-post.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-post.rs index 08b54a89aac..99105f7e88c 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-post.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-post.rs @@ -1,7 +1,7 @@ use prusti_contracts::*; trait Percentage { - #[ensures(result <= 100)] //~ ERROR postcondition might not hold + #[ensures(result <= 100)] //~ERROR: postcondition might not hold fn get(&self) -> u8 { 101 } diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-pre.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-pre.rs index d00c71fb06d..f5ad281bbe7 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-pre.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-defi-pre.rs @@ -3,7 +3,7 @@ use prusti_contracts::*; trait Percentage { #[requires(arg <= 100)] fn set(&mut self, arg: u8) { - assert!(arg <= 99); //~ ERROR the asserted expression might not hold + assert!(arg <= 99); //~ERROR: the asserted expression might not hold } } diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-post.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-post.rs index 580f1c05ecb..9279c11fc9a 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-post.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-post.rs @@ -1,7 +1,7 @@ use prusti_contracts::*; trait Percentage { - #[ensures(result <= 100)] //~ ERROR postcondition might not hold + #[ensures(result <= 100)] //~ERROR: postcondition might not hold fn get(&self) -> u8 { 100 } diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-pre.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-pre.rs index da2e0b458f3..e5f762cd862 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-pre.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-prov-impl-pre.rs @@ -11,7 +11,7 @@ struct Effective {} impl Percentage for Effective { fn set(&mut self, arg: u8) { - assert!(arg <= 99); //~ ERROR the asserted expression might not hold + assert!(arg <= 99); //~ERROR: the asserted expression might not hold } } diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-post.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-post.rs index f62f01fab47..f647733eaf3 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-post.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-post.rs @@ -7,7 +7,7 @@ trait Percentage { fn test(t: &T) { let p = t.get(); - assert!(p <= 99); //~ ERROR the asserted expression might not hold + assert!(p <= 99); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-pre.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-pre.rs index fbab399986e..d482e5de948 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-pre.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-call-pre.rs @@ -6,7 +6,7 @@ trait Percentage { } fn test(t: &mut T) { - t.set(101); //~ ERROR precondition might not hold + t.set(101); //~ERROR: precondition might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-post.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-post.rs index 43d679947c8..ce9775982d4 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-post.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-post.rs @@ -1,7 +1,7 @@ use prusti_contracts::*; trait Percentage { - #[ensures(result <= 100)] //~ ERROR postcondition might not hold + #[ensures(result <= 100)] //~ERROR: postcondition might not hold fn get(&self) -> u8; } diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-pre.rs b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-pre.rs index 2b3574e5b04..f56b3a98d98 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-pre.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-basic-norm-reqd-impl-pre.rs @@ -9,7 +9,7 @@ struct Effective {} impl Percentage for Effective { fn set(&mut self, arg: u8) { - assert!(arg <= 99); //~ ERROR the asserted expression might not hold + assert!(arg <= 99); //~ERROR: the asserted expression might not hold } } diff --git a/prusti-tests/tests/verify/fail/erdinm/traits-combined.rs b/prusti-tests/tests/verify/fail/erdinm/traits-combined.rs index 53c8be08f8e..c4bd840328f 100644 --- a/prusti-tests/tests/verify/fail/erdinm/traits-combined.rs +++ b/prusti-tests/tests/verify/fail/erdinm/traits-combined.rs @@ -1,7 +1,7 @@ use prusti_contracts::*; trait Percentage { - #[ensures(result <= 100)] //~ ERROR postcondition might not hold + #[ensures(result <= 100)] //~ERROR: postcondition might not hold fn get(&self) -> u8; #[requires(arg <= 100)] @@ -15,7 +15,7 @@ impl Percentage for Fail { 101 } fn set(&mut self, arg: u8) { - assert!(arg <= 99); //~ ERROR the asserted expression might not hold + assert!(arg <= 99); //~ERROR: the asserted expression might not hold } } @@ -32,7 +32,7 @@ impl Percentage for Pass { fn test_get_fail(t: &T) { let p = t.get(); - assert!(p <= 99); //~ ERROR the asserted expression might not hold + assert!(p <= 99); //~ERROR: the asserted expression might not hold } fn test_get_pass(t: &T) { @@ -41,7 +41,7 @@ fn test_get_pass(t: &T) { } fn test_set_fail(t: &mut T) { - t.set(101); //~ ERROR precondition might not hold + t.set(101); //~ERROR: precondition might not hold } fn test_set_pass(t: &mut T) { diff --git a/prusti-tests/tests/verify/fail/fold-unfold/balance.rs b/prusti-tests/tests/verify/fail/fold-unfold/balance.rs index 85b4499d669..956b12f1031 100644 --- a/prusti-tests/tests/verify/fail/fold-unfold/balance.rs +++ b/prusti-tests/tests/verify/fail/fold-unfold/balance.rs @@ -17,7 +17,7 @@ impl Account { } #[ensures(self.bal == old(self.bal) - amount)] - fn withdraw(&mut self, amount: u32) { //~ ERROR implicit type invariants might not hold at the end of the method. + fn withdraw(&mut self, amount: u32) { //~ERROR: implicit type invariants might not hold at the end of the method. self.bal = self.bal - amount; } diff --git a/prusti-tests/tests/verify/fail/fold-unfold/negative-enum.rs b/prusti-tests/tests/verify/fail/fold-unfold/negative-enum.rs index ebcc7db885d..bb6f103782d 100644 --- a/prusti-tests/tests/verify/fail/fold-unfold/negative-enum.rs +++ b/prusti-tests/tests/verify/fail/fold-unfold/negative-enum.rs @@ -5,7 +5,7 @@ pub enum E3 { V2(u32), } -pub fn test3(e: &mut E3) -> &mut u32 { //~ ERROR implicit type invariants might not hold at the end of the method. +pub fn test3(e: &mut E3) -> &mut u32 { //~ERROR: implicit type invariants might not hold at the end of the method. match e { E3::V1(ref mut b) => { *b -= 5; diff --git a/prusti-tests/tests/verify/fail/fold-unfold/negative.rs b/prusti-tests/tests/verify/fail/fold-unfold/negative.rs index 62c91dbdeea..c36b6027fe0 100644 --- a/prusti-tests/tests/verify/fail/fold-unfold/negative.rs +++ b/prusti-tests/tests/verify/fail/fold-unfold/negative.rs @@ -4,11 +4,11 @@ struct U { f: u32, } -fn test1(a: &mut U, value: u32) { //~ ERROR implicit type invariants might not hold at the end of the method. +fn test1(a: &mut U, value: u32) { //~ERROR: implicit type invariants might not hold at the end of the method. a.f -= value; } -fn test2(a: &mut U) -> &mut u32 { //~ ERROR implicit type invariants might not hold at the end of the method. +fn test2(a: &mut U) -> &mut u32 { //~ERROR: implicit type invariants might not hold at the end of the method. a.f -= 5; &mut a.f } @@ -19,7 +19,7 @@ fn test3(a: u32) { fn test4(a: u32) { let b = a - 5; - test3(b); //~ ERROR implicit type invariant expected by the function call might not hold. + test3(b); //~ERROR: implicit type invariant expected by the function call might not hold. } diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-25-wrong.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-25-wrong.rs index d2f9a2c50e9..3f229b5b88d 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-25-wrong.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-25-wrong.rs @@ -6,7 +6,7 @@ struct T { f: i32, } -#[ensures(old(x.f) == result)] //~ ERROR postcondition +#[ensures(old(x.f) == result)] //~ERROR: postcondition fn extract(x: &mut T) -> i32 { // move x let y = x; diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-72.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-72.rs index 96afc0baf96..c50a9ea7b16 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-72.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-72.rs @@ -43,7 +43,7 @@ impl VecWrapperI32 { } fn test0(x: VecWrapperI32) { - let z = x.lookup(0); //~ ERROR precondition of pure function call might not hold + let z = x.lookup(0); //~ERROR: precondition of pure function call might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-73.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-73.rs index 8f3645b73a7..1037223e9c6 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-73.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-73.rs @@ -47,14 +47,14 @@ impl VecWrapperusize { // binary search using recursion pub fn binary_search_rec(arr: VecWrapperusize, target: usize) -> Option { let len = arr.len(); - return binary_search_help(arr, 0, len - 1, target); //~ ERROR type invariant expected by the function call might not hold. + return binary_search_help(arr, 0, len - 1, target); //~ERROR: type invariant expected by the function call might not hold. } // Here the precondition is missing fn binary_search_help(arr: VecWrapperusize, left: usize, right: usize, target: usize) -> Option { if left <= right { let mid = (left + right) / 2; - if arr.lookup(mid) < target { //~ ERROR precondition of pure function call might not hold + if arr.lookup(mid) < target { //~ERROR: precondition of pure function call might not hold return binary_search_help(arr, mid + 1, right, target); } else if arr.lookup(mid) > target { return binary_search_help(arr, left, mid - 1, target); diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-74.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-74.rs index 1457732c7d4..64fe81e5b52 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-74.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-74.rs @@ -56,7 +56,7 @@ pub fn binary_search_iter(arr: VecWrapperusize, target: usize) -> Option let mut condition = left <= right && !done; while condition { let mid = (left + right) / 2; - if arr.lookup(mid) < target { //~ ERROR precondition of pure function call might not hold. + if arr.lookup(mid) < target { //~ERROR: precondition of pure function call might not hold. left = mid + 1; } else if arr.lookup(mid) > target { right = mid - 1; diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-ops.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-ops.rs index 18bc9d48072..f27f9f75e2c 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-ops.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-ops.rs @@ -4,7 +4,7 @@ use prusti_contracts::*; #[pure] #[requires(n > 0)] #[ensures(true)] -#[ensures(true && (result == 5 || false))] //~ ERROR postcondition +#[ensures(true && (result == 5 || false))] //~ERROR: postcondition #[ensures(true)] fn magic(n: i32) -> i32 { n diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-pure-fn.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-pure-fn.rs index 6957552e584..6573a800a84 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-pure-fn.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-81-pure-fn.rs @@ -9,7 +9,7 @@ fn bad(n: i32) -> bool { #[pure] #[requires(n > 0)] #[ensures(true)] -#[ensures(bad(n))] //~ ERROR postcondition +#[ensures(bad(n))] //~ERROR: postcondition #[ensures(true)] fn magic(n: i32) -> i32 { n diff --git a/prusti-tests/tests/verify/fail/gitlab-issues/issue-81.rs b/prusti-tests/tests/verify/fail/gitlab-issues/issue-81.rs index abd176c71f4..d1c9d585345 100644 --- a/prusti-tests/tests/verify/fail/gitlab-issues/issue-81.rs +++ b/prusti-tests/tests/verify/fail/gitlab-issues/issue-81.rs @@ -2,7 +2,7 @@ use prusti_contracts::*; #[pure] #[requires(n > 0)] -#[ensures(result == 5)] //~ ERROR postcondition +#[ensures(result == 5)] //~ERROR: postcondition fn magic(n: i32) -> i32 { n } diff --git a/prusti-tests/tests/verify/fail/incorrect/const_argument.rs b/prusti-tests/tests/verify/fail/incorrect/const_argument.rs index 75f1964b75a..1bae47ba0c9 100644 --- a/prusti-tests/tests/verify/fail/incorrect/const_argument.rs +++ b/prusti-tests/tests/verify/fail/incorrect/const_argument.rs @@ -6,7 +6,7 @@ fn test(x: i32) { let mut i = 100; while i > 0 { if i == 10 { - foo(123); //~ ERROR please use a local variable as argument + foo(123); //~ERROR: please use a local variable as argument } i -= 1; } diff --git a/prusti-tests/tests/verify/fail/incorrect/invalid_loop_condition.rs b/prusti-tests/tests/verify/fail/incorrect/invalid_loop_condition.rs index 567e4ad2583..5b36ce3ede4 100644 --- a/prusti-tests/tests/verify/fail/incorrect/invalid_loop_condition.rs +++ b/prusti-tests/tests/verify/fail/incorrect/invalid_loop_condition.rs @@ -9,12 +9,12 @@ fn test_break() { body_invariant!(true); continue } - assert!(i == 10); //~ ERROR might not hold + assert!(i == 10); //~ERROR: might not hold } fn test_continue() { let mut i = 0; - 'label: while { //~ ERROR loop invariant cannot be in a conditional branch + 'label: while { //~ERROR: loop invariant cannot be in a conditional branch if i < 10 { i += 1; continue 'label; diff --git a/prusti-tests/tests/verify/fail/incorrect/old_expr_type.rs b/prusti-tests/tests/verify/fail/incorrect/old_expr_type.rs index 66f0cc96e88..0ee186c760a 100644 --- a/prusti-tests/tests/verify/fail/incorrect/old_expr_type.rs +++ b/prusti-tests/tests/verify/fail/incorrect/old_expr_type.rs @@ -10,7 +10,7 @@ impl Foo { unimplemented!() } - #[ensures(self.len() == old(self).len() - 1)] //~ ERROR postcondition might not hold. + #[ensures(self.len() == old(self).len() - 1)] //~ERROR: postcondition might not hold. pub fn foo(&mut self) -> i32 { 42 } diff --git a/prusti-tests/tests/verify/fail/incorrect/panic.rs b/prusti-tests/tests/verify/fail/incorrect/panic.rs index 662de1f7285..4fd1f5c71a4 100644 --- a/prusti-tests/tests/verify/fail/incorrect/panic.rs +++ b/prusti-tests/tests/verify/fail/incorrect/panic.rs @@ -7,7 +7,7 @@ fn prepare_client(client_state: &AnyClientState) -> Result { AnyClientState::Tendermint(cs) => cs, _ => return Err(0) }; - panic!() //~ ERROR panic!(..) statement might be reachable + panic!() //~ERROR: panic!(..) statement might be reachable } fn main() { diff --git a/prusti-tests/tests/verify/fail/issues/issue-1033-2.rs b/prusti-tests/tests/verify/fail/issues/issue-1033-2.rs index d3ed07bad60..838db1d6c2d 100644 --- a/prusti-tests/tests/verify/fail/issues/issue-1033-2.rs +++ b/prusti-tests/tests/verify/fail/issues/issue-1033-2.rs @@ -7,7 +7,7 @@ pub struct Foo(T); impl Foo { #[pure] #[ensures(result == (left == right))] - fn eq(left: T, right: T) -> bool { //~ ERROR pure function parameters must be Copy + fn eq(left: T, right: T) -> bool { //~ERROR: pure function parameters must be Copy left == right } } diff --git a/prusti-tests/tests/verify/fail/issues/issue-1033-3.rs b/prusti-tests/tests/verify/fail/issues/issue-1033-3.rs index 27056c3351b..190b3d4df37 100644 --- a/prusti-tests/tests/verify/fail/issues/issue-1033-3.rs +++ b/prusti-tests/tests/verify/fail/issues/issue-1033-3.rs @@ -13,5 +13,5 @@ impl Foo { #[pure] pub fn test() { - assert!(Foo::eq(0, 0)); //~ ERROR use of impure function + assert!(Foo::eq(0, 0)); //~ERROR: use of impure function } diff --git a/prusti-tests/tests/verify/fail/issues/issue-1200-1.rs b/prusti-tests/tests/verify/fail/issues/issue-1200-1.rs index ae5cdd07d95..d64f019e7e8 100644 --- a/prusti-tests/tests/verify/fail/issues/issue-1200-1.rs +++ b/prusti-tests/tests/verify/fail/issues/issue-1200-1.rs @@ -26,7 +26,7 @@ fn fast_fft_len( std::cmp::Ordering::Equal => return product, std::cmp::Ordering::Greater => { best = min(best, product); - if product % multi_factor2 != 0 { //~ ERROR attempt to calculate the remainder with a divisor of zero + if product % multi_factor2 != 0 { //~ERROR: attempt to calculate the remainder with a divisor of zero return best; } product /= multi_factor2; diff --git a/prusti-tests/tests/verify/fail/issues/issue-167.rs b/prusti-tests/tests/verify/fail/issues/issue-167.rs index c6843e6e072..3d96095d921 100644 --- a/prusti-tests/tests/verify/fail/issues/issue-167.rs +++ b/prusti-tests/tests/verify/fail/issues/issue-167.rs @@ -6,7 +6,7 @@ use prusti_contracts::*; #[requires(n > 0)] #[requires(true)] #[ensures(true)] -#[ensures(result == 5)] //~ ERROR postcondition might not hold. +#[ensures(result == 5)] //~ERROR: postcondition might not hold. #[ensures(true)] fn test(n: i32) -> i32 { n diff --git a/prusti-tests/tests/verify/fail/issues/issue-447-1.rs b/prusti-tests/tests/verify/fail/issues/issue-447-1.rs index 191ecb14912..f3c3ef92f0d 100644 --- a/prusti-tests/tests/verify/fail/issues/issue-447-1.rs +++ b/prusti-tests/tests/verify/fail/issues/issue-447-1.rs @@ -36,7 +36,7 @@ fn index_slice(slice: &[T], ix: usize) -> &T { } fn push_all(vec: &mut Vec, slice: &[T]) { - for i in 0..slice_len(slice) { //~ ERROR iterators are not fully supported + for i in 0..slice_len(slice) { //~ERROR: iterators are not fully supported push(vec, index_slice(slice, i).clone()) } } diff --git a/prusti-tests/tests/verify/fail/issues/issue-737-1.rs b/prusti-tests/tests/verify/fail/issues/issue-737-1.rs index 6518e6ea028..8c0555a502e 100644 --- a/prusti-tests/tests/verify/fail/issues/issue-737-1.rs +++ b/prusti-tests/tests/verify/fail/issues/issue-737-1.rs @@ -19,7 +19,7 @@ impl Stack { #[requires(0 < self.len())] fn top_node(&mut self) -> &mut Node { match self.head { - None => { unreachable!() }, //~ ERROR unreachable!(..) statement might be reachable + None => { unreachable!() }, //~ERROR: unreachable!(..) statement might be reachable Some(ref mut node) => node, } } diff --git a/prusti-tests/tests/verify/fail/issues/issue960-1.rs b/prusti-tests/tests/verify/fail/issues/issue960-1.rs index aa8f1f70253..e439949e2d0 100644 --- a/prusti-tests/tests/verify/fail/issues/issue960-1.rs +++ b/prusti-tests/tests/verify/fail/issues/issue960-1.rs @@ -3,22 +3,22 @@ use prusti_contracts::*; #[requires(end <= slice.len())] fn foo(slice: &[i32], start: usize, end: usize) { - let subslice = &slice[start..end]; //~ ERROR the range end may be smaller than the start when slicing + let subslice = &slice[start..end]; //~ERROR: the range end may be smaller than the start when slicing } #[requires(start <= end)] fn bar(slice: &[i32], start: usize, end: usize) { - let subslice = &slice[start..end]; //~ ERROR the range end value may be out of bounds when slicing + let subslice = &slice[start..end]; //~ERROR: the range end value may be out of bounds when slicing } #[requires(end <= slice.len())] fn foo_mut(slice: &mut [i32], start: usize, end: usize) { - let subslice = &mut slice[start..end]; //~ ERROR mutably slicing is not fully supported yet + let subslice = &mut slice[start..end]; //~ERROR: mutably slicing is not fully supported yet } #[requires(start <= end)] fn bar_mut(slice: &mut [i32], start: usize, end: usize) { - let subslice = &mut slice[start..end]; //~ ERROR mutably slicing is not fully supported yet + let subslice = &mut slice[start..end]; //~ERROR: mutably slicing is not fully supported yet } fn main() {} \ No newline at end of file diff --git a/prusti-tests/tests/verify/fail/loops/continue_before_invariant.rs b/prusti-tests/tests/verify/fail/loops/continue_before_invariant.rs index 48811e73121..d9cf9550117 100644 --- a/prusti-tests/tests/verify/fail/loops/continue_before_invariant.rs +++ b/prusti-tests/tests/verify/fail/loops/continue_before_invariant.rs @@ -7,7 +7,7 @@ fn random(i: u32) -> bool { fn continue_before_invariant() { let mut i = 0; - 'myloop: while { //~ ERROR the loop invariant cannot be in a conditional branch of the loop + 'myloop: while { //~ERROR: the loop invariant cannot be in a conditional branch of the loop if random(i + 2) { continue 'myloop; } diff --git a/prusti-tests/tests/verify/fail/loops/havock_loop_vars.rs b/prusti-tests/tests/verify/fail/loops/havock_loop_vars.rs index 1ffdf54cf89..5eaaf89a0c2 100644 --- a/prusti-tests/tests/verify/fail/loops/havock_loop_vars.rs +++ b/prusti-tests/tests/verify/fail/loops/havock_loop_vars.rs @@ -18,7 +18,7 @@ fn test() { } else { z = Some(x); } - assert!(false); //~ ERROR might not hold + assert!(false); //~ERROR: might not hold } } diff --git a/prusti-tests/tests/verify/fail/loops/incorrect_invariant.rs b/prusti-tests/tests/verify/fail/loops/incorrect_invariant.rs index 9a724915124..3ea6cc9e145 100644 --- a/prusti-tests/tests/verify/fail/loops/incorrect_invariant.rs +++ b/prusti-tests/tests/verify/fail/loops/incorrect_invariant.rs @@ -3,7 +3,7 @@ use prusti_contracts::*; pub fn simple_loop() { let mut x = 0; while x < 100 { - body_invariant!(x == 42); //~ ERROR loop invariant might not hold + body_invariant!(x == 42); //~ERROR: loop invariant might not hold x += 1; } } diff --git a/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity.rs b/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity.rs index 45ee2e99766..f8ad849af2b 100644 --- a/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity.rs +++ b/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity.rs @@ -6,7 +6,7 @@ struct T { val: i32 } -#[ensures(false)] //~ ERROR postcondition +#[ensures(false)] //~ERROR: postcondition fn identity(x: &mut T) -> &mut T { x } diff --git a/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity2.rs b/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity2.rs index 4a9400b2114..89dd7d3dd7b 100644 --- a/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity2.rs +++ b/prusti-tests/tests/verify/fail/magic-wands/wrong-wand-identity2.rs @@ -25,12 +25,12 @@ fn identity3(x: &mut T, v: i32) -> &mut i32 { &mut x.val } -#[after_expiry(x.val == 5)] //~ ERROR pledge +#[after_expiry(x.val == 5)] //~ERROR: pledge fn identity4(x: &mut T) -> &mut T { x } -#[after_expiry(x.val != before_expiry(result.val))] //~ ERROR pledge +#[after_expiry(x.val != before_expiry(result.val))] //~ERROR: pledge fn identity5(x: &mut T) -> &mut T { x } diff --git a/prusti-tests/tests/verify/fail/moves/basic.rs b/prusti-tests/tests/verify/fail/moves/basic.rs index e72bb61b9f4..bddd9fd164d 100644 --- a/prusti-tests/tests/verify/fail/moves/basic.rs +++ b/prusti-tests/tests/verify/fail/moves/basic.rs @@ -9,7 +9,7 @@ pub fn test4() -> S2 { f: 8, }; let y = x; - assert!(y.f == 9); //~ ERROR the asserted expression might not hold + assert!(y.f == 9); //~ERROR: the asserted expression might not hold y } diff --git a/prusti-tests/tests/verify/fail/nll-rfc/message.rs b/prusti-tests/tests/verify/fail/nll-rfc/message.rs index da100e4e8b9..3d9ffa72210 100644 --- a/prusti-tests/tests/verify/fail/nll-rfc/message.rs +++ b/prusti-tests/tests/verify/fail/nll-rfc/message.rs @@ -130,7 +130,7 @@ fn router(me: &StringWrapper, rx: Receiver, tx: Sender) { if recipient.equals(me) { // The program does not handle the case in which `send()` fails, so the // `unwrap()` might panic. - tx.send(message).unwrap(); //~ ERROR precondition might not hold. + tx.send(message).unwrap(); //~ERROR: precondition might not hold. } else { process(data); } diff --git a/prusti-tests/tests/verify/fail/nll-rfc/wrong-case1.rs b/prusti-tests/tests/verify/fail/nll-rfc/wrong-case1.rs index fb8c9ec89dc..28e104f29a7 100644 --- a/prusti-tests/tests/verify/fail/nll-rfc/wrong-case1.rs +++ b/prusti-tests/tests/verify/fail/nll-rfc/wrong-case1.rs @@ -62,11 +62,11 @@ fn capitalize(vec: &mut VecWrapperI32) { vec.store(i, value); i += 1; not_finished = i < vec.len(); - unreachable!(); //~ ERROR might be reachable + unreachable!(); //~ERROR: might be reachable } } -#[ensures(false)] //~ ERROR postcondition +#[ensures(false)] //~ERROR: postcondition fn bar() { let mut data = VecWrapperI32::new(); data.push(1); diff --git a/prusti-tests/tests/verify/fail/no-annotations/assert-bool.rs b/prusti-tests/tests/verify/fail/no-annotations/assert-bool.rs index 37f0effe7f5..ce9b0f91a30 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/assert-bool.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/assert-bool.rs @@ -1,5 +1,5 @@ fn foo(x: bool) { - assert!(x); //~ ERROR the asserted expression might not hold + assert!(x); //~ERROR: the asserted expression might not hold } fn main() {} diff --git a/prusti-tests/tests/verify/fail/no-annotations/assert-false.rs b/prusti-tests/tests/verify/fail/no-annotations/assert-false.rs index bedad1aa6c3..b777e7c5365 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/assert-false.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/assert-false.rs @@ -1,3 +1,3 @@ fn main() { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } diff --git a/prusti-tests/tests/verify/fail/no-annotations/assert-from-macro.rs b/prusti-tests/tests/verify/fail/no-annotations/assert-from-macro.rs index 18f16af6ddb..e6814cb6015 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/assert-from-macro.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/assert-from-macro.rs @@ -1,6 +1,6 @@ macro_rules! my_assert { ( $( $args:expr ),* ) => { - assert!( $( $args ),* ) //~ ERROR the asserted expression might not hold + assert!( $( $args ),* ) //~ERROR: the asserted expression might not hold }; } diff --git a/prusti-tests/tests/verify/fail/no-annotations/div-by-zero.rs b/prusti-tests/tests/verify/fail/no-annotations/div-by-zero.rs index 478de430481..d2481bb58e6 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/div-by-zero.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/div-by-zero.rs @@ -4,7 +4,7 @@ fn div_rem(x: usize, d: usize) -> (usize, usize) { ( - x / d, //~ ERROR assertion might fail with "attempt to divide by zero" + x / d, //~ERROR: assertion might fail with "attempt to divide by zero" x % d ) } diff --git a/prusti-tests/tests/verify/fail/no-annotations/divide-by-zero.rs b/prusti-tests/tests/verify/fail/no-annotations/divide-by-zero.rs index e07b8573673..3c846903d40 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/divide-by-zero.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/divide-by-zero.rs @@ -1,4 +1,4 @@ fn main() { let y = 0; - let z = 1 / y; //~ ERROR assertion might fail with "attempt to divide by zero" + let z = 1 / y; //~ERROR: assertion might fail with "attempt to divide by zero" } diff --git a/prusti-tests/tests/verify/fail/no-annotations/external-call-fail.rs b/prusti-tests/tests/verify/fail/no-annotations/external-call-fail.rs index bd400140e7e..0522270d443 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/external-call-fail.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/external-call-fail.rs @@ -1,6 +1,6 @@ fn test(x: i32) { let is_pos = x.is_positive(); - assert!(is_pos); //~ ERROR the asserted expression might not hold + assert!(is_pos); //~ERROR: the asserted expression might not hold } fn main(){} diff --git a/prusti-tests/tests/verify/fail/no-annotations/multiple-errors.rs b/prusti-tests/tests/verify/fail/no-annotations/multiple-errors.rs index ca406835c12..8060db14d2b 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/multiple-errors.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/multiple-errors.rs @@ -1,11 +1,11 @@ fn foo() { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn bar() { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn main() { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } diff --git a/prusti-tests/tests/verify/fail/no-annotations/never-type.rs b/prusti-tests/tests/verify/fail/no-annotations/never-type.rs index 7ccd91f0f89..07de84139dc 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/never-type.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/never-type.rs @@ -1,7 +1,7 @@ #![feature(never_type)] fn diverging() -> ! { - panic!(); //~ ERROR panic!(..) statement might be reachable + panic!(); //~ERROR: panic!(..) statement might be reachable } fn main() {} diff --git a/prusti-tests/tests/verify/fail/no-annotations/panic-in-impl.rs b/prusti-tests/tests/verify/fail/no-annotations/panic-in-impl.rs index 1aeeb01fa05..8579bdd3f91 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/panic-in-impl.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/panic-in-impl.rs @@ -2,7 +2,7 @@ struct T(u32, i32); impl Default for T { fn default() -> Self { - panic!("Error message") //~ ERROR panic!(..) statement might be reachable + panic!("Error message") //~ERROR: panic!(..) statement might be reachable } } diff --git a/prusti-tests/tests/verify/fail/no-annotations/panic-reason.rs b/prusti-tests/tests/verify/fail/no-annotations/panic-reason.rs index 9b7a5273389..ecea80b4e1d 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/panic-reason.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/panic-reason.rs @@ -1,36 +1,36 @@ fn test_panic(x: bool) { - panic!(); //~ ERROR panic!(..) statement might be reachable + panic!(); //~ERROR: panic!(..) statement might be reachable } fn test_assert(x: bool) { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn test_assert_msg(x: bool) { // FIXME: see mir_encoder encode_panic_cause - assert!(false, "msg"); //~ ERROR panic!(..) statement might be reachable + assert!(false, "msg"); //~ERROR: panic!(..) statement might be reachable } fn test_debug_assert(x: bool) { - debug_assert!(false); //~ ERROR the asserted expression might not hold + debug_assert!(false); //~ERROR: the asserted expression might not hold } fn test_debug_assert_msg(x: bool) { - debug_assert!(false, "msg"); //~ ERROR the asserted expression might not hold + debug_assert!(false, "msg"); //~ERROR: the asserted expression might not hold } fn test_unreachable(x: bool) { - unreachable!(); //~ ERROR unreachable!(..) statement might be reachable + unreachable!(); //~ERROR: unreachable!(..) statement might be reachable } fn test_unimplemented(x: bool) { - unimplemented!(); //~ ERROR unimplemented!(..) statement might be reachable + unimplemented!(); //~ERROR: unimplemented!(..) statement might be reachable } macro_rules! inner_panic { () => { { - panic!(); //~ ERROR panic!(..) statement might be reachable + panic!(); //~ERROR: panic!(..) statement might be reachable } }; } @@ -42,7 +42,7 @@ fn test_inner_panic(x: bool) { macro_rules! inner_panic_msg { () => { { - panic!("msg"); //~ ERROR panic!(..) statement might be reachable + panic!("msg"); //~ERROR: panic!(..) statement might be reachable } }; } @@ -54,7 +54,7 @@ fn test_inner_panic_msg(x: bool) { macro_rules! inner_assert { () => { { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } }; } @@ -67,7 +67,7 @@ macro_rules! inner_assert_msg { () => { { // FIXME: see mir_encoder encode_panic_cause - assert!(false, "msg"); //~ ERROR panic!(..) statement might be reachable + assert!(false, "msg"); //~ERROR: panic!(..) statement might be reachable } }; } @@ -79,7 +79,7 @@ fn test_inner_assert_msg(x: bool) { macro_rules! inner_debug_assert { () => { { - debug_assert!(false); //~ ERROR the asserted expression might not hold + debug_assert!(false); //~ERROR: the asserted expression might not hold } }; } @@ -91,7 +91,7 @@ fn test_inner_debug_assert(x: bool) { macro_rules! inner_debug_assert_msg { () => { { - debug_assert!(false, "msg"); //~ ERROR the asserted expression might not hold + debug_assert!(false, "msg"); //~ERROR: the asserted expression might not hold } }; } @@ -103,7 +103,7 @@ fn test_inner_debug_assert_msg(x: bool) { macro_rules! inner_unreachable { () => { { - unreachable!(); //~ ERROR unreachable!(..) statement might be reachable + unreachable!(); //~ERROR: unreachable!(..) statement might be reachable } }; } @@ -115,7 +115,7 @@ fn test_inner_unreachable(x: bool) { macro_rules! inner_unimplemented { () => { { - unimplemented!(); //~ ERROR unimplemented!(..) statement might be reachable + unimplemented!(); //~ERROR: unimplemented!(..) statement might be reachable } }; } diff --git a/prusti-tests/tests/verify/fail/no-annotations/panic.rs b/prusti-tests/tests/verify/fail/no-annotations/panic.rs index 9df5de846e2..05fb2e5b4c1 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/panic.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/panic.rs @@ -1,3 +1,3 @@ fn main() { - panic!(); //~ ERROR panic!(..) statement might be reachable + panic!(); //~ERROR: panic!(..) statement might be reachable } diff --git a/prusti-tests/tests/verify/fail/no-annotations/predicate-old-expr.rs b/prusti-tests/tests/verify/fail/no-annotations/predicate-old-expr.rs index 7427a1bb7c9..603f7c5d424 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/predicate-old-expr.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/predicate-old-expr.rs @@ -15,7 +15,7 @@ fn lookup(head: &List, index: usize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => unreachable!() //~ ERROR unreachable!(..) statement might be reachable + None => unreachable!() //~ERROR: unreachable!(..) statement might be reachable } } } diff --git a/prusti-tests/tests/verify/fail/no-annotations/redefine-assert.rs b/prusti-tests/tests/verify/fail/no-annotations/redefine-assert.rs index f193dc4f235..b480e40e029 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/redefine-assert.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/redefine-assert.rs @@ -1,6 +1,6 @@ macro_rules! assert { ( $( $args:expr ),* ) => { - panic!( $( $args ),* ) //~ ERROR panic!(..) statement might be reachable + panic!( $( $args ),* ) //~ERROR: panic!(..) statement might be reachable }; } diff --git a/prusti-tests/tests/verify/fail/no-annotations/signed-discriminant.rs b/prusti-tests/tests/verify/fail/no-annotations/signed-discriminant.rs index dfae19b0d48..6b79e9b26df 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/signed-discriminant.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/signed-discriminant.rs @@ -32,7 +32,7 @@ fn test_err() { let x = SignedEnum::A; if let SignedEnum::A = x { - panic!() //~ ERROR panic!(..) statement might be reachable + panic!() //~ERROR: panic!(..) statement might be reachable } else { // Nothing } diff --git a/prusti-tests/tests/verify/fail/no-annotations/unimplemented.rs b/prusti-tests/tests/verify/fail/no-annotations/unimplemented.rs index 3b9544be32a..5388a84d1a2 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/unimplemented.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/unimplemented.rs @@ -1,5 +1,5 @@ fn foo(x: i32) -> i32 { - unimplemented!(); //~ ERROR unimplemented!(..) statement might be reachable + unimplemented!(); //~ERROR: unimplemented!(..) statement might be reachable } fn main(){} diff --git a/prusti-tests/tests/verify/fail/no-annotations/unreachable-branch.rs b/prusti-tests/tests/verify/fail/no-annotations/unreachable-branch.rs index fa1598bff8c..4979b97a514 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/unreachable-branch.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/unreachable-branch.rs @@ -15,7 +15,7 @@ fn compute(expr: Expr) -> i32 { let value = match simplified { Expr::Sum(_, _) => { - unreachable!() //~ ERROR unreachable!(..) statement might be reachable + unreachable!() //~ERROR: unreachable!(..) statement might be reachable }, Expr::Constant(IntBox { val }) => val }; diff --git a/prusti-tests/tests/verify/fail/no-annotations/unreachable.rs b/prusti-tests/tests/verify/fail/no-annotations/unreachable.rs index f64a400bb38..400b3006a72 100644 --- a/prusti-tests/tests/verify/fail/no-annotations/unreachable.rs +++ b/prusti-tests/tests/verify/fail/no-annotations/unreachable.rs @@ -1,5 +1,5 @@ fn foo(x: i32) -> i32 { - unreachable!(); //~ ERROR unreachable!(..) statement might be reachable + unreachable!(); //~ERROR: unreachable!(..) statement might be reachable } fn main(){} diff --git a/prusti-tests/tests/verify/fail/predicates/doesnt-hold.rs b/prusti-tests/tests/verify/fail/predicates/doesnt-hold.rs index 91ecc3b3bad..3d5b28d1cd8 100644 --- a/prusti-tests/tests/verify/fail/predicates/doesnt-hold.rs +++ b/prusti-tests/tests/verify/fail/predicates/doesnt-hold.rs @@ -10,5 +10,5 @@ predicate! { fn precond_fail() {} fn main() { - precond_fail(); //~ ERROR precondition might not hold + precond_fail(); //~ERROR: precondition might not hold } diff --git a/prusti-tests/tests/verify/fail/pure-fn/array.rs b/prusti-tests/tests/verify/fail/pure-fn/array.rs index a5dcc9eefcd..b809775c64b 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/array.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/array.rs @@ -8,5 +8,5 @@ fn convert(x: [u32; 2]) -> (u32, u32) { fn main() { let a = [123, 456]; let b = (123, 123); - assert!(convert(a) == b); //~ ERROR the asserted expression might not hold + assert!(convert(a) == b); //~ERROR: the asserted expression might not hold } diff --git a/prusti-tests/tests/verify/fail/pure-fn/fail-pc.rs b/prusti-tests/tests/verify/fail/pure-fn/fail-pc.rs index a50768be411..2ba27f1e807 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/fail-pc.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/fail-pc.rs @@ -1,7 +1,7 @@ use prusti_contracts::*; #[pure] -#[ensures(result == n*(n+1)/2)] //~ ERROR postcondition +#[ensures(result == n*(n+1)/2)] //~ERROR: postcondition fn sum1(n: i32) -> i32 { if n <= 0 { 0 } else { sum1(n-1)+n } } @@ -14,5 +14,5 @@ fn sum2(n: i32) -> i32 { } #[requires(sum1(-1) == 0)] -#[requires(sum2(-1) == 0)] //~ ERROR precondition +#[requires(sum2(-1) == 0)] //~ERROR: precondition fn main() {} diff --git a/prusti-tests/tests/verify/fail/pure-fn/integer_bounds.rs b/prusti-tests/tests/verify/fail/pure-fn/integer_bounds.rs index 739d9ca9d5a..1e0ec6cf7f4 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/integer_bounds.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/integer_bounds.rs @@ -34,7 +34,7 @@ fn u32_foo_call_4() { fn u32_foo_call_5() { } -#[ensures(u32_foo() <= 4294967295)] //~ ERROR postcondition +#[ensures(u32_foo() <= 4294967295)] //~ERROR: postcondition fn u32_foo_call_6() { } diff --git a/prusti-tests/tests/verify/fail/pure-fn/panic-in-fn.rs b/prusti-tests/tests/verify/fail/pure-fn/panic-in-fn.rs index 4e75d5a8349..15e320c58cb 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/panic-in-fn.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/panic-in-fn.rs @@ -23,7 +23,7 @@ fn lookup(head: &List, index: isize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => diverging() //~ ERROR diverging + None => diverging() //~ERROR: diverging } } } @@ -35,7 +35,7 @@ fn lookup2(head: &List, index: isize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => panic!() //~ ERROR panic!(..) statement might be reachable + None => panic!() //~ERROR: panic!(..) statement might be reachable } } } @@ -47,7 +47,7 @@ fn lookup3(head: &List, index: isize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => unreachable!() //~ ERROR unreachable!(..) statement might be reachable + None => unreachable!() //~ERROR: unreachable!(..) statement might be reachable } } } @@ -59,7 +59,7 @@ fn lookup4(head: &List, index: isize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => unimplemented!() //~ ERROR unimplemented!(..) statement might be reachable + None => unimplemented!() //~ERROR: unimplemented!(..) statement might be reachable } } } @@ -72,7 +72,7 @@ fn lookup5(head: &List, index: isize) -> u32 { match head.next { Some(box ref tail) => lookup(tail, index - 1), None => { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold 0 } } diff --git a/prusti-tests/tests/verify/fail/pure-fn/wrong-quantifiers.rs b/prusti-tests/tests/verify/fail/pure-fn/wrong-quantifiers.rs index 433b6356142..d9311beb99d 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/wrong-quantifiers.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/wrong-quantifiers.rs @@ -18,7 +18,7 @@ fn lookup(head: &List, index: usize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => unreachable!() //~ ERROR unreachable!(..) statement might be reachable + None => unreachable!() //~ERROR: unreachable!(..) statement might be reachable } } } @@ -32,7 +32,7 @@ fn len(head: &List) -> usize { } #[ensures(len(&result) == old(len(&tail)) + 1)] -#[ensures(lookup(&result, 0) == old(x))] //~ ERROR postcondition might not hold +#[ensures(lookup(&result, 0) == old(x))] //~ERROR: postcondition might not hold #[ensures(if len(&result) >= 2 { old(lookup(&tail, 0)) == lookup(&result, 1) } else { true })] #[ensures(forall(|i: usize| (0 <= i && i < old(len(&tail))) ==> old(lookup(&tail, i)) == lookup(&result, i)))] #[ensures(forall(|i: usize| (0 <= i && i < old(len(&tail))) ==> i * 2 == i + i))] diff --git a/prusti-tests/tests/verify/fail/pure-fn/wrong-ref-mut-arg.rs b/prusti-tests/tests/verify/fail/pure-fn/wrong-ref-mut-arg.rs index 6b63d443351..8927b04e209 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/wrong-ref-mut-arg.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/wrong-ref-mut-arg.rs @@ -20,7 +20,7 @@ fn lookup(head: &List, index: usize) -> u32 { } else { match head.next { Some(box ref tail) => lookup(tail, index - 1), - None => unreachable!() //~ ERROR might be reachable + None => unreachable!() //~ERROR: might be reachable } } } @@ -43,7 +43,7 @@ fn prepend_list(x: u32, tail: List, check: bool) -> List { next: Some(Box::new(tail)), }; if check { - assert!(lookup(&result, 0) == 123); //~ ERROR the asserted expression might not hold + assert!(lookup(&result, 0) == 123); //~ERROR: the asserted expression might not hold diverging() } result diff --git a/prusti-tests/tests/verify/fail/pure-fn/wrong-simple-fn.rs b/prusti-tests/tests/verify/fail/pure-fn/wrong-simple-fn.rs index fe469df31b2..e5f3ae7947c 100644 --- a/prusti-tests/tests/verify/fail/pure-fn/wrong-simple-fn.rs +++ b/prusti-tests/tests/verify/fail/pure-fn/wrong-simple-fn.rs @@ -12,7 +12,7 @@ fn magic(n: i32) -> i32 { } } -#[ensures(magic(-1) == 123)] //~ ERROR +#[ensures(magic(-1) == 123)] //~ERROR: postcondition might not hold #[ensures(magic(0) == -1)] #[ensures(magic(1) == 1)] #[ensures(magic(2) == 42)] diff --git a/prusti-tests/tests/verify/fail/quantifiers/triggers.rs b/prusti-tests/tests/verify/fail/quantifiers/triggers.rs index 55341543e67..05b7e18f9c7 100644 --- a/prusti-tests/tests/verify/fail/quantifiers/triggers.rs +++ b/prusti-tests/tests/verify/fail/quantifiers/triggers.rs @@ -20,7 +20,7 @@ pub fn test1() { pub fn test2() { // We unroll the function at most once, hence this fails. - assert!(fib(4) == 5); //~ ERROR the asserted expression might not hold + assert!(fib(4) == 5); //~ERROR: the asserted expression might not hold } #[pure] diff --git a/prusti-tests/tests/verify/fail/shared-borrows/basic.rs b/prusti-tests/tests/verify/fail/shared-borrows/basic.rs index dccd98ac23f..039d854c424 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/basic.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/basic.rs @@ -3,12 +3,12 @@ use prusti_contracts::*; pub fn test1() { let a = 4; let _x = &a; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test2(a: u32) { let _x = &a; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test3() { @@ -19,7 +19,7 @@ pub fn test3() { let _c = *y; a = 6; let _b = a; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } /* @@ -45,7 +45,7 @@ pub fn test4(a: u32) { let y = &a; let _b = *x; let _c = *y; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test5() { @@ -56,7 +56,7 @@ pub fn test5() { let _c = *y; a = 6; let _b = a; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/shared-borrows/conditionals.rs b/prusti-tests/tests/verify/fail/shared-borrows/conditionals.rs index ff778ca890d..7dd9ca6e03c 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/conditionals.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/conditionals.rs @@ -10,14 +10,14 @@ pub fn test1(a: u32, b: u32, cond: bool) { x = &b; } borrow(x); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test1_1(a: u32, b: u32, cond: bool) { let x; if cond { x = &a; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } else { x = &b; } @@ -30,7 +30,7 @@ pub fn test1_2(a: u32, b: u32, cond: bool) { x = &a; } else { x = &b; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } borrow(x); } @@ -43,7 +43,7 @@ pub fn test2(a: u32, b: u32, cond: bool) { x = &b; } let _y = x; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test3(cond: bool) { @@ -64,7 +64,7 @@ pub fn test3(cond: bool) { a = 7; b = 8; assert!(a == 7 && b == 8); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test3_1(cond: bool) { @@ -79,7 +79,7 @@ pub fn test3_1(cond: bool) { borrow(x); if cond { assert!(*x == 5); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } else { assert!(*x == 6); } @@ -102,7 +102,7 @@ pub fn test3_2(cond: bool) { assert!(*x == 5); } else { assert!(*x == 6); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } a = 7; b = 8; diff --git a/prusti-tests/tests/verify/fail/shared-borrows/functions.rs b/prusti-tests/tests/verify/fail/shared-borrows/functions.rs index 5cd30e905fd..78649bfbfe9 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/functions.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/functions.rs @@ -8,24 +8,24 @@ pub fn test1() { let a = 5; let x = &a; borrow(x); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test2(x: &u32) { let a = *x; let y = &a; borrow(y); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test3(x: &u32) { borrow(x); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test4(x: &mut u32) { borrow(x); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test5() { @@ -34,18 +34,18 @@ pub fn test5() { let x = &a; let y = &b; borrow2(x, y); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[requires(*x == 5)] #[ensures(*x == 5)] pub fn test6(x: &u32) { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[ensures(*x == old(*x))] pub fn test7(x: &u32) { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test8() { @@ -57,7 +57,7 @@ pub fn test8() { borrow2(x, &a); assert!(a == 5); assert!(*x == 5); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/shared-borrows/loops.rs b/prusti-tests/tests/verify/fail/shared-borrows/loops.rs index ad06d441d7f..cfdedcc3955 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/loops.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/loops.rs @@ -10,7 +10,7 @@ pub fn test1(n: &mut i32) { i += 1; cond = i < *n; } - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[ensures(*n == old(*n))] @@ -22,7 +22,7 @@ pub fn test2(n: &mut i32) { borrow(n); cond = i < *n; } - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[ensures(*n == old(*n))] @@ -33,7 +33,7 @@ pub fn test2_1(n: &mut i32) { i += 1; borrow(n); cond = i < *n; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } } @@ -46,7 +46,7 @@ pub fn test3(n: &i32) { borrow(n); cond = i < *n; } - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[ensures(*n == old(*n))] @@ -57,7 +57,7 @@ pub fn test3_1(n: &i32) { i += 1; borrow(n); cond = i < *n; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } } @@ -67,7 +67,7 @@ pub fn test4(n: &i32) { let mut i = 0; let mut cond = i < *n; while cond { - body_invariant!(i == 0); //~ ERROR loop invariant might not hold after a loop iteration + body_invariant!(i == 0); //~ERROR: loop invariant might not hold after a loop iteration i += 1; borrow(n); cond = i < *n; @@ -82,7 +82,7 @@ pub fn test4_1(n: &i32) { while cond { body_invariant!(cond == (i < *n)); body_invariant!(0 <= i && i <= *n); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold i += 1; borrow(n); cond = i < *n; @@ -103,7 +103,7 @@ pub fn test4_2(n: &i32) { borrow(n); cond = i < *n; } - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/shared-borrows/mut-borrows.rs b/prusti-tests/tests/verify/fail/shared-borrows/mut-borrows.rs index 01073849c8b..21bae38b794 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/mut-borrows.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/mut-borrows.rs @@ -5,19 +5,19 @@ fn borrow(_x: &u32) {} pub fn test1(mut a: u32) { let x = &mut a; let _y = &*x; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test2(x: &mut u32) { let _y = &*x; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } pub fn test3(x: &mut u32) { let y = &*x; assert!(*y == *x); let _a = *y; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[ensures(*x == 5)] @@ -27,7 +27,7 @@ pub fn test4(x: &mut u32) { let a = *y; assert!(a == *y && a == *x); *x = 5; - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/shared-borrows/reborrowing.rs b/prusti-tests/tests/verify/fail/shared-borrows/reborrowing.rs index 93ef86c7c06..8325e4cf8eb 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/reborrowing.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/reborrowing.rs @@ -2,11 +2,11 @@ use prusti_contracts::*; #[ensures(*result == old(*x))] pub fn reborrow(x: &u32) -> &u32 { - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold x } -#[ensures(false)] //~ ERROR postcondition might not hold. +#[ensures(false)] //~ERROR: postcondition might not hold. #[ensures(*result == old(*x))] pub fn reborrow2(x: &u32) -> &u32 { x @@ -22,7 +22,7 @@ pub fn test1() { assert!(a == 5); a = 6; assert!(a == 6); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/shared-borrows/ref-field.rs b/prusti-tests/tests/verify/fail/shared-borrows/ref-field.rs index 04d8b044d43..1a76bc7f38a 100644 --- a/prusti-tests/tests/verify/fail/shared-borrows/ref-field.rs +++ b/prusti-tests/tests/verify/fail/shared-borrows/ref-field.rs @@ -18,11 +18,11 @@ fn pure_get_field(x: &U) -> u32 { } fn test_wrong_precondition_pure(x: &U) -> u32 { - pure_get_field(x) //~ ERROR precondition of pure function call might not hold + pure_get_field(x) //~ERROR: precondition of pure function call might not hold } #[requires(x.v == 123)] -#[ensures(x.v == 456)] //~ ERROR postcondition might not hold +#[ensures(x.v == 456)] //~ERROR: postcondition might not hold fn test_wrong_postcondition_pure(x: &U) -> u32 { pure_get_field(x) } @@ -34,11 +34,11 @@ fn get_field(x: &U) -> u32 { } fn test_wrong_precondition(x: &U) -> u32 { - get_field(x) //~ ERROR precondition might not hold + get_field(x) //~ERROR: precondition might not hold } #[requires(x.v == 123)] -#[ensures(x.v == 456)] //~ ERROR postcondition might not hold +#[ensures(x.v == 456)] //~ERROR: postcondition might not hold fn test_wrong_postcondition(x: &U) -> u32 { get_field(x) } diff --git a/prusti-tests/tests/verify/fail/simple-specs/binary-search.rs b/prusti-tests/tests/verify/fail/simple-specs/binary-search.rs index ab678965d27..dfe7f933ae7 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/binary-search.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/binary-search.rs @@ -44,13 +44,13 @@ impl VecWrapperusize { // binary search using recursion pub fn binary_search_rec(arr: VecWrapperusize, target: usize) -> Option { let len = arr.len(); - binary_search_help(arr, 0, len - 1, target) //~ ERROR type invariant expected by the function call might not hold. + binary_search_help(arr, 0, len - 1, target) //~ERROR: type invariant expected by the function call might not hold. } fn binary_search_help(arr: VecWrapperusize, left: usize, right: usize, target: usize) -> Option { if left <= right { let mid = (left + right) / 2; - if arr.lookup(mid) < target { //~ ERROR precondition of pure function call might not hold + if arr.lookup(mid) < target { //~ERROR: precondition of pure function call might not hold return binary_search_help(arr, mid + 1, right, target); } else if arr.lookup(mid) > target { return binary_search_help(arr, left, mid - 1, target); @@ -73,7 +73,7 @@ pub fn binary_search_iter(arr: VecWrapperusize, target: usize) -> Option let mut condition = left <= right && !done; while condition { let mid = (left + right) / 2; - if arr.lookup(mid) < target { //~ ERROR precondition of pure function call might not hold + if arr.lookup(mid) < target { //~ERROR: precondition of pure function call might not hold left = mid + 1; } else if arr.lookup(mid) > target { right = mid - 1; diff --git a/prusti-tests/tests/verify/fail/simple-specs/ensures-false.rs b/prusti-tests/tests/verify/fail/simple-specs/ensures-false.rs index 2f69d3b9e28..504671a0261 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/ensures-false.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/ensures-false.rs @@ -1,5 +1,5 @@ use prusti_contracts::*; -#[ensures(false)] //~ ERROR postcondition +#[ensures(false)] //~ERROR: postcondition fn main() { } diff --git a/prusti-tests/tests/verify/fail/simple-specs/incorrect_nested_quantifiers.rs b/prusti-tests/tests/verify/fail/simple-specs/incorrect_nested_quantifiers.rs index 99d3bc190ca..84bef3bd8b4 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/incorrect_nested_quantifiers.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/incorrect_nested_quantifiers.rs @@ -1,6 +1,6 @@ use prusti_contracts::*; -#[ensures(forall(|y: u32| forall(|z: u32| y + z > old(*x))))] //~ ERROR postcondition might not hold +#[ensures(forall(|y: u32| forall(|z: u32| y + z > old(*x))))] //~ERROR: postcondition might not hold fn test(x: &mut u32) {} fn main() {} diff --git a/prusti-tests/tests/verify/fail/simple-specs/loops-before-inside.rs b/prusti-tests/tests/verify/fail/simple-specs/loops-before-inside.rs index 6bbc315bdf9..6e9e06f5212 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/loops-before-inside.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/loops-before-inside.rs @@ -3,7 +3,7 @@ use prusti_contracts::*; fn test_invariant_on_entry() -> i32 { let mut x = 0; while x < 10 { - body_invariant!(false); //~ ERROR loop invariant might not hold in the first loop iteration + body_invariant!(false); //~ERROR: loop invariant might not hold in the first loop iteration x += 1; } x @@ -12,7 +12,7 @@ fn test_invariant_on_entry() -> i32 { fn test_invariant_after_loop_iteration() -> i32 { let mut x = 0; while x < 10 { - body_invariant!(x == 0); //~ ERROR loop invariant might not hold after a loop iteration + body_invariant!(x == 0); //~ERROR: loop invariant might not hold after a loop iteration x += 1; } x diff --git a/prusti-tests/tests/verify/fail/simple-specs/no-precondition.rs b/prusti-tests/tests/verify/fail/simple-specs/no-precondition.rs index 4a37f2d6a84..74ee3c81ed7 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/no-precondition.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/no-precondition.rs @@ -1,6 +1,6 @@ use prusti_contracts::*; -#[ensures(match result { 4 => false, _ => true})] //~ ERROR postcondition might not hold +#[ensures(match result { 4 => false, _ => true})] //~ERROR: postcondition might not hold fn foo(x: i64, y: bool) -> i64 { let mut return_value = x * x; @@ -26,7 +26,7 @@ fn foo2(x: i64, y: bool) -> i64 { // ...more code... - assert!(return_value >= 0); //~ ERROR the asserted expression might not hold + assert!(return_value >= 0); //~ERROR: the asserted expression might not hold return_value } diff --git a/prusti-tests/tests/verify/fail/simple-specs/panic-in-post.rs b/prusti-tests/tests/verify/fail/simple-specs/panic-in-post.rs index d586b8c76d9..bf38f0e4d6f 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/panic-in-post.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/panic-in-post.rs @@ -8,7 +8,7 @@ use prusti_contracts::*; fn good(x: u32) {} #[ensures({ - assert!(x != 0); //~ ERROR postcondition might not hold + assert!(x != 0); //~ERROR: postcondition might not hold true })] fn bad(x: u32) {} diff --git a/prusti-tests/tests/verify/fail/simple-specs/panic-in-pre.rs b/prusti-tests/tests/verify/fail/simple-specs/panic-in-pre.rs index 88fab3e48d4..110e2dd1359 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/panic-in-pre.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/panic-in-pre.rs @@ -6,11 +6,11 @@ use prusti_contracts::*; })] fn foo(x: u32) { assert!(x != 0); // OK - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn bad(x: u32) { - foo(x); //~ ERROR precondition might not hold + foo(x); //~ERROR: precondition might not hold } fn main() { diff --git a/prusti-tests/tests/verify/fail/simple-specs/simple-ensures.rs b/prusti-tests/tests/verify/fail/simple-specs/simple-ensures.rs index 6425026a56a..863f180db5a 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/simple-ensures.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/simple-ensures.rs @@ -1,7 +1,7 @@ use prusti_contracts::*; -#[ensures(result == 6)] //~ ERROR postcondition might not hold +#[ensures(result == 6)] //~ERROR: postcondition might not hold fn func() -> u32{ 5 } diff --git a/prusti-tests/tests/verify/fail/simple-specs/trees-wrong.rs b/prusti-tests/tests/verify/fail/simple-specs/trees-wrong.rs index c20af30bca8..94edb873605 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/trees-wrong.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/trees-wrong.rs @@ -63,7 +63,7 @@ fn do_solve1(i: isize, fruits: &mut VecWrapperU32) -> u32 { } else { //do_solve1(i - 1, fruits) max( - fruits.lookup(to_usize(i)) //~ ERROR precondition + fruits.lookup(to_usize(i)) //~ERROR: precondition + do_solve1(i - 2, fruits), do_solve1(i - 1, fruits) ) diff --git a/prusti-tests/tests/verify/fail/simple-specs/unsigned_ints.rs b/prusti-tests/tests/verify/fail/simple-specs/unsigned_ints.rs index 4c09b0a1d32..7b1e39077bc 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/unsigned_ints.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/unsigned_ints.rs @@ -21,25 +21,25 @@ fn get_i32() -> i32 { fn test1() { assert!(get_usize() >= 0); assert!(get_u32() >= 0); - assert!(get_i32() >= 0); //~ ERROR the asserted expression might not hold + assert!(get_i32() >= 0); //~ERROR: the asserted expression might not hold } fn test2() { - assert!(get_usize() >= 1); //~ ERROR the asserted expression might not hold + assert!(get_usize() >= 1); //~ERROR: the asserted expression might not hold } fn test3(x: usize, y: u32, z: i32) { assert!(x >= 0); assert!(y >= 0); - assert!(z >= 0); //~ ERROR the asserted expression might not hold + assert!(z >= 0); //~ERROR: the asserted expression might not hold } fn test4(x: usize) { - assert!(x >= 1); //~ ERROR the asserted expression might not hold + assert!(x >= 1); //~ERROR: the asserted expression might not hold } fn test5(x: usize) { - test4(4 - x); //~ ERROR type invariant expected by the function call might not hold. + test4(4 - x); //~ERROR: type invariant expected by the function call might not hold. } fn main() {} diff --git a/prusti-tests/tests/verify/fail/simple-specs/unsupported-types.rs b/prusti-tests/tests/verify/fail/simple-specs/unsupported-types.rs index 321a32d4a10..eccd3a1babd 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/unsupported-types.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/unsupported-types.rs @@ -18,7 +18,7 @@ impl Request { Ok(req) } - #[ensures(matches!(result, Ok(_)))] //~ ERROR postcondition might not hold + #[ensures(matches!(result, Ok(_)))] //~ERROR: postcondition might not hold pub fn bad_parse() -> result::Result { Err(ErrorTypes::Err2) } diff --git a/prusti-tests/tests/verify/fail/simple-specs/wrong-identity.rs b/prusti-tests/tests/verify/fail/simple-specs/wrong-identity.rs index 3b468de6a6f..a10e9f61f3b 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/wrong-identity.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/wrong-identity.rs @@ -1,6 +1,6 @@ use prusti_contracts::*; -#[ensures(result == old(x))] //~ ERROR postcondition might not hold +#[ensures(result == old(x))] //~ERROR: postcondition might not hold fn identity(x: i32) -> i32 { x + 1 } diff --git a/prusti-tests/tests/verify/fail/simple-specs/wrong-method.rs b/prusti-tests/tests/verify/fail/simple-specs/wrong-method.rs index 58749e1463b..7b65b44ec6d 100644 --- a/prusti-tests/tests/verify/fail/simple-specs/wrong-method.rs +++ b/prusti-tests/tests/verify/fail/simple-specs/wrong-method.rs @@ -6,7 +6,7 @@ struct S { impl S { #[requires(true)] - #[ensures(false)] //~ ERROR postcondition + #[ensures(false)] //~ERROR: postcondition pub fn test(self) {} } diff --git a/prusti-tests/tests/verify/fail/trait-contracts-refinement/method-call.rs b/prusti-tests/tests/verify/fail/trait-contracts-refinement/method-call.rs index 400f26dfe39..78838c842b8 100644 --- a/prusti-tests/tests/verify/fail/trait-contracts-refinement/method-call.rs +++ b/prusti-tests/tests/verify/fail/trait-contracts-refinement/method-call.rs @@ -13,7 +13,7 @@ trait Foo { } #[requires(-1 <= c && c <= 1)] - #[ensures(result > 1)] //~ ERROR postcondition + #[ensures(result > 1)] //~ERROR: postcondition fn baz(&self, c: isize) -> isize { assert!(-1 <= c && c <= 1); // Ok 100 @@ -36,7 +36,7 @@ impl Foo for Dummy { fn test_foo_pre() { let d = Dummy; - d.foo(100); //~ ERROR precondition + d.foo(100); //~ERROR: precondition } fn test_foo_post() { @@ -52,7 +52,7 @@ fn test_bar_1_pre() { fn test_bar_2_pre() { let d = Dummy; - d.bar(100); //~ ERROR precondition + d.bar(100); //~ERROR: precondition } fn test_bar_1_post() { diff --git a/prusti-tests/tests/verify/fail/unsupported/async.rs b/prusti-tests/tests/verify/fail/unsupported/async.rs index a85edd76305..b1c5a0b9411 100644 --- a/prusti-tests/tests/verify/fail/unsupported/async.rs +++ b/prusti-tests/tests/verify/fail/unsupported/async.rs @@ -1,7 +1,7 @@ pub async fn connect(dst: D) where D: std::convert::TryInto -{ //~ ERROR unsupported type +{ //~ERROR: unsupported type } fn main(){} diff --git a/prusti-tests/tests/verify/fail/unsupported/async2.rs b/prusti-tests/tests/verify/fail/unsupported/async2.rs index 75bd37235ff..7fd0c523f58 100644 --- a/prusti-tests/tests/verify/fail/unsupported/async2.rs +++ b/prusti-tests/tests/verify/fail/unsupported/async2.rs @@ -5,7 +5,7 @@ impl QueryClient pub async fn accounts( &mut self, _request: u32 - ) -> Result { //~ ERROR unsupported type + ) -> Result { //~ERROR: unsupported type unimplemented!() } } diff --git a/prusti-tests/tests/verify/fail/unsupported/closure_ref_in_return.rs b/prusti-tests/tests/verify/fail/unsupported/closure_ref_in_return.rs index 9cce9a7bb1a..6a95c8198f5 100644 --- a/prusti-tests/tests/verify/fail/unsupported/closure_ref_in_return.rs +++ b/prusti-tests/tests/verify/fail/unsupported/closure_ref_in_return.rs @@ -19,7 +19,7 @@ pub enum ChainRequest { fn go(key_name: String) -> () { - || ChainRequest::AddKey { //~ ERROR access to reference-typed fields is not supported + || ChainRequest::AddKey { //~ERROR: access to reference-typed fields is not supported key_name }; } diff --git a/prusti-tests/tests/verify/fail/unsupported/higher_ranked_type.rs b/prusti-tests/tests/verify/fail/unsupported/higher_ranked_type.rs index f13bb1485f7..e7b0e5a7c01 100644 --- a/prusti-tests/tests/verify/fail/unsupported/higher_ranked_type.rs +++ b/prusti-tests/tests/verify/fail/unsupported/higher_ranked_type.rs @@ -1,3 +1,3 @@ fn main() { - let _ = (0..1).filter(|_| true); //~ ERROR higher-ranked lifetimes and types are not supported + let _ = (0..1).filter(|_| true); //~ERROR: higher-ranked lifetimes and types are not supported } \ No newline at end of file diff --git a/prusti-tests/tests/verify/fail/unsupported/iterators.rs b/prusti-tests/tests/verify/fail/unsupported/iterators.rs index f6a6a3e82f8..c21742d6149 100644 --- a/prusti-tests/tests/verify/fail/unsupported/iterators.rs +++ b/prusti-tests/tests/verify/fail/unsupported/iterators.rs @@ -8,7 +8,7 @@ pub struct cpu_set_t { } pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { - for slot in cpuset.bits.iter_mut() { //~ ERROR iterators are not fully supported yet + for slot in cpuset.bits.iter_mut() { //~ERROR: iterators are not fully supported yet *slot = 0; } } diff --git a/prusti-tests/tests/verify/fail/unsupported/rawptr.rs b/prusti-tests/tests/verify/fail/unsupported/rawptr.rs index 427889acc20..c33326b5a06 100644 --- a/prusti-tests/tests/verify/fail/unsupported/rawptr.rs +++ b/prusti-tests/tests/verify/fail/unsupported/rawptr.rs @@ -1,7 +1,7 @@ fn foo(p: *const i32) { - let _ = p.is_null(); //~ ERROR raw pointers are not supported + let _ = p.is_null(); //~ERROR: raw pointers are not supported } fn main() { - let _: *const i32 = std::ptr::null_mut(); //~ ERROR raw pointers are not supported + let _: *const i32 = std::ptr::null_mut(); //~ERROR: raw pointers are not supported } diff --git a/prusti-tests/tests/verify/fail/unsupported/region_of_proj.rs b/prusti-tests/tests/verify/fail/unsupported/region_of_proj.rs index 5a1961d19a3..abd638600b8 100644 --- a/prusti-tests/tests/verify/fail/unsupported/region_of_proj.rs +++ b/prusti-tests/tests/verify/fail/unsupported/region_of_proj.rs @@ -1,5 +1,5 @@ fn main() { println!("Hi"); let mut t = [0]; - t[0] = 1; //~ ERROR determining the region of array indexing is not supported + t[0] = 1; //~ERROR: determining the region of array indexing is not supported } \ No newline at end of file diff --git a/prusti-tests/tests/verify/fail/unsupported/shallow_borrow.rs b/prusti-tests/tests/verify/fail/unsupported/shallow_borrow.rs index f4c34448945..6d6efae5df4 100644 --- a/prusti-tests/tests/verify/fail/unsupported/shallow_borrow.rs +++ b/prusti-tests/tests/verify/fail/unsupported/shallow_borrow.rs @@ -4,7 +4,7 @@ fn iterator_len_hint(iter: &I) -> Option where I: Iterator, { - match iter.size_hint() { //~ ERROR unsupported creation of shallow borrows (implicitly created when lowering matches) + match iter.size_hint() { //~ERROR: unsupported creation of shallow borrows (implicitly created when lowering matches) (lo, Some(hi)) if lo == hi => Some(lo), _ => None, } diff --git a/prusti-tests/tests/verify/fail/unsupported/two_phase_borrow.rs b/prusti-tests/tests/verify/fail/unsupported/two_phase_borrow.rs index 43be1f4b0b5..d38292a8da9 100644 --- a/prusti-tests/tests/verify/fail/unsupported/two_phase_borrow.rs +++ b/prusti-tests/tests/verify/fail/unsupported/two_phase_borrow.rs @@ -1,6 +1,6 @@ fn foo(a: &mut [i32], l: usize) {} -fn bar(a: &mut [i32]) { //~ ERROR two-phase borrows are not supported +fn bar(a: &mut [i32]) { //~ERROR: two-phase borrows are not supported foo(a, a.len()); } diff --git a/prusti-tests/tests/verify/fail/unsupported/union.rs b/prusti-tests/tests/verify/fail/unsupported/union.rs index 0ba7260c025..5951cecbe70 100644 --- a/prusti-tests/tests/verify/fail/unsupported/union.rs +++ b/prusti-tests/tests/verify/fail/unsupported/union.rs @@ -4,5 +4,5 @@ union Foo { } fn main() { - let _ = Foo { a: [0] }; //~ ERROR unions are not supported + let _ = Foo { a: [0] }; //~ERROR: unions are not supported } diff --git a/prusti-tests/tests/verify/fail/unsupported/unique_borrow.rs b/prusti-tests/tests/verify/fail/unsupported/unique_borrow.rs index 2420d03e6b1..9f57fc30237 100644 --- a/prusti-tests/tests/verify/fail/unsupported/unique_borrow.rs +++ b/prusti-tests/tests/verify/fail/unsupported/unique_borrow.rs @@ -19,8 +19,8 @@ impl Lazy { { { let r = &mut self.0; - self.1.call_once(|| { //~ ERROR unsuported creation of unique borrows (implicitly created in closure bindings) - *r = None; //~ ERROR determining the region of a dereferentiation is not supported + self.1.call_once(|| { //~ERROR: unsuported creation of unique borrows (implicitly created in closure bindings) + *r = None; //~ERROR: determining the region of a dereferentiation is not supported }); } } diff --git a/prusti-tests/tests/verify/fail/unsupported/unsize.rs b/prusti-tests/tests/verify/fail/unsupported/unsize.rs index b0588aba2bd..7213bf9f190 100644 --- a/prusti-tests/tests/verify/fail/unsupported/unsize.rs +++ b/prusti-tests/tests/verify/fail/unsupported/unsize.rs @@ -1,3 +1,3 @@ fn main() { - let _ = vec![1]; //~ ERROR unsizing a std::boxed::Box<[i32; 1]> into a std::boxed::Box<[i32]> is not supported + let _ = vec![1]; //~ERROR: unsizing a std::boxed::Box<[i32; 1]> into a std::boxed::Box<[i32]> is not supported } \ No newline at end of file diff --git a/prusti-tests/tests/verify/fail/unsupported/variadic_func.rs b/prusti-tests/tests/verify/fail/unsupported/variadic_func.rs index 1c68990763b..bc8fadb0a50 100644 --- a/prusti-tests/tests/verify/fail/unsupported/variadic_func.rs +++ b/prusti-tests/tests/verify/fail/unsupported/variadic_func.rs @@ -1,6 +1,6 @@ #![feature(c_variadic)] -unsafe extern "C" fn func(i: i32, mut args: ...) {} //~ ERROR variadic functions are not supported +unsafe extern "C" fn func(i: i32, mut args: ...) {} //~ERROR: variadic functions are not supported fn main() { - unsafe{func(0, 0);} //~ ERROR variadic functions are not supported + unsafe{func(0, 0);} //~ERROR: variadic functions are not supported } diff --git a/prusti-tests/tests/verify_overflow/fail/casts/sign_mix.rs b/prusti-tests/tests/verify_overflow/fail/casts/sign_mix.rs index 1bdca62320e..bea49cccf93 100644 --- a/prusti-tests/tests/verify_overflow/fail/casts/sign_mix.rs +++ b/prusti-tests/tests/verify_overflow/fail/casts/sign_mix.rs @@ -1,59 +1,59 @@ use prusti_contracts::*; pub fn u64_u32(x: u64) -> i32 { - x as i32 //~ ERROR value might not fit into the target type. + x as i32 //~ERROR: value might not fit into the target type. } pub fn u64_i16(x: u64) -> i16 { - x as i16 //~ ERROR value might not fit into the target type. + x as i16 //~ERROR: value might not fit into the target type. } pub fn u64_i8(x: u64) -> i8 { - x as i8 //~ ERROR value might not fit into the target type. + x as i8 //~ERROR: value might not fit into the target type. } pub fn u16_i8(x: u16) -> i8 { - x as i8 //~ ERROR value might not fit into the target type. + x as i8 //~ERROR: value might not fit into the target type. } #[requires(0 <= x)] pub fn i64_u32_max(x: i64) -> u32 { - x as u32 //~ ERROR value might not fit into the target type. + x as u32 //~ERROR: value might not fit into the target type. } #[requires(0 <= x)] pub fn i64_u16_max(x: i64) -> u16 { - x as u16 //~ ERROR value might not fit into the target type. + x as u16 //~ERROR: value might not fit into the target type. } #[requires(0 <= x)] pub fn i64_u8_max(x: i64) -> u8 { - x as u8 //~ ERROR value might not fit into the target type. + x as u8 //~ERROR: value might not fit into the target type. } #[requires(0 <= x)] pub fn i16_u8_max(x: i16) -> u8 { - x as u8 //~ ERROR value might not fit into the target type. + x as u8 //~ERROR: value might not fit into the target type. } #[requires(x < std::u32::MAX as i64)] pub fn i64_u32_min(x: i64) -> u32 { - x as u32 //~ ERROR value might not fit into the target type. + x as u32 //~ERROR: value might not fit into the target type. } #[requires(x < std::u16::MAX as i64)] pub fn i64_u16_min(x: i64) -> u16 { - x as u16 //~ ERROR value might not fit into the target type. + x as u16 //~ERROR: value might not fit into the target type. } #[requires(x < std::u8::MAX as i64)] pub fn i64_u8_min(x: i64) -> u8 { - x as u8 //~ ERROR value might not fit into the target type. + x as u8 //~ERROR: value might not fit into the target type. } #[requires(x < std::u8::MAX as i16)] pub fn i16_u8_min(x: i16) -> u8 { - x as u8 //~ ERROR value might not fit into the target type. + x as u8 //~ERROR: value might not fit into the target type. } fn preserve_sign() { @@ -82,7 +82,7 @@ fn preserve_sign() { assert!(-5i128 as i128 == -5i128); assert!( - -5i8 as u128 //~ ERROR value might not fit into the target type. + -5i8 as u128 //~ERROR: value might not fit into the target type. == 5u128 ); } diff --git a/prusti-tests/tests/verify_overflow/fail/casts/signed.rs b/prusti-tests/tests/verify_overflow/fail/casts/signed.rs index 429fe6b5519..fdc835f468a 100644 --- a/prusti-tests/tests/verify_overflow/fail/casts/signed.rs +++ b/prusti-tests/tests/verify_overflow/fail/casts/signed.rs @@ -2,42 +2,42 @@ use prusti_contracts::*; #[requires(x < std::i32::MAX as i64)] pub fn i64_u32_max(x: i64) -> i32 { - x as i32 //~ ERROR value might not fit into the target type. + x as i32 //~ERROR: value might not fit into the target type. } #[requires(x < std::i16::MAX as i64)] pub fn i64_i16_max(x: i64) -> i16 { - x as i16 //~ ERROR value might not fit into the target type. + x as i16 //~ERROR: value might not fit into the target type. } #[requires(x < std::i8::MAX as i64)] pub fn i64_i8_max(x: i64) -> i8 { - x as i8 //~ ERROR value might not fit into the target type. + x as i8 //~ERROR: value might not fit into the target type. } #[requires(x < std::i8::MAX as i16)] pub fn u16_i8_max(x: i16) -> i8 { - x as i8 //~ ERROR value might not fit into the target type. + x as i8 //~ERROR: value might not fit into the target type. } #[requires(std::i32::MIN as i64 <= x)] pub fn i64_u32_min(x: i64) -> i32 { - x as i32 //~ ERROR value might not fit into the target type. + x as i32 //~ERROR: value might not fit into the target type. } #[requires(std::i16::MIN as i64 <= x)] pub fn i64_i16_min(x: i64) -> i16 { - x as i16 //~ ERROR value might not fit into the target type. + x as i16 //~ERROR: value might not fit into the target type. } #[requires(std::i8::MIN as i64 <= x)] pub fn i64_i8_min(x: i64) -> i8 { - x as i8 //~ ERROR value might not fit into the target type. + x as i8 //~ERROR: value might not fit into the target type. } #[requires(std::i8::MIN as i16 <= x)] pub fn u16_i8_min(x: i16) -> i8 { - x as i8 //~ ERROR value might not fit into the target type. + x as i8 //~ERROR: value might not fit into the target type. } fn main() {} \ No newline at end of file diff --git a/prusti-tests/tests/verify_overflow/fail/casts/unsigned.rs b/prusti-tests/tests/verify_overflow/fail/casts/unsigned.rs index c677948512e..3dabc11ec71 100644 --- a/prusti-tests/tests/verify_overflow/fail/casts/unsigned.rs +++ b/prusti-tests/tests/verify_overflow/fail/casts/unsigned.rs @@ -1,19 +1,19 @@ use prusti_contracts::*; pub fn u64_u32(x: u64) -> u32 { - x as u32 //~ ERROR value might not fit into the target type. + x as u32 //~ERROR: value might not fit into the target type. } pub fn u64_u16(x: u64) -> u16 { - x as u16 //~ ERROR value might not fit into the target type. + x as u16 //~ERROR: value might not fit into the target type. } pub fn u64_u8(x: u64) -> u8 { - x as u8 //~ ERROR value might not fit into the target type. + x as u8 //~ERROR: value might not fit into the target type. } pub fn u16_u8(x: u16) -> u8 { - x as u8 //~ ERROR value might not fit into the target type. + x as u8 //~ERROR: value might not fit into the target type. } fn main() {} \ No newline at end of file diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/arithmetic.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/arithmetic.rs index cad371c3c2c..07da7d143ff 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/arithmetic.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/arithmetic.rs @@ -13,11 +13,11 @@ fn test2() { let a = 1; let b = 2; let c = a + b; - assert!(c == 4); //~ ERROR the asserted expression might not hold + assert!(c == 4); //~ERROR: the asserted expression might not hold } fn test3(a: i32, b: i32) -> i32 { - a + b //~ ERROR assertion might fail with "attempt to add with overflow" + a + b //~ERROR: assertion might fail with "attempt to add with overflow" } fn test4() { diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/drops.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/drops.rs index 27730ab4029..a3a0684df7d 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/drops.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/drops.rs @@ -27,7 +27,7 @@ fn test1() { fn test2() { let b = T2 { f: 4 }; - assert!(b.f == 5); //~ ERROR the asserted expression might not hold + assert!(b.f == 5); //~ERROR: the asserted expression might not hold } fn random() -> bool { @@ -46,7 +46,7 @@ fn test4() { if random() { let _b = a; } - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } fn test5() { diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/drops2.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/drops2.rs index c95b2c24e8f..cfccada4fbf 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/drops2.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/drops2.rs @@ -21,7 +21,7 @@ impl Drop for T { fn test1() { { let a = T { f: 4 }; - } //~ ERROR the drop handler was called. + } //~ERROR: the drop handler was called. let b = T2 { f: 4 }; } @@ -43,7 +43,7 @@ fn test3() { fn test4() { let a = T { f: 4 }; let b = T3 { g: a }; -} //~ ERROR the drop handler was called. +} //~ERROR: the drop handler was called. fn test5() { let a = T { f: 4 }; @@ -67,7 +67,7 @@ fn test7() { if random() { drop(b.g); } -} //~ ERROR the drop handler was called. +} //~ERROR: the drop handler was called. fn test8() { let c = random(); @@ -90,7 +90,7 @@ fn test9() { } else { drop(b); } -} //~ ERROR the drop handler was called. +} //~ERROR: the drop handler was called. fn main() {} diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/model.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/model.rs index 6dd3ef05e18..a45c20d51b1 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/model.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/model.rs @@ -18,7 +18,7 @@ fn push_i32(v: &mut VecWrapper, val: i32) { v.values.push(val); } -#[ensures(v.model().last_pushed == 5)] //~ ERROR postcondition might not hold. +#[ensures(v.model().last_pushed == 5)] //~ERROR: postcondition might not hold. fn len(v: VecWrapper){ () } diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/model2.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/model2.rs index b2dfeef7704..be6a14b688a 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/model2.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/model2.rs @@ -37,7 +37,7 @@ fn push_i32(v: &mut VecWrapper, val: i32) { } -#[ensures(v.model().last_pushed.x == 5)] //~ ERROR postcondition might not hold. +#[ensures(v.model().last_pushed.x == 5)] //~ERROR: postcondition might not hold. fn len(v: VecWrapper){ () } diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/old.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/old.rs index 215cfafa725..ec99da029c1 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/old.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/old.rs @@ -7,7 +7,7 @@ use prusti_contracts::*; fn test1(a: i32) {} #[requires(a == 4)] -#[ensures(old(a) == 5)] //~ ERROR postcondition might not hold. +#[ensures(old(a) == 5)] //~ERROR: postcondition might not hold. fn test2(a: i32) {} #[requires(a == 4)] @@ -17,7 +17,7 @@ fn test3(mut a: i32) { } #[requires(a == 4)] -#[ensures(old(a) == 5)] //~ ERROR postcondition might not hold. +#[ensures(old(a) == 5)] //~ERROR: postcondition might not hold. fn test4(mut a: i32) { a = 5; } @@ -29,14 +29,14 @@ fn test5(mut a: i32) { } #[requires(a == 4)] -#[ensures(a == 5)] //~ ERROR postcondition might not hold. +#[ensures(a == 5)] //~ERROR: postcondition might not hold. fn test6(mut a: i32) { a = 5; } fn test7() { test5(4); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[requires(a < 10)] @@ -55,7 +55,7 @@ fn test9() { let a = 5; let b = inc1(a); assert!(b == 6); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[requires(a < 10)] @@ -75,7 +75,7 @@ fn test11() { let a = 5; let b = inc2(a); assert!(b == 6); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[requires(a < 10)] @@ -94,7 +94,7 @@ fn test13() { let a = 5; let b = inc3(a); assert!(b == 6); - assert!(false); //~ ERROR the asserted expression might not hold + assert!(false); //~ERROR: the asserted expression might not hold } #[requires(a == 4)] diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/pure.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/pure.rs index b2302a87409..39a879e124a 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/pure.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/pure.rs @@ -13,7 +13,7 @@ fn test1(a: usize) -> usize { identity(a) } -#[ensures(a != result)] //~ ERROR postcondition might not hold. +#[ensures(a != result)] //~ERROR: postcondition might not hold. fn test1_neg(a: usize) -> usize { identity(a) } @@ -30,7 +30,7 @@ fn identity2(a: usize) -> usize { #[ensures(a == identity2(a))] fn test3(a: usize) {} -#[ensures(a != identity2(a))] //~ ERROR postcondition might not hold. +#[ensures(a != identity2(a))] //~ERROR: postcondition might not hold. fn test4(a: usize) {} #[pure] diff --git a/prusti-tests/tests/verify_overflow/fail/core_proof/pure2.rs b/prusti-tests/tests/verify_overflow/fail/core_proof/pure2.rs index 01901b88992..1e75c3d5a08 100644 --- a/prusti-tests/tests/verify_overflow/fail/core_proof/pure2.rs +++ b/prusti-tests/tests/verify_overflow/fail/core_proof/pure2.rs @@ -17,7 +17,7 @@ fn count(n: usize) -> usize { // This is expected to fail because the gas is set to 2 and proving this // requires unfolding 3 times. If this succeeded, then it would indicate // that we have a matching loop. -#[ensures(count(3) == 3)] //~ ERROR postcondition might not hold. +#[ensures(count(3) == 3)] //~ERROR: postcondition might not hold. fn test6() {} fn main() {} diff --git a/prusti-tests/tests/verify_overflow/fail/extern-spec/duplicate-1.rs b/prusti-tests/tests/verify_overflow/fail/extern-spec/duplicate-1.rs index dc4ff8eacf1..1fa02ecaaf8 100644 --- a/prusti-tests/tests/verify_overflow/fail/extern-spec/duplicate-1.rs +++ b/prusti-tests/tests/verify_overflow/fail/extern-spec/duplicate-1.rs @@ -20,7 +20,7 @@ impl TestStruct { #[pure] #[ensures(result >= a && result >= b)] #[ensures(result == a || result == b)] - fn max(a: i32, b: i32) -> i32; //~ ERROR already has a specification + fn max(a: i32, b: i32) -> i32; //~ERROR: already has a specification } fn main() { diff --git a/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-1.rs b/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-1.rs index ed1758aa35e..8c9f586e1a7 100644 --- a/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-1.rs +++ b/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-1.rs @@ -4,7 +4,7 @@ use prusti_contracts::*; impl std::vec::Vec { /// Wrong number of arguments #[ensures(self.len() == old(self.len()) + 1)] - fn push(&mut self); //~ ERROR this function takes 2 arguments but 1 argument was supplied + fn push(&mut self); //~ERROR: this function takes 2 arguments but 1 argument was supplied } fn main() {} diff --git a/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-2.rs b/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-2.rs index 929ba79f928..422a6642316 100644 --- a/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-2.rs +++ b/prusti-tests/tests/verify_overflow/fail/extern-spec/mismatched-sigs-2.rs @@ -4,7 +4,7 @@ use prusti_contracts::*; impl std::vec::Vec { /// Wrong method name #[ensures(self.len() == 0)] - fn clears(&mut self); //~ ERROR no function or associated item + fn clears(&mut self); //~ERROR: no function or associated item } fn main() {} diff --git a/prusti-tests/tests/verify_overflow/fail/fail-uint-fn.rs b/prusti-tests/tests/verify_overflow/fail/fail-uint-fn.rs index bd506e28db7..c42c5bc1f79 100644 --- a/prusti-tests/tests/verify_overflow/fail/fail-uint-fn.rs +++ b/prusti-tests/tests/verify_overflow/fail/fail-uint-fn.rs @@ -2,17 +2,17 @@ use prusti_contracts::*; #[pure] fn test_minus_i32(x: i32) -> i32 { - -x //~ ERROR negate with overflow + -x //~ERROR: negate with overflow } #[pure] fn test_minus_i64(x: i64) -> i64 { - -x //~ ERROR negate with overflow + -x //~ERROR: negate with overflow } #[pure] fn test_minus_isize(x: isize) -> isize { - -x //~ ERROR negate with overflow + -x //~ERROR: negate with overflow } fn main() {} diff --git a/prusti-tests/tests/verify_overflow/fail/generic/snap-eq.rs b/prusti-tests/tests/verify_overflow/fail/generic/snap-eq.rs index 476afd73600..838aaa601ad 100644 --- a/prusti-tests/tests/verify_overflow/fail/generic/snap-eq.rs +++ b/prusti-tests/tests/verify_overflow/fail/generic/snap-eq.rs @@ -6,19 +6,19 @@ fn foo(a: T, b: T) {} struct X { a: i32 } fn test1() { - foo(4, 5); //~ ERROR precondition might not hold + foo(4, 5); //~ERROR: precondition might not hold } fn test2() { - foo(false, true); //~ ERROR precondition might not hold + foo(false, true); //~ERROR: precondition might not hold } fn test3() { - foo((1, 1), (1, 2)); //~ ERROR precondition might not hold + foo((1, 1), (1, 2)); //~ERROR: precondition might not hold } fn test4() { - foo(X { a: 2 }, X { a: 1 }); //~ ERROR precondition might not hold + foo(X { a: 2 }, X { a: 1 }); //~ERROR: precondition might not hold } #[trusted] diff --git a/prusti-tests/tests/verify_overflow/fail/index-vec.rs b/prusti-tests/tests/verify_overflow/fail/index-vec.rs index 04929897555..9f9922f72a0 100644 --- a/prusti-tests/tests/verify_overflow/fail/index-vec.rs +++ b/prusti-tests/tests/verify_overflow/fail/index-vec.rs @@ -2,7 +2,7 @@ use prusti_contracts::*; #[pure] fn get_third(v: &Vec) -> u32 { - v[2] //~ ERROR Using usize as index/range type for &std::vec::Vec is not currently supported in pure functions + v[2] //~ERROR: Using usize as index/range type for &std::vec::Vec is not currently supported in pure functions //~^ ERROR Non-slice LHS type '&u32' not supported yet } diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-2.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-2.rs index 05a4ba1f1e6..f0b2139d936 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-2.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-2.rs @@ -19,7 +19,7 @@ impl Percentage { //#[requires(x <= 100)] fn test(x: u8) { let mut perc = Percentage { value: x }; - perc.incr(); //~ ERROR precondition might not hold + perc.incr(); //~ERROR: precondition might not hold } fn main() {} diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-4.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-4.rs index 6d03a1ffd66..0073a73a65c 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-4.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-4.rs @@ -9,7 +9,7 @@ struct Percentage { } impl Percentage { - fn incr(&mut self) { //~ ERROR type invariants + fn incr(&mut self) { //~ERROR: type invariants if self.value <= 100 { // mistake self.value += 1; } diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-6.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-6.rs index 94c47399fcc..dd07986b2bd 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-6.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-6.rs @@ -10,7 +10,7 @@ struct Percentage { impl Percentage { //#[requires(value <= 100)] - fn new(value: u8) -> Self { //~ ERROR type invariants + fn new(value: u8) -> Self { //~ERROR: type invariants Percentage { value: value, } diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-7.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-7.rs index cc2e282f330..4f37924206c 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-7.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-basic-7.rs @@ -10,7 +10,7 @@ struct Percentage { #[requires(percentage.value >= 10)] -fn adjust_percentage(percentage: &mut Percentage, flag: bool) { //~ ERROR type invariants +fn adjust_percentage(percentage: &mut Percentage, flag: bool) { //~ERROR: type invariants let mut f0 = flag; if flag { percentage.value += 10; // temporarily break invariant diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-borrow.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-borrow.rs index c04926aded9..3b6a9e71087 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-borrow.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-borrow.rs @@ -6,7 +6,7 @@ struct Percentage { value: u8, } -fn make_percentage() -> Percentage { //~ ERROR type invariants +fn make_percentage() -> Percentage { //~ERROR: type invariants let mut p = Percentage { value: 100 }; double(&mut p.value); p diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-construct.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-construct.rs index 8c2eadd1dde..13d8279c828 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-construct.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-construct.rs @@ -6,7 +6,7 @@ struct Percentage { value: u8, } -fn make_percentage() -> Percentage { //~ ERROR type invariants +fn make_percentage() -> Percentage { //~ERROR: type invariants Percentage { value: 101 } } diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-func.rs b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-func.rs index c4e1c2596a9..9e0ff03de35 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/invariants-func.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/invariants-func.rs @@ -22,7 +22,7 @@ fn adjust_percentage(percentage: &mut Percentage, flag: bool) { f0 = true; } - print_percentage(percentage); //~ ERROR precondition + print_percentage(percentage); //~ERROR: precondition if f0 { percentage.value /= 2; // restore invariant diff --git a/prusti-tests/tests/verify_overflow/fail/invariants/issue-1015.rs b/prusti-tests/tests/verify_overflow/fail/invariants/issue-1015.rs index 61f5280e2ba..41721b3fc7f 100644 --- a/prusti-tests/tests/verify_overflow/fail/invariants/issue-1015.rs +++ b/prusti-tests/tests/verify_overflow/fail/invariants/issue-1015.rs @@ -5,7 +5,7 @@ use prusti_contracts::*; struct S; #[pure] -#[ensures(false)] //~ ERROR postcondition might not hold. +#[ensures(false)] //~ERROR: postcondition might not hold. fn foo(s: &S) {} fn main() { diff --git a/prusti-tests/tests/verify_overflow/fail/issues/issue-416.rs b/prusti-tests/tests/verify_overflow/fail/issues/issue-416.rs index 8c0979c6734..a7b4bd61ba0 100644 --- a/prusti-tests/tests/verify_overflow/fail/issues/issue-416.rs +++ b/prusti-tests/tests/verify_overflow/fail/issues/issue-416.rs @@ -8,7 +8,7 @@ impl SafeVec { #[pure] // FIXME: The error was tracked in https://github.com/viperproject/prusti-dev/issues/683 pub unsafe fn get_unchecked_1(&self, idx: usize) -> &T { - self.0.get_unchecked(idx) //~ ERROR use of impure function + self.0.get_unchecked(idx) //~ERROR: use of impure function } #[pure] diff --git a/prusti-tests/tests/verify_overflow/fail/issues/issue-709-12.rs b/prusti-tests/tests/verify_overflow/fail/issues/issue-709-12.rs index 8db5fe6f37d..a851f9bcf55 100644 --- a/prusti-tests/tests/verify_overflow/fail/issues/issue-709-12.rs +++ b/prusti-tests/tests/verify_overflow/fail/issues/issue-709-12.rs @@ -11,7 +11,7 @@ impl B { #[requires(index <= self.0.len())] #[ensures(result.len() == index)] pub fn get_mut(&mut self, index: usize) -> &mut [A] { - &mut self.0[0..index] //~ ERROR mutably slicing is not fully supported yet + &mut self.0[0..index] //~ERROR: mutably slicing is not fully supported yet } } diff --git a/prusti-tests/tests/verify_overflow/fail/overflow/bisect.rs b/prusti-tests/tests/verify_overflow/fail/overflow/bisect.rs index c7cde7e03ff..3caaa956774 100644 --- a/prusti-tests/tests/verify_overflow/fail/overflow/bisect.rs +++ b/prusti-tests/tests/verify_overflow/fail/overflow/bisect.rs @@ -17,7 +17,7 @@ fn bisect(f: &T, target: i32) -> Option { let mut high = f.domain_size(); while low < high { body_invariant!(low < high && high <= f.domain_size()); - let mid = (low + high) / 2; //~ ERROR assertion might fail with "attempt to add with overflow" + let mid = (low + high) / 2; //~ERROR: assertion might fail with "attempt to add with overflow" let mid_val = f.eval(mid); if mid_val < target { low = mid + 1; diff --git a/prusti-tests/tests/verify_overflow/fail/pure-fn-overflow-error.rs b/prusti-tests/tests/verify_overflow/fail/pure-fn-overflow-error.rs index 135630688a6..b1962065cd4 100644 --- a/prusti-tests/tests/verify_overflow/fail/pure-fn-overflow-error.rs +++ b/prusti-tests/tests/verify_overflow/fail/pure-fn-overflow-error.rs @@ -2,7 +2,7 @@ use prusti_contracts::*; #[pure] fn test_usize(x: usize) -> usize { - x - 1 //~ ERROR overflow + x - 1 //~ERROR: overflow } pub fn test() { diff --git a/prusti-tests/tests/verify_overflow/fail/pure_assignments.rs b/prusti-tests/tests/verify_overflow/fail/pure_assignments.rs index b03f47b0b5f..35512439f7d 100644 --- a/prusti-tests/tests/verify_overflow/fail/pure_assignments.rs +++ b/prusti-tests/tests/verify_overflow/fail/pure_assignments.rs @@ -5,7 +5,7 @@ use prusti_contracts::*; #[pure] fn pure1() -> (u32, u32) { let mut x = (1, 2); - x.1 = 3; //~ ERROR only assignments to local variables are supported in pure code + x.1 = 3; //~ERROR: only assignments to local variables are supported in pure code x } @@ -13,7 +13,7 @@ fn pure1() -> (u32, u32) { fn pure2() -> (u32, u32) { let mut x = (1, 2); let y = &mut x.1; - *y = 3; //~ ERROR only assignments to local variables are supported in pure code + *y = 3; //~ERROR: only assignments to local variables are supported in pure code x } diff --git a/prusti-utils/src/config.rs b/prusti-utils/src/config.rs index e11da7863fc..e3e59986b60 100644 --- a/prusti-utils/src/config.rs +++ b/prusti-utils/src/config.rs @@ -4,6 +4,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #![allow(deprecated)] +#![allow(clippy::too_long_first_doc_paragraph)] pub mod commandline; diff --git a/prusti-utils/src/launch/mod.rs b/prusti-utils/src/launch/mod.rs index c546e107c2c..66dc32d3789 100644 --- a/prusti-utils/src/launch/mod.rs +++ b/prusti-utils/src/launch/mod.rs @@ -288,13 +288,23 @@ pub fn set_java_home_setting(cmd: &mut Command, java_home: &Path) { cmd.env("PRUSTI_JAVA_HOME", java_home); } -/// Checks if the current crate has a (transitive) dependency on `prusti-contracts` -/// and if that should lead to enabling the `prusti` feature when running cargo. -/// Will panic if there is a transitive dependency but not a direct one; in such a -/// case it wouldn't be possible to enable the feature. -pub fn enable_prusti_feature(cargo_path: &str) -> bool { - let out = Command::new(cargo_path) - .args(["tree", "--prefix", "depth", "-f", " [{f}] {p}"]) +/// Checks if the current crate enable the `prusti` cargo feature on +/// `prusti-contracts`. +/// +/// The feature should be enabled if the current crate has a (transitive) +/// dependency on `prusti-contracts`. Will panic if there is a transitive +/// dependency but not a direct one; in such a case it isn't possible +/// to enable the feature. +pub fn enable_prusti_feature(cargo_path: &str, manifest_path: Option<&str>) -> bool { + let mut command = Command::new(cargo_path); + command.args(["tree", "--prefix", "depth", "-f", " [{f}] {p}"]); + + // `--manifest-path` makes `cargo` invocations not CWD-dependent. + if let Some(manifest_path) = manifest_path { + command.args(["--manifest-path", manifest_path]); + } + + let out = command .output() .unwrap_or_else(|_| panic!("Failed to run '{cargo_path} tree'")); // Expected stdout: diff --git a/prusti-utils/src/report/user.rs b/prusti-utils/src/report/user.rs index fb5a30e624b..3b5e9c14d99 100644 --- a/prusti-utils/src/report/user.rs +++ b/prusti-utils/src/report/user.rs @@ -8,8 +8,10 @@ use crate::config; -/// Print to stderr a message that is only meant to be read by the user. -/// The output goes to *stderr*, to be displayed in the "compiler output" area in rust-playground. +/// Print a message to stderr that is only meant to be read by the user. +/// +/// The output goes to stderr, to be displayed in the "compiler output" area +/// in rust-playground. /// Note: this function does nothing if `config::quiet()` is true. pub fn message(msg: S) { if !config::quiet() { diff --git a/prusti-viper/src/lib.rs b/prusti-viper/src/lib.rs index d4059ae9339..171becd8cd3 100644 --- a/prusti-viper/src/lib.rs +++ b/prusti-viper/src/lib.rs @@ -4,7 +4,10 @@ use rustc_hash::FxHashMap; use viper::{self, AstFactory, Position}; /// Convert the given VIR program into a Viper program (i.e., Java object). -pub fn program_to_viper<'vir, 'v>(program: vir::Program<'vir>, ast: &'vir AstFactory<'v>) -> viper::Program<'vir> { +pub fn program_to_viper<'vir>( + program: vir::Program<'vir>, + ast: &'vir AstFactory<'_>, +) -> viper::Program<'vir> { let mut domains: FxHashMap<_, _> = Default::default(); let mut domain_functions: FxHashMap<_, _> = Default::default(); let mut domain_axioms: FxHashMap<_, _> = Default::default(); @@ -26,9 +29,11 @@ pub fn program_to_viper<'vir, 'v>(program: vir::Program<'vir>, ast: &'vir AstFac program.to_viper_no_pos(&ctx) } -/// Context for conversion of VIR nodes to Viper AST. We need to keep track of -/// domain information in particular, since domain function application nodes -/// must be created with information that we do not store in the VIR. +/// Context for conversion of VIR nodes to Viper AST. +/// +/// We need to keep track of domain information in particular, since domain +/// function application nodes must be created with information that we do not +/// store in the VIR. pub struct ToViperContext<'vir, 'v> { /// Wrapper around JNI methods to create Viper AST methods. ast: &'v AstFactory<'v>, @@ -87,7 +92,12 @@ pub trait ToViperVec<'vir, 'v> { type Output; /// Extend the given vector with the converted contents of `self`. - fn to_viper_extend(&self, vec: &mut Vec, ctx: &ToViperContext<'vir, 'v>, pos: Position); + fn to_viper_extend( + &self, + vec: &mut Vec, + ctx: &ToViperContext<'vir, 'v>, + pos: Position, + ); /// Indicate how many elements there are in `self`. Does not need to be /// provided, nor does it need to be accurate; this is only used to set a @@ -110,14 +120,22 @@ pub trait ToViperVec<'vir, 'v> { trait ToViperPosHelper<'vir, 'v> { type Output; fn to_viper_no_pos(&self, ctx: &ToViperContext<'vir, 'v>) -> Self::Output; - fn to_viper_with_span(&self, ctx: &ToViperContext<'vir, 'v>, span: Option<&'vir vir::VirSpan<'vir>>) -> Self::Output; + fn to_viper_with_span( + &self, + ctx: &ToViperContext<'vir, 'v>, + span: Option<&'vir vir::VirSpan<'vir>>, + ) -> Self::Output; } impl<'vir, 'v, T: ToViper<'vir, 'v>> ToViperPosHelper<'vir, 'v> for T { type Output = >::Output; fn to_viper_no_pos(&self, ctx: &ToViperContext<'vir, 'v>) -> Self::Output { self.to_viper(ctx, ctx.ast.no_position()) } - fn to_viper_with_span(&self, ctx: &ToViperContext<'vir, 'v>, span: Option<&'vir vir::VirSpan<'vir>>) -> Self::Output { + fn to_viper_with_span( + &self, + ctx: &ToViperContext<'vir, 'v>, + span: Option<&'vir vir::VirSpan<'vir>>, + ) -> Self::Output { self.to_viper(ctx, ctx.span_to_pos(span)) } } @@ -125,16 +143,16 @@ impl<'vir, 'v, T: ToViper<'vir, 'v>> ToViperPosHelper<'vir, 'v> for T { trait ToViperVecPosHelper<'vir, 'v> { type Output; fn to_viper_extend_no_pos(&self, vec: &mut Vec, ctx: &ToViperContext<'vir, 'v>); - fn to_viper_vec_no_pos(&self, ctx: &ToViperContext<'vir, 'v>) -> Vec; + //fn to_viper_vec_no_pos(&self, ctx: &ToViperContext<'vir, 'v>) -> Vec; } impl<'vir, 'v, T: ToViperVec<'vir, 'v>> ToViperVecPosHelper<'vir, 'v> for T { type Output = >::Output; fn to_viper_extend_no_pos(&self, vec: &mut Vec, ctx: &ToViperContext<'vir, 'v>) { self.to_viper_extend(vec, ctx, ctx.ast.no_position()); } - fn to_viper_vec_no_pos(&self, ctx: &ToViperContext<'vir, 'v>) -> Vec { - self.to_viper_vec(ctx, ctx.ast.no_position()) - } + //fn to_viper_vec_no_pos(&self, ctx: &ToViperContext<'vir, 'v>) -> Vec { + // self.to_viper_vec(ctx, ctx.ast.no_position()) + //} } impl<'vir, 'v> ToViper<'vir, 'v> for vir::AccField<'vir> { @@ -146,7 +164,9 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::AccField<'vir> { self.field.to_viper_no_pos(ctx), pos, ), - self.perm.map(|v| v.to_viper_no_pos(ctx)).unwrap_or_else(|| ctx.ast.full_perm()), + self.perm + .map(|v| v.to_viper_no_pos(ctx)) + .unwrap_or_else(|| ctx.ast.full_perm()), pos, ) } @@ -182,7 +202,12 @@ impl<'vir, 'v> ToViperVec<'vir, 'v> for vir::CfgBlock<'vir> { fn size_hint(&self) -> Option { Some(1 + self.stmts.len() + self.terminator.size_hint().unwrap_or(1)) } - fn to_viper_extend(&self, vec: &mut Vec, ctx: &ToViperContext<'vir, 'v>, _pos: Position) { + fn to_viper_extend( + &self, + vec: &mut Vec, + ctx: &ToViperContext<'vir, 'v>, + _pos: Position, + ) { vec.push(self.label.to_viper_no_pos(ctx)); // TODO: pass own position to label? vec.extend(self.stmts.iter().map(|v| v.to_viper_no_pos(ctx))); self.terminator.to_viper_extend_no_pos(vec, ctx); @@ -208,7 +233,9 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Const<'vir> { match self { vir::ConstData::Bool(true) => ctx.ast.true_lit_with_pos(pos), vir::ConstData::Bool(false) => ctx.ast.false_lit_with_pos(pos), - vir::ConstData::Int(v) if *v < (i64::MAX as u128) => ctx.ast.int_lit_with_pos(*v as i64, pos), + vir::ConstData::Int(v) if *v < (i64::MAX as u128) => { + ctx.ast.int_lit_with_pos(*v as i64, pos) + } vir::ConstData::Int(v) => ctx.ast.int_lit_from_ref_with_pos(v, pos), vir::ConstData::Wildcard => ctx.ast.wildcard_perm(), vir::ConstData::Null => ctx.ast.null_lit_with_pos(pos), @@ -221,9 +248,21 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Domain<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { ctx.ast.domain( self.name, - &self.functions.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.axioms.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.typarams.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .functions + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .axioms + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .typarams + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), ) } } @@ -231,25 +270,33 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Domain<'vir> { impl<'vir, 'v> ToViper<'vir, 'v> for vir::DomainAxiom<'vir> { type Output = viper::NamedDomainAxiom<'v>; fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { - let (domain, _) = ctx.domain_axioms.get(self.name).expect("no domain for domain axiom"); - ctx.ast.named_domain_axiom( - self.name, - self.expr.to_viper_no_pos(ctx), - domain.name, - ) + let (domain, _) = ctx + .domain_axioms + .get(self.name) + .expect("no domain for domain axiom"); + ctx.ast + .named_domain_axiom(self.name, self.expr.to_viper_no_pos(ctx), domain.name) } } impl<'vir, 'v> ToViper<'vir, 'v> for vir::DomainFunction<'vir> { type Output = viper::DomainFunc<'v>; fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { - let (domain, _) = ctx.domain_functions.get(self.name.to_str()).expect("no domain for domain function"); + let (domain, _) = ctx + .domain_functions + .get(self.name.to_str()) + .expect("no domain for domain function"); ctx.ast.domain_func( self.name.to_str(), - &self.args.iter().enumerate().map(|(idx, v)| ctx.ast.local_var_decl( - &format!("arg{idx}"), - v.to_viper_no_pos(ctx), - )).collect::>(), + &self + .args + .iter() + .enumerate() + .map(|(idx, v)| { + ctx.ast + .local_var_decl(&format!("arg{idx}"), v.to_viper_no_pos(ctx)) + }) + .collect::>(), self.ret.to_viper_no_pos(ctx), self.unique, domain.name, @@ -282,17 +329,15 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Expr<'vir> { vir::ExprKindData::Local(v) => v.to_viper_with_span(ctx, self.span), vir::ExprKindData::Old(v) => ctx.ast.old(v.to_viper_no_pos(ctx)), // TODO: position vir::ExprKindData::PredicateApp(v) => v.to_viper_with_span(ctx, self.span), - vir::ExprKindData::Result(ty) => ctx.ast.result_with_pos( - ty.to_viper_no_pos(ctx), - ctx.span_to_pos(self.span), - ), + vir::ExprKindData::Result(ty) => ctx + .ast + .result_with_pos(ty.to_viper_no_pos(ctx), ctx.span_to_pos(self.span)), vir::ExprKindData::Ternary(v) => v.to_viper_with_span(ctx, self.span), vir::ExprKindData::Unfolding(v) => v.to_viper_with_span(ctx, self.span), vir::ExprKindData::UnOp(v) => v.to_viper_with_span(ctx, self.span), //vir::ExprKindData::Lazy(&'vir str, Box Fn(&'vir crate::VirCtxt<'a>, Curr) -> Next + 'vir>), //vir::ExprKindData::Todo(&'vir str) => unreachable!(), - _ => unimplemented!(), } } @@ -301,10 +346,7 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Expr<'vir> { impl<'vir, 'v> ToViper<'vir, 'v> for vir::Field<'vir> { type Output = viper::Field<'v>; fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { - ctx.ast.field( - self.name, - self.ty.to_viper_no_pos(ctx), - ) + ctx.ast.field(self.name, self.ty.to_viper_no_pos(ctx)) } } @@ -313,8 +355,16 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Forall<'vir> { // `pos` coming from the parent `Expr` is used fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, pos: Position) -> Self::Output { ctx.ast.forall_with_pos( - &self.qvars.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.triggers.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .qvars + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .triggers + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), self.body.to_viper_no_pos(ctx), pos, ) @@ -328,7 +378,11 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::FuncApp<'vir> { if let Some((domain, _)) = ctx.domain_functions.get(self.target) { ctx.ast.domain_func_app2( self.target, - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), &[], self.result_ty.to_viper_no_pos(ctx), domain.name, @@ -337,7 +391,11 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::FuncApp<'vir> { } else { ctx.ast.func_app( self.target, - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), self.result_ty.to_viper_no_pos(ctx), pos, ) @@ -350,10 +408,22 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Function<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { ctx.ast.function( self.name, - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), self.ret.to_viper_no_pos(ctx), - &self.pres.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.posts.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .pres + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .posts + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), ctx.ast.no_position(), // TODO: position (each function should have its own) self.expr.map(|v| v.to_viper_no_pos(ctx)), ) @@ -371,36 +441,44 @@ impl<'vir, 'v> ToViperVec<'vir, 'v> for vir::GotoIf<'vir> { } // `pos` coming from the parent `Stmt` should be used, but the nodes // created her cannot be created with positions - fn to_viper_extend(&self, vec: &mut Vec, ctx: &ToViperContext<'vir, 'v>, _pos: Position) { + fn to_viper_extend( + &self, + vec: &mut Vec, + ctx: &ToViperContext<'vir, 'v>, + _pos: Position, + ) { if self.targets.is_empty() { - self.otherwise_statements.iter() + self.otherwise_statements + .iter() .for_each(|v| vec.push(v.to_viper_no_pos(ctx))); vec.push(ctx.ast.goto(&self.otherwise.name())); return; } let value = self.value.to_viper_no_pos(ctx); - vec.push(self.targets.iter() - .rfold({ + vec.push(self.targets.iter().rfold( + { let mut vec_otherwise = Vec::with_capacity(1 + self.otherwise_statements.len()); - self.otherwise_statements.iter() + self.otherwise_statements + .iter() .for_each(|v| vec_otherwise.push(v.to_viper_no_pos(ctx))); vec_otherwise.push(ctx.ast.goto(&self.otherwise.name())); ctx.ast.seqn(&vec_otherwise, &[]) - }, |else_, target| { + }, + |else_, target| { let mut vec_then = Vec::with_capacity(1 + target.statements.len()); - target.statements.iter() + target + .statements + .iter() .for_each(|v| vec_then.push(v.to_viper_no_pos(ctx))); vec_then.push(ctx.ast.goto(&target.label.name())); let stmt = ctx.ast.if_stmt( - ctx.ast.eq_cmp( - value, - target.value.to_viper_no_pos(ctx), - ), + ctx.ast.eq_cmp(value, target.value.to_viper_no_pos(ctx)), ctx.ast.seqn(&vec_then, &[]), else_, ); ctx.ast.seqn(&[stmt], &[]) - })) + }, + )) } } @@ -409,10 +487,8 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Let<'vir> { // `pos` coming from the parent `Expr` is used fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, pos: Position) -> Self::Output { ctx.ast.let_expr_with_pos( - ctx.ast.local_var_decl( - self.name, - self.val.ty().to_viper_no_pos(ctx), - ), + ctx.ast + .local_var_decl(self.name, self.val.ty().to_viper_no_pos(ctx)), self.val.to_viper_no_pos(ctx), self.expr.to_viper_no_pos(ctx), pos, @@ -424,21 +500,16 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::LocalData<'vir> { type Output = viper::Expr<'v>; // `pos` coming from the parent `Expr` is used fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, pos: Position) -> Self::Output { - ctx.ast.local_var( - self.name, - self.ty.to_viper_no_pos(ctx), - pos, - ) + ctx.ast + .local_var(self.name, self.ty.to_viper_no_pos(ctx), pos) } } impl<'vir, 'v> ToViper<'vir, 'v> for vir::LocalDeclData<'vir> { type Output = viper::LocalVarDecl<'v>; fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { - ctx.ast.local_var_decl( - self.name, - self.ty.to_viper_no_pos(ctx), - ) + ctx.ast + .local_var_decl(self.name, self.ty.to_viper_no_pos(ctx)) } } @@ -447,10 +518,26 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Method<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { ctx.ast.method( self.name, - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.rets.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.pres.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.posts.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .rets + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .pres + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .posts + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), self.body.map(|body| { let size_hint = body.blocks.iter().flat_map(|b| b.size_hint()).sum(); let mut result = if size_hint > 0 { @@ -458,24 +545,18 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Method<'vir> { } else { Vec::new() }; - let mut declarations: Vec = Vec::with_capacity(1 + body.blocks.len()); - body.blocks.iter() - .for_each(|b| { - declarations.push(ctx.ast.label( - &b.label.name(), - &[], - ).into()); - b.stmts.iter() - .for_each(|s| match s.kind { - vir::StmtKindGenData::LocalDecl(decl, _) => declarations.push(decl.to_viper_no_pos(ctx).into()), - _ => (), - }); - b.to_viper_extend_no_pos(&mut result, ctx); + let mut declarations: Vec = + Vec::with_capacity(1 + body.blocks.len()); + body.blocks.iter().for_each(|b| { + declarations.push(ctx.ast.label(&b.label.name(), &[]).into()); + b.stmts.iter().for_each(|s| { + if let vir::StmtKindGenData::LocalDecl(decl, _) = s.kind { + declarations.push(decl.to_viper_no_pos(ctx).into()); + } }); - ctx.ast.seqn( - &result, - &declarations, - ) + b.to_viper_extend_no_pos(&mut result, ctx); + }); + ctx.ast.seqn(&result, &declarations) }), ) } @@ -487,8 +568,16 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::MethodCall<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, pos: Position) -> Self::Output { ctx.ast.method_call_with_pos( self.method, - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), - &self.targets.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .targets + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), pos, ) } @@ -500,11 +589,17 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::PredicateApp<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, pos: Position) -> Self::Output { ctx.ast.predicate_access_predicate_with_pos( ctx.ast.predicate_access_with_pos( - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), self.target, pos, ), - self.perm.map(|v| v.to_viper_no_pos(ctx)).unwrap_or_else(|| ctx.ast.full_perm()), + self.perm + .map(|v| v.to_viper_no_pos(ctx)) + .unwrap_or_else(|| ctx.ast.full_perm()), pos, ) } @@ -515,7 +610,11 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Predicate<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { ctx.ast.predicate( self.name, - &self.args.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .args + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), self.expr.map(|v| v.to_viper_no_pos(ctx)), ) } @@ -525,11 +624,31 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Program<'vir> { type Output = viper::Program<'v>; fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { ctx.ast.program( - &self.domains.iter().map(|v| v.to_viper_no_pos(&ctx)).collect::>(), - &self.fields.iter().map(|v| v.to_viper_no_pos(&ctx)).collect::>(), - &self.functions.iter().map(|v| v.to_viper_no_pos(&ctx)).collect::>(), - &self.predicates.iter().map(|v| v.to_viper_no_pos(&ctx)).collect::>(), - &self.methods.iter().map(|v| v.to_viper_no_pos(&ctx)).collect::>(), + &self + .domains + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .fields + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .functions + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .predicates + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), + &self + .methods + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), ) } } @@ -550,18 +669,15 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Stmt<'vir> { fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { match self.kind { vir::StmtKindGenData::Comment(v) => ctx.ast.comment(v), - vir::StmtKindGenData::Exhale(v) => ctx.ast.exhale( - v.to_viper_no_pos(ctx), - ctx.span_to_pos(self.span), - ), - vir::StmtKindGenData::Fold(pred) => ctx.ast.fold_with_pos( - pred.to_viper_no_pos(ctx), - ctx.span_to_pos(self.span), - ), - vir::StmtKindGenData::Inhale(v) => ctx.ast.inhale( - v.to_viper_no_pos(ctx), - ctx.span_to_pos(self.span), - ), + vir::StmtKindGenData::Exhale(v) => ctx + .ast + .exhale(v.to_viper_no_pos(ctx), ctx.span_to_pos(self.span)), + vir::StmtKindGenData::Fold(pred) => ctx + .ast + .fold_with_pos(pred.to_viper_no_pos(ctx), ctx.span_to_pos(self.span)), + vir::StmtKindGenData::Inhale(v) => ctx + .ast + .inhale(v.to_viper_no_pos(ctx), ctx.span_to_pos(self.span)), vir::StmtKindGenData::LocalDecl(decl, Some(expr)) => ctx.ast.local_var_assign( ctx.ast.local_var_with_pos( decl.name, @@ -571,13 +687,14 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Stmt<'vir> { expr.to_viper_no_pos(ctx), // TODO: position? ), - vir::StmtKindGenData::LocalDecl(decl, None) => ctx.ast.comment(&format!("var {}", decl.name)), + vir::StmtKindGenData::LocalDecl(decl, None) => { + ctx.ast.comment(&format!("var {}", decl.name)) + } vir::StmtKindGenData::MethodCall(v) => v.to_viper_with_span(ctx, self.span), vir::StmtKindGenData::PureAssign(v) => v.to_viper_with_span(ctx, self.span), - vir::StmtKindGenData::Unfold(pred) => ctx.ast.unfold_with_pos( - pred.to_viper_no_pos(ctx), - ctx.span_to_pos(self.span), - ), + vir::StmtKindGenData::Unfold(pred) => ctx + .ast + .unfold_with_pos(pred.to_viper_no_pos(ctx), ctx.span_to_pos(self.span)), //vir::StmtGenData::Dummy(#[reify_copy] &'vir str), _ => unimplemented!(), } @@ -594,22 +711,23 @@ impl<'vir, 'v> ToViperVec<'vir, 'v> for vir::TerminatorStmt<'vir> { } } // `pos` coming from the parent `TerminatorStmt` is used - fn to_viper_extend(&self, vec: &mut Vec, ctx: &ToViperContext<'vir, 'v>, pos: Position) { + fn to_viper_extend( + &self, + vec: &mut Vec, + ctx: &ToViperContext<'vir, 'v>, + pos: Position, + ) { match self { - vir::TerminatorStmtGenData::AssumeFalse => vec.push(ctx.ast.inhale( - ctx.ast.false_lit_with_pos(pos), - pos, - )), + vir::TerminatorStmtGenData::AssumeFalse => { + vec.push(ctx.ast.inhale(ctx.ast.false_lit_with_pos(pos), pos)) + } vir::TerminatorStmtGenData::Goto(label) => vec.push(ctx.ast.goto(&label.name())), vir::TerminatorStmtGenData::GotoIf(v) => v.to_viper_extend_no_pos(vec, ctx), vir::TerminatorStmtGenData::Exit => vec.push(ctx.ast.comment("return")), vir::TerminatorStmtGenData::Dummy(v) => vec.push(ctx.ast.seqn( &[ ctx.ast.comment(v), - ctx.ast.assert( - ctx.ast.false_lit_with_pos(pos), - pos, - ), + ctx.ast.assert(ctx.ast.false_lit_with_pos(pos), pos), ], &[], )), @@ -634,7 +752,11 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Trigger<'vir> { type Output = viper::Trigger<'v>; fn to_viper(&self, ctx: &ToViperContext<'vir, 'v>, _pos: Position) -> Self::Output { ctx.ast.trigger( - &self.exprs.iter().map(|v| v.to_viper_no_pos(ctx)).collect::>(), + &self + .exprs + .iter() + .map(|v| v.to_viper_no_pos(ctx)) + .collect::>(), // TODO: position (each trigger should have its own) ) } @@ -648,14 +770,26 @@ impl<'vir, 'v> ToViper<'vir, 'v> for vir::Type<'vir> { vir::TypeData::Bool => ctx.ast.bool_type(), vir::TypeData::DomainTypeParam(param) => ctx.ast.type_var(param.name), vir::TypeData::Domain(name, params) => { - let domain = ctx.domains.get(name).unwrap_or_else(|| panic!("Domain {name} not found")); + let domain = ctx + .domains + .get(name) + .unwrap_or_else(|| panic!("Domain {name} not found")); ctx.ast.domain_type( name, - &domain.typarams.iter() + &domain + .typarams + .iter() .zip(params.iter()) - .map(|(domain_param, actual)| (ctx.ast.type_var(domain_param.name), actual.to_viper_no_pos(ctx))) + .map(|(domain_param, actual)| { + ( + ctx.ast.type_var(domain_param.name), + actual.to_viper_no_pos(ctx), + ) + }) .collect::>(), - &domain.typarams.iter() + &domain + .typarams + .iter() .map(|v| ctx.ast.type_var(v.name)) .collect::>(), ) diff --git a/prusti/build.rs b/prusti/build.rs index 0f64555d221..d67cc3dcb3f 100644 --- a/prusti/build.rs +++ b/prusti/build.rs @@ -24,7 +24,8 @@ fn main() { { if let Ok(timestamp) = commit_timestamp.trim().parse() { let commit_naive_datetime = NaiveDateTime::from_timestamp_opt(timestamp, 0).unwrap(); - let commit_time = DateTime::::from_utc(commit_naive_datetime, Utc); + let commit_time = + DateTime::::from_naive_utc_and_offset(commit_naive_datetime, Utc); println!( "cargo:rustc-env=COMMIT_TIME={}", commit_time.format("%F %T %Z") diff --git a/prusti/src/callbacks.rs b/prusti/src/callbacks.rs index 9ab918c925d..af1c0af169c 100644 --- a/prusti/src/callbacks.rs +++ b/prusti/src/callbacks.rs @@ -1,6 +1,4 @@ use crate::verifier::verify; -use mir_state_analysis::test_free_pcs; -use prusti_utils::config; use prusti_interface::{ environment::{mir_storage, Environment}, specs::{self, cross_crate::CrossCrateSpecs, is_spec_fn}, @@ -9,21 +7,16 @@ use prusti_rustc_interface::{ borrowck::consumers, data_structures::steal::Steal, driver::Compilation, + hir::{def::DefKind, def_id::LocalDefId}, index::IndexVec, interface::{interface::Compiler, Config, Queries}, - hir::{def::DefKind, def_id::LocalDefId}, middle::{ - mir, - query::{ - queries::mir_borrowck::ProvidedValue as MirBorrowck, - ExternProviders, - - }, + mir, query::queries::mir_borrowck::ProvidedValue as MirBorrowck, ty::TyCtxt, util::Providers, - ty::TyCtxt, }, - session::{EarlyDiagCtxt, Session}, + session::Session, }; +use prusti_utils::config; #[derive(Default)] pub struct PrustiCompilerCalls; @@ -82,16 +75,13 @@ struct NoAnn; impl prusti_rustc_interface::ast_pretty::pprust::PpAnn for NoAnn {} - impl prusti_rustc_interface::driver::Callbacks for PrustiCompilerCalls { fn config(&mut self, config: &mut Config) { assert!(config.override_queries.is_none()); - config.override_queries = Some( - |_session: &Session, providers: &mut Providers| { - providers.mir_borrowck = mir_borrowck; - providers.mir_promoted = mir_promoted; - }, - ); + config.override_queries = Some(|_session: &Session, providers: &mut Providers| { + providers.mir_borrowck = mir_borrowck; + providers.mir_promoted = mir_promoted; + }); } #[tracing::instrument(level = "debug", skip_all)] fn after_expansion<'tcx>( @@ -101,7 +91,8 @@ impl prusti_rustc_interface::driver::Callbacks for PrustiCompilerCalls { ) -> Compilation { if compiler.sess.is_rust_2015() { compiler - .sess.dcx() + .sess + .dcx() .struct_warn( "Prusti specifications are supported only from 2018 edition. Please \ specify the edition with adding a command line argument `--edition=2018` or \ @@ -179,7 +170,7 @@ impl prusti_rustc_interface::driver::Callbacks for PrustiCompilerCalls { test_free_pcs(&mir, tcx); } } else {*/ - verify(env, def_spec); + verify(env, def_spec); //} } }); diff --git a/prusti/src/driver.rs b/prusti/src/driver.rs index bb7ab987936..d44857b6c35 100644 --- a/prusti/src/driver.rs +++ b/prusti/src/driver.rs @@ -7,6 +7,7 @@ #![feature(rustc_private)] #![feature(proc_macro_internals)] #![feature(decl_macro)] +#![allow(internal_features)] #![deny(unused_must_use)] mod arg_value; @@ -16,11 +17,11 @@ mod verifier; use arg_value::arg_value; use callbacks::PrustiCompilerCalls; use log::info; -use prusti_utils::{config, report::user, Stopwatch}; use prusti_rustc_interface::{ - driver, errors, + driver, session::{self, EarlyDiagCtxt}, }; +use prusti_utils::{config, report::user, Stopwatch}; use std::env; use tracing_chrome::{ChromeLayerBuilder, FlushGuard}; use tracing_subscriber::{filter::EnvFilter, prelude::*}; @@ -72,7 +73,9 @@ fn init_loggers() -> Option { fn main() { driver::install_ice_hook(BUG_REPORT_URL, |handler| { let version_info = get_prusti_version_info(); - handler.handle().note(format!("Prusti version: {version_info}")); + handler + .handle() + .note(format!("Prusti version: {version_info}")); }); // To measure how long Prusti takes to run diff --git a/prusti/src/verifier.rs b/prusti/src/verifier.rs index 11059f09c4c..aaa37243aba 100644 --- a/prusti/src/verifier.rs +++ b/prusti/src/verifier.rs @@ -1,13 +1,8 @@ //! A module that invokes the verifier `prusti-viper` use log::{debug, warn}; +use prusti_interface::{data::VerificationTask, environment::Environment, specs::typed}; use prusti_utils::{config, report::user}; -use prusti_interface::{ - data::{VerificationResult, VerificationTask}, - environment::Environment, - specs::typed, -}; -use prusti_rustc_interface::errors::MultiSpan; #[tracing::instrument(name = "prusti::verify", level = "debug", skip(env))] pub fn verify(env: Environment<'_>, def_spec: typed::DefSpecificationMap) { @@ -46,48 +41,33 @@ pub fn verify(env: Environment<'_>, def_spec: typed::DefSpecificationMap) { // encode the crate to a RequestWithContext // TODO: push RequestWithContext through (replace VerificationRequest // which is constructed further inside `prusti_server`) - let request = prusti_encoder::test_entrypoint( - env.tcx(), - env.body, - def_spec, - ); + let request = prusti_encoder::test_entrypoint(env.tcx(), env.body, def_spec); let program = request.program; let mut results = prusti_server::verify_programs(vec![program]); assert_eq!(results.len(), 1); // TODO: eventually verify separate methods as separate programs again? let result = results.pop().unwrap().1; - println!("verification result: {result:?}"); - - let success = match result { + let _success = match result { viper::VerificationResult::Success => true, viper::VerificationResult::JavaException(_e) => false, viper::VerificationResult::ConsistencyErrors(_e) => false, viper::VerificationResult::Failure(errors) => { errors .into_iter() - .flat_map(|error| prusti_encoder::backtranslate_error( + .flat_map(|error| { + prusti_encoder::backtranslate_error( &error.full_id, error.offending_pos_id.unwrap().parse::().unwrap(), error.reason_pos_id.and_then(|id| id.parse::().ok()), ) .expect("verification error could not be backtranslated") - .into_iter()) + .into_iter() + }) .for_each(|prusti_error| prusti_error.emit(&env.diagnostic)); false } }; - if !success { - // TODO: This will be unnecessary if diagnostic errors are emitted - // earlier, it's useful for now to ensure that Prusti returns an - // error code when verification fails - env.diagnostic.span_err_with_help_and_notes( - MultiSpan::new(), - "Verification failed", - &None, - &[], - ); - } //let verification_result = // if verification_task.procedures.is_empty() && verification_task.types.is_empty() { diff --git a/task-encoder/src/lib.rs b/task-encoder/src/lib.rs index 1e39303851c..3e9a3c5a3b5 100644 --- a/task-encoder/src/lib.rs +++ b/task-encoder/src/lib.rs @@ -8,7 +8,6 @@ impl OutputRefAny for () {} pub enum TaskEncoderCacheState<'vir, E: TaskEncoder + 'vir + ?Sized> { // None, // indicated by absence in the cache - /// Task was enqueued but not yet started. Enqueued, @@ -29,9 +28,7 @@ pub enum TaskEncoderCacheState<'vir, E: TaskEncoder + 'vir + ?Sized> { }, /// An error occurred when enqueing the task. - ErrorEnqueue { - error: TaskEncoderError, - }, + ErrorEnqueue { error: TaskEncoderError }, /// An error occurred when encoding the task. The full "local" encoding is /// not available. However, tasks which depend on this task may still @@ -49,16 +46,12 @@ pub enum TaskEncoderCacheState<'vir, E: TaskEncoder + 'vir + ?Sized> { /// Cache for a task encoder. See `TaskEncoderCacheState` for a description of /// the possible values in the encoding process. -pub type Cache<'vir, E> = LinkedHashMap< - ::TaskKey<'vir>, - TaskEncoderCacheState<'vir, E>, ->; +pub type Cache<'vir, E> = + LinkedHashMap<::TaskKey<'vir>, TaskEncoderCacheState<'vir, E>>; pub type CacheRef<'vir, E> = RefCell>; -pub type CacheStatic = LinkedHashMap< - ::TaskKey<'static>, - TaskEncoderCacheState<'static, E>, ->; +pub type CacheStatic = + LinkedHashMap<::TaskKey<'static>, TaskEncoderCacheState<'static, E>>; pub type CacheStaticRef = RefCell>; /* pub struct TaskEncoderOutput<'vir, E: TaskEncoder>( @@ -78,11 +71,24 @@ impl<'vir, E: TaskEncoder> TaskEncoderOutput<'vir, E> { } */ +/// The result of an `encode` call. +pub type EncodeResult<'vir, E /*: TaskEncoder + 'vir + ?Sized*/> = Result< + Option<( + ::OutputRef<'vir>, + ::OutputFullLocal<'vir>, + ::OutputFullDependency<'vir>, + )>, + TaskEncoderError, +>; + /// The result of the actual encoder implementation (`do_encode_full`). -pub type EncodeFullResult<'vir, E: TaskEncoder + 'vir + ?Sized> = Result<( - E::OutputFullLocal<'vir>, - E::OutputFullDependency<'vir>, -), EncodeFullError<'vir, E>>; +pub type EncodeFullResult<'vir, E /*: TaskEncoder + 'vir + ?Sized*/> = Result< + ( + ::OutputFullLocal<'vir>, + ::OutputFullDependency<'vir>, + ), + EncodeFullError<'vir, E>, +>; /// An unsuccessful result occurring in `do_encode_full`. pub enum EncodeFullError<'vir, E: TaskEncoder + 'vir + ?Sized> { @@ -97,7 +103,10 @@ pub enum EncodeFullError<'vir, E: TaskEncoder + 'vir + ?Sized> { AlreadyEncoded, /// An actual error occurred during encoding. - EncodingError(::EncodingError, Option>), + EncodingError( + ::EncodingError, + Option>, + ), DependencyError, } @@ -108,7 +117,10 @@ impl<'vir, E: TaskEncoder + 'vir + ?Sized> std::fmt::Debug for EncodeFullError<' fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::AlreadyEncoded => write!(f, "AlreadyEncoded"), - Self::EncodingError(err, _output_dep) => f.debug_tuple("EncodingError").field(err)/*.field(output_dep)*/.finish(), + Self::EncodingError(err, _output_dep) => f + .debug_tuple("EncodingError") + .field(err) /*.field(output_dep)*/ + .finish(), Self::DependencyError => write!(f, "DependencyError"), } } @@ -122,7 +134,8 @@ pub enum TaskEncoderError { } impl std::fmt::Debug for TaskEncoderError - where ::EncodingError: std::fmt::Debug +where + ::EncodingError: std::fmt::Debug, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut helper = f.debug_struct("TaskEncoderError"); @@ -155,12 +168,16 @@ pub struct TaskEncoderDependencies<'vir, E: TaskEncoder + 'vir + ?Sized> { impl<'vir, E: TaskEncoder + 'vir + ?Sized> TaskEncoderDependencies<'vir, E> { fn check_cycle(&self) -> Result<(), EncodeFullError<'vir, E>> { if let Some(task_key) = self.task_key.as_ref() { - if E::with_cache(move |cache| matches!( - cache.borrow().get(task_key), - Some(TaskEncoderCacheState::Encoded { .. } - | TaskEncoderCacheState::ErrorEncode { .. } - | TaskEncoderCacheState::ErrorEnqueue { .. }), - )) { + if E::with_cache(move |cache| { + matches!( + cache.borrow().get(task_key), + Some( + TaskEncoderCacheState::Encoded { .. } + | TaskEncoderCacheState::ErrorEncode { .. } + | TaskEncoderCacheState::ErrorEnqueue { .. } + ), + ) + }) { return Err(EncodeFullError::AlreadyEncoded); } } @@ -170,10 +187,7 @@ impl<'vir, E: TaskEncoder + 'vir + ?Sized> TaskEncoderDependencies<'vir, E> { pub fn require_ref( &mut self, task: ::TaskDescription<'vir>, - ) -> Result< - ::OutputRef<'vir>, - EncodeFullError<'vir, E>, - > { + ) -> Result<::OutputRef<'vir>, EncodeFullError<'vir, E>> { EOther::encode_ref(task) .map_err(|_| EncodeFullError::DependencyError) .and_then(|result| { @@ -185,10 +199,7 @@ impl<'vir, E: TaskEncoder + 'vir + ?Sized> TaskEncoderDependencies<'vir, E> { pub fn require_local( &mut self, task: ::TaskDescription<'vir>, - ) -> Result< - ::OutputFullLocal<'vir>, - EncodeFullError<'vir, E>, - > { + ) -> Result<::OutputFullLocal<'vir>, EncodeFullError<'vir, E>> { EOther::encode(task, true) .map(Option::unwrap) .map(|(_output_ref, output_local, _output_dep)| output_local) @@ -202,10 +213,7 @@ impl<'vir, E: TaskEncoder + 'vir + ?Sized> TaskEncoderDependencies<'vir, E> { pub fn require_dep( &mut self, task: ::TaskDescription<'vir>, - ) -> Result< - ::OutputFullDependency<'vir>, - EncodeFullError<'vir, E>, - > { + ) -> Result<::OutputFullDependency<'vir>, EncodeFullError<'vir, E>> { EOther::encode(task, true) .map(Option::unwrap) .map(|(_output_ref, _output_local, output_dep)| output_dep) @@ -221,13 +229,17 @@ impl<'vir, E: TaskEncoder + 'vir + ?Sized> TaskEncoderDependencies<'vir, E> { task_key: E::TaskKey<'vir>, output_ref: E::OutputRef<'vir>, ) -> Result<(), EncodeFullError<'vir, E>> { - assert!(self.task_key.replace(task_key.clone()).is_none(), "output ref already set for task key {task_key:?}"); + assert!( + self.task_key.replace(task_key.clone()).is_none(), + "output ref already set for task key {task_key:?}" + ); self.check_cycle()?; - assert!(E::with_cache(move |cache| matches!(cache.borrow_mut().insert( - task_key, - TaskEncoderCacheState::Started { output_ref }, - ), Some(TaskEncoderCacheState::Enqueued - | TaskEncoderCacheState::Started { .. })))); + assert!(E::with_cache(move |cache| matches!( + cache + .borrow_mut() + .insert(task_key, TaskEncoderCacheState::Started { output_ref },), + Some(TaskEncoderCacheState::Enqueued | TaskEncoderCacheState::Started { .. }) + ))); Ok(()) } } @@ -241,7 +253,8 @@ pub trait TaskEncoder { /// for example if the description should be normalised or some non-trivial /// resolution needs to happen. In other words, multiple descriptions may /// lead to the same key and hence the same output. - type TaskKey<'vir>: std::hash::Hash + Eq + Clone + std::fmt::Debug = Self::TaskDescription<'vir>; + type TaskKey<'vir>: std::hash::Hash + Eq + Clone + std::fmt::Debug = + Self::TaskDescription<'vir>; /// A reference to an encoded item. Should be non-unit for tasks which can /// be "referred" to from other parts of a program, as opposed to tasks @@ -253,7 +266,8 @@ pub trait TaskEncoder { /// dependencies (such as methods), this output should only be emitted in /// one Viper program. type OutputFullLocal<'vir>: Clone - where Self: 'vir; + where + Self: 'vir; /// Fully encoded output for this task for dependents. When encoding items /// which can be dependencies (such as methods), this output should be @@ -267,7 +281,9 @@ pub trait TaskEncoder { /// Enters the given function with a reference to the cache for this /// encoder. fn with_cache<'vir, F, R>(f: F) -> R - where Self: 'vir, F: FnOnce(&'vir CacheRef<'vir, Self>) -> R; + where + Self: 'vir, + F: FnOnce(&'vir CacheRef<'vir, Self>) -> R; //fn get_all_outputs() -> Self::CacheRef<'vir> { // todo!() @@ -276,7 +292,8 @@ pub trait TaskEncoder { //} fn enqueue<'vir>(task: Self::TaskDescription<'vir>) - where Self: 'vir + where + Self: 'vir, { let task_key = Self::task_to_key(&task); let task_key_clone = task_key.clone(); // TODO: remove? @@ -286,28 +303,32 @@ pub trait TaskEncoder { } // enqueue, expecting no entry (we just checked) - assert!(Self::with_cache(move |cache| cache.borrow_mut().insert( - task_key, - TaskEncoderCacheState::Enqueued, - ).is_none())); + assert!(Self::with_cache(move |cache| cache + .borrow_mut() + .insert(task_key, TaskEncoderCacheState::Enqueued,) + .is_none())); } - fn encode_ref<'vir>(task: Self::TaskDescription<'vir>) -> Result< - Self::OutputRef<'vir>, - TaskEncoderError, - > - where Self: 'vir + fn encode_ref<'vir>( + task: Self::TaskDescription<'vir>, + ) -> Result, TaskEncoderError> + where + Self: 'vir, { let task_key = Self::task_to_key(&task); // is there an output ref available already? let task_key_clone = task_key.clone(); - if let Some(output_ref) = Self::with_cache(move |cache| match cache.borrow().get(&task_key_clone) { - Some(TaskEncoderCacheState::Started { output_ref, .. }) - | Some(TaskEncoderCacheState::Encoded { output_ref, .. }) - | Some(TaskEncoderCacheState::ErrorEncode { output_ref, .. }) => Some(output_ref.clone()), - _ => None, - }) { + if let Some(output_ref) = + Self::with_cache(move |cache| match cache.borrow().get(&task_key_clone) { + Some(TaskEncoderCacheState::Started { output_ref, .. }) + | Some(TaskEncoderCacheState::Encoded { output_ref, .. }) + | Some(TaskEncoderCacheState::ErrorEncode { output_ref, .. }) => { + Some(output_ref.clone()) + } + _ => None, + }) + { return Ok(output_ref); } @@ -320,24 +341,28 @@ pub trait TaskEncoder { Self::encode(task, false)?; let task_key_clone = task_key.clone(); - if let Some(output_ref) = Self::with_cache(move |cache| match cache.borrow().get(&task_key_clone) { - Some(TaskEncoderCacheState::Started { output_ref, .. }) - | Some(TaskEncoderCacheState::Encoded { output_ref, .. }) - | Some(TaskEncoderCacheState::ErrorEncode { output_ref, .. }) => Some(output_ref.clone()), - _ => None, - }) { + if let Some(output_ref) = + Self::with_cache(move |cache| match cache.borrow().get(&task_key_clone) { + Some(TaskEncoderCacheState::Started { output_ref, .. }) + | Some(TaskEncoderCacheState::Encoded { output_ref, .. }) + | Some(TaskEncoderCacheState::ErrorEncode { output_ref, .. }) => { + Some(output_ref.clone()) + } + _ => None, + }) + { return Ok(output_ref); } panic!("output ref not found after encoding") // TODO: error? } - fn encode<'vir>(task: Self::TaskDescription<'vir>, need_output: bool) -> Result, - Self::OutputFullLocal<'vir>, - Self::OutputFullDependency<'vir>, - )>, TaskEncoderError> - where Self: 'vir + fn encode<'vir>( + task: Self::TaskDescription<'vir>, + need_output: bool, + ) -> EncodeResult<'vir, Self> + where + Self: 'vir, { let task_key = Self::task_to_key(&task); @@ -353,14 +378,16 @@ pub trait TaskEncoder { output_local, output_dep, .. - } => if need_output { - Some(Ok(Some(( - output_ref.clone(), - output_local.clone(), - output_dep.clone(), - )))) - } else { - Some(Ok(None)) + } => { + if need_output { + Some(Ok(Some(( + output_ref.clone(), + output_local.clone(), + output_dep.clone(), + )))) + } else { + Some(Ok(None)) + } } // TODO: should we return Some(Ok(None)) for `Started`, if `!need_output` ? TaskEncoderCacheState::Enqueued | TaskEncoderCacheState::Started { .. } => None, @@ -385,198 +412,217 @@ pub trait TaskEncoder { let encode_result = Self::do_encode_full(&task_key, &mut deps); let output_ref = Self::with_cache(|cache| match cache.borrow().get(&task_key) { - Some(TaskEncoderCacheState::Started { output_ref } - | TaskEncoderCacheState::Encoded { output_ref, .. }) => output_ref.clone(), + Some( + TaskEncoderCacheState::Started { output_ref } + | TaskEncoderCacheState::Encoded { output_ref, .. }, + ) => output_ref.clone(), _ => panic!("encoder did not provide output ref for task {task_key:?}"), }); match encode_result { Ok((output_local, output_dep)) => { if need_output { - Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::Encoded { - output_ref: output_ref.clone(), - deps, - output_local: output_local.clone(), - output_dep: output_dep.clone(), - })); - Ok(Some(( - output_ref, - output_local, - output_dep, - ))) + Self::with_cache(|cache| { + cache.borrow_mut().insert( + task_key, + TaskEncoderCacheState::Encoded { + output_ref: output_ref.clone(), + deps, + output_local: output_local.clone(), + output_dep: output_dep.clone(), + }, + ) + }); + Ok(Some((output_ref, output_local, output_dep))) } else { - Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::Encoded { - output_ref: output_ref, - deps, - output_local: output_local, - output_dep: output_dep, - })); + Self::with_cache(|cache| { + cache.borrow_mut().insert( + task_key, + TaskEncoderCacheState::Encoded { + output_ref, + deps, + output_local, + output_dep, + }, + ) + }); Ok(None) } } - Err(EncodeFullError::AlreadyEncoded) => Self::with_cache(|cache| match cache.borrow().get(&task_key).unwrap() { - TaskEncoderCacheState::Encoded { - output_ref, - output_local, - output_dep, - .. - } => if need_output { - Ok(Some(( - // TODO: does it even make sense for an encoder to request the full encoding - // when a cycle can occur? - output_ref.clone(), - output_local.clone(), - output_dep.clone(), - ))) - } else { - Ok(None) - }, - TaskEncoderCacheState::ErrorEnqueue { error } - | TaskEncoderCacheState::ErrorEncode { error, .. } => Err(error.clone()), - TaskEncoderCacheState::Started { .. } - | TaskEncoderCacheState::Enqueued => panic!("encoder did not finish for task {task_key:?}"), - }), + Err(EncodeFullError::AlreadyEncoded) => { + Self::with_cache(|cache| match cache.borrow().get(&task_key).unwrap() { + TaskEncoderCacheState::Encoded { + output_ref, + output_local, + output_dep, + .. + } => { + if need_output { + Ok(Some(( + // TODO: does it even make sense for an encoder to request the full encoding + // when a cycle can occur? + output_ref.clone(), + output_local.clone(), + output_dep.clone(), + ))) + } else { + Ok(None) + } + } + TaskEncoderCacheState::ErrorEnqueue { error } + | TaskEncoderCacheState::ErrorEncode { error, .. } => Err(error.clone()), + TaskEncoderCacheState::Started { .. } | TaskEncoderCacheState::Enqueued => { + panic!("encoder did not finish for task {task_key:?}") + } + }) + } Err(EncodeFullError::DependencyError) => todo!(), Err(EncodeFullError::EncodingError(err, maybe_output_dep)) => { - Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::ErrorEncode { - output_ref: output_ref.clone(), - deps, - error: TaskEncoderError::EncodingError(err.clone()), - output_dep: maybe_output_dep, - })); + Self::with_cache(|cache| { + cache.borrow_mut().insert( + task_key, + TaskEncoderCacheState::ErrorEncode { + output_ref: output_ref.clone(), + deps, + error: TaskEncoderError::EncodingError(err.clone()), + output_dep: maybe_output_dep, + }, + ) + }); Err(TaskEncoderError::EncodingError(err)) } } } - /* - /// Given a task description for this encoder, enqueue it and return the - /// reference to the output. If the task is already enqueued, the output - /// reference already exists. - fn encode<'vir>(task: Self::TaskDescription<'vir>) -> Self::OutputRef<'vir> - where Self: 'vir - { - let task_key = Self::task_to_key(&task); - let task_key_clone = task_key.clone(); - if let Some(output_ref) = Self::with_cache(move |cache| match cache.borrow().get(&task_key_clone) { - Some(TaskEncoderCacheState::Enqueued { output_ref }) - | Some(TaskEncoderCacheState::Started { output_ref, .. }) - | Some(TaskEncoderCacheState::Encoded { output_ref, .. }) - | Some(TaskEncoderCacheState::ErrorEncode { output_ref, .. }) => Some(output_ref.clone()), - _ => None, - }) { - return output_ref; + /// Given a task description for this encoder, enqueue it and return the + /// reference to the output. If the task is already enqueued, the output + /// reference already exists. + fn encode<'vir>(task: Self::TaskDescription<'vir>) -> Self::OutputRef<'vir> + where Self: 'vir + { + let task_key = Self::task_to_key(&task); + let task_key_clone = task_key.clone(); + if let Some(output_ref) = Self::with_cache(move |cache| match cache.borrow().get(&task_key_clone) { + Some(TaskEncoderCacheState::Enqueued { output_ref }) + | Some(TaskEncoderCacheState::Started { output_ref, .. }) + | Some(TaskEncoderCacheState::Encoded { output_ref, .. }) + | Some(TaskEncoderCacheState::ErrorEncode { output_ref, .. }) => Some(output_ref.clone()), + _ => None, + }) { + return output_ref; + } + let task_ref = Self::task_to_output_ref(&task); + let task_key_clone = task_key.clone(); + let task_ref_clone = task_ref.clone(); + assert!(Self::with_cache(move |cache| cache.borrow_mut().insert( + task_key_clone, + TaskEncoderCacheState::Enqueued { output_ref: task_ref_clone }, + ).is_none())); + task_ref } - let task_ref = Self::task_to_output_ref(&task); - let task_key_clone = task_key.clone(); - let task_ref_clone = task_ref.clone(); - assert!(Self::with_cache(move |cache| cache.borrow_mut().insert( - task_key_clone, - TaskEncoderCacheState::Enqueued { output_ref: task_ref_clone }, - ).is_none())); - task_ref - } - // TODO: this function should not be needed - fn encode_eager<'vir>(task: Self::TaskDescription<'vir>) -> Result<( - Self::OutputRef<'vir>, - Self::OutputFullLocal<'vir>, - Self::OutputFullDependency<'vir>, - ), TaskEncoderError> - where Self: 'vir - { - let task_key = Self::task_to_key(&task); - // enqueue - let output_ref = Self::encode(task); - // process - Self::encode_full(task_key) - .map(|(output_full_local, output_full_dep)| (output_ref, output_full_local, output_full_dep)) - } + // TODO: this function should not be needed + fn encode_eager<'vir>(task: Self::TaskDescription<'vir>) -> Result<( + Self::OutputRef<'vir>, + Self::OutputFullLocal<'vir>, + Self::OutputFullDependency<'vir>, + ), TaskEncoderError> + where Self: 'vir + { + let task_key = Self::task_to_key(&task); + // enqueue + let output_ref = Self::encode(task); + // process + Self::encode_full(task_key) + .map(|(output_full_local, output_full_dep)| (output_ref, output_full_local, output_full_dep)) + } - /// Given a task key, fully encode the given task. If this task was already - /// finished, the encoding is not repeated. If this task was enqueued, but - /// not finished, return a `CyclicError`. - fn encode_full<'vir>(task_key: Self::TaskKey<'vir>) -> Result<( - Self::OutputFullLocal<'vir>, - Self::OutputFullDependency<'vir>, - ), TaskEncoderError> - where Self: 'vir - { - let mut output_ref_opt = None; - let ret = Self::with_cache(|cache| { - // should be queued by now - match cache.borrow().get(&task_key).unwrap() { - TaskEncoderCacheState::Enqueued { output_ref } => { - output_ref_opt = Some(output_ref.clone()); - None + /// Given a task key, fully encode the given task. If this task was already + /// finished, the encoding is not repeated. If this task was enqueued, but + /// not finished, return a `CyclicError`. + fn encode_full<'vir>(task_key: Self::TaskKey<'vir>) -> Result<( + Self::OutputFullLocal<'vir>, + Self::OutputFullDependency<'vir>, + ), TaskEncoderError> + where Self: 'vir + { + let mut output_ref_opt = None; + let ret = Self::with_cache(|cache| { + // should be queued by now + match cache.borrow().get(&task_key).unwrap() { + TaskEncoderCacheState::Enqueued { output_ref } => { + output_ref_opt = Some(output_ref.clone()); + None + } + TaskEncoderCacheState::Started { .. } => Some(Err(TaskEncoderError::CyclicError)), + TaskEncoderCacheState::Encoded { output_local, output_dep, .. } => + Some(Ok(( + output_local.clone(), + output_dep.clone(), + ))), + TaskEncoderCacheState::ErrorEncode { error, .. } => + Some(Err(error.clone())), } - TaskEncoderCacheState::Started { .. } => Some(Err(TaskEncoderError::CyclicError)), - TaskEncoderCacheState::Encoded { output_local, output_dep, .. } => - Some(Ok(( - output_local.clone(), - output_dep.clone(), - ))), - TaskEncoderCacheState::ErrorEncode { error, .. } => - Some(Err(error.clone())), + }); + if let Some(ret) = ret { + return ret; } - }); - if let Some(ret) = ret { - return ret; - } - let output_ref = output_ref_opt.unwrap(); + let output_ref = output_ref_opt.unwrap(); - let mut deps: TaskEncoderDependencies<'vir> = Default::default(); - match Self::do_encode_full(&task_key, &mut deps) { - Ok((output_local, output_dep)) => { - Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::Encoded { - output_ref: output_ref.clone(), - deps, - output_local: output_local.clone(), - output_dep: output_dep.clone(), - })); - Ok(( - output_local, - output_dep, - )) - } - Err((err, maybe_output_dep)) => { - Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::ErrorEncode { - output_ref: output_ref.clone(), - deps, - error: TaskEncoderError::EncodingError(err.clone()), - output_dep: maybe_output_dep, - })); - Err(TaskEncoderError::EncodingError(err)) + let mut deps: TaskEncoderDependencies<'vir> = Default::default(); + match Self::do_encode_full(&task_key, &mut deps) { + Ok((output_local, output_dep)) => { + Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::Encoded { + output_ref: output_ref.clone(), + deps, + output_local: output_local.clone(), + output_dep: output_dep.clone(), + })); + Ok(( + output_local, + output_dep, + )) + } + Err((err, maybe_output_dep)) => { + Self::with_cache(|cache| cache.borrow_mut().insert(task_key, TaskEncoderCacheState::ErrorEncode { + output_ref: output_ref.clone(), + deps, + error: TaskEncoderError::EncodingError(err.clone()), + output_dep: maybe_output_dep, + })); + Err(TaskEncoderError::EncodingError(err)) + } } } - } -*/ + */ /// Given a task description, create a key for storing it in the cache. - fn task_to_key<'vir>(task: &Self::TaskDescription<'vir>) -> // Result< - Self::TaskKey<'vir>;//, - // Self::EnqueueingError, - //> -/* - /// Given a task description, create a reference to the output. - fn task_to_output_ref<'vir>(task: &Self::TaskDescription<'vir>) -> Self::OutputRef<'vir>; -*/ + fn task_to_key<'vir>(task: &Self::TaskDescription<'vir>) -> Self::TaskKey<'vir>; + /* + /// Given a task description, create a reference to the output. + fn task_to_output_ref<'vir>(task: &Self::TaskDescription<'vir>) -> Self::OutputRef<'vir>; + */ fn do_encode_full<'vir>( task_key: &Self::TaskKey<'vir>, deps: &mut TaskEncoderDependencies<'vir, Self>, ) -> EncodeFullResult<'vir, Self>; fn all_outputs<'vir>() -> Vec> - where Self: 'vir + where + Self: 'vir, { Self::with_cache(|cache| { - let mut ret = vec![]; - for (_task_key, cache_state) in cache.borrow().iter() { - match cache_state { // TODO: make this into an iterator chain - TaskEncoderCacheState::Encoded { output_local, .. } => ret.push(output_local.clone()), - _ => {} - } - } - ret + cache + .borrow() + .iter() + .flat_map(|(_, cache_state)| { + if let TaskEncoderCacheState::Encoded { output_local, .. } = cache_state { + Some(output_local) + } else { + None + } + }) + .cloned() + .collect() }) } } diff --git a/viper/benches/bench_program.rs b/viper/benches/bench_program.rs index a735827300a..f2c60a3a544 100644 --- a/viper/benches/bench_program.rs +++ b/viper/benches/bench_program.rs @@ -92,7 +92,10 @@ fn build_program<'a>(ast: &'a AstFactory) -> Program<'a> { Some( // x % 2 == 0 ast.eq_cmp( - ast.module(ast.local_var("v", ast.int_type(), ast.no_position()), ast.int_lit(2)), + ast.mod_( + ast.local_var("v", ast.int_type(), ast.no_position()), + ast.int_lit(2), + ), ast.int_lit(0), ), ), @@ -106,7 +109,7 @@ fn build_program<'a>(ast: &'a AstFactory) -> Program<'a> { ast.and( ast.field_access_predicate( ast.field_access( - ast.local_var("box", ast.ref_type()), + ast.local_var("box", ast.ref_type(), ast.no_position()), ast.field("value", ast.int_type()), ), ast.full_perm(), @@ -114,7 +117,7 @@ fn build_program<'a>(ast: &'a AstFactory) -> Program<'a> { ast.func_app( "even", &[ast.field_access( - ast.local_var("box", ast.ref_type()), + ast.local_var("box", ast.ref_type(), ast.no_position()), ast.field("value", ast.int_type()), )], ast.bool_type(), @@ -140,7 +143,10 @@ fn build_program<'a>(ast: &'a AstFactory) -> Program<'a> { &[ // EvenNumBox(box) ast.predicate_access_predicate( - ast.predicate_access(&[ast.local_var("box", ast.ref_type(), ast.no_position())], "EvenNumBox"), + ast.predicate_access( + &[ast.local_var("box", ast.ref_type(), ast.no_position())], + "EvenNumBox", + ), ast.full_perm(), ), ], @@ -169,7 +175,10 @@ fn build_program<'a>(ast: &'a AstFactory) -> Program<'a> { ), // fold EvenNumBox(box) ast.fold(ast.predicate_access_predicate( - ast.predicate_access(&[ast.local_var("box", ast.ref_type(), ast.no_position())], "EvenNumBox"), + ast.predicate_access( + &[ast.local_var("box", ast.ref_type(), ast.no_position())], + "EvenNumBox", + ), ast.full_perm(), )), ], diff --git a/viper/src/ast_factory/expression.rs b/viper/src/ast_factory/expression.rs index 5806840e792..594b3992686 100644 --- a/viper/src/ast_factory/expression.rs +++ b/viper/src/ast_factory/expression.rs @@ -440,52 +440,52 @@ impl<'a> AstFactory<'a> { BinOpBv::BitAnd => ast::utility::BVFactory::call_and( &factory_, factory, - self.jni.new_string(&format!("bv{size}_and")), + self.jni.new_string(format!("bv{size}_and")), ), BinOpBv::BitOr => ast::utility::BVFactory::call_or( &factory_, factory, - self.jni.new_string(&format!("bv{size}_or")), + self.jni.new_string(format!("bv{size}_or")), ), BinOpBv::BitXor => ast::utility::BVFactory::call_xor( &factory_, factory, - self.jni.new_string(&format!("bv{size}_xor")), + self.jni.new_string(format!("bv{size}_xor")), ), BinOpBv::BvAdd => ast::utility::BVFactory::call_add( &factory_, factory, - self.jni.new_string(&format!("bv{size}_add")), + self.jni.new_string(format!("bv{size}_add")), ), BinOpBv::BvSub => ast::utility::BVFactory::call_sub( &factory_, factory, - self.jni.new_string(&format!("bv{size}_sub")), + self.jni.new_string(format!("bv{size}_sub")), ), BinOpBv::BvMul => ast::utility::BVFactory::call_mul( &factory_, factory, - self.jni.new_string(&format!("bv{size}_mul")), + self.jni.new_string(format!("bv{size}_mul")), ), BinOpBv::BvUDiv => ast::utility::BVFactory::call_udiv( &factory_, factory, - self.jni.new_string(&format!("bv{size}_udiv")), + self.jni.new_string(format!("bv{size}_udiv")), ), BinOpBv::BvShl => ast::utility::BVFactory::call_shl( &factory_, factory, - self.jni.new_string(&format!("bv{size}_shl")), + self.jni.new_string(format!("bv{size}_shl")), ), BinOpBv::BvLShr => ast::utility::BVFactory::call_lshr( &factory_, factory, - self.jni.new_string(&format!("bv{size}_lshr")), + self.jni.new_string(format!("bv{size}_lshr")), ), BinOpBv::BvAShr => ast::utility::BVFactory::call_ashr( &factory_, factory, - self.jni.new_string(&format!("bv{size}_ashr")), + self.jni.new_string(format!("bv{size}_ashr")), ), } .unwrap(); diff --git a/viper/src/ast_factory/mod.rs b/viper/src/ast_factory/mod.rs index e58288b71db..2a74339ea70 100644 --- a/viper/src/ast_factory/mod.rs +++ b/viper/src/ast_factory/mod.rs @@ -15,7 +15,7 @@ use crate::jni_utils::JniUtils; use jni::{objects::JObject, JNIEnv}; use viper_sys::wrappers::viper::silver::ast; -pub use self::{ast_type::*, expression::*, position::*, program::*, statement::*, structs::*}; +pub use self::{expression::*, structs::*}; #[derive(Clone, Copy)] pub struct AstFactory<'a> { diff --git a/viper/src/verification_result.rs b/viper/src/verification_result.rs index 81e931c186b..e51be74274b 100644 --- a/viper/src/verification_result.rs +++ b/viper/src/verification_result.rs @@ -22,7 +22,7 @@ pub enum VerificationResult { #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ConsistencyError { pub message: String, - pub pos_id: Option + pub pos_id: Option, } impl VerificationResult { diff --git a/viper/src/verifier.rs b/viper/src/verifier.rs index 24c2abdf565..60b491793bd 100644 --- a/viper/src/verifier.rs +++ b/viper/src/verifier.rs @@ -11,7 +11,8 @@ use crate::{ silicon_counterexample::SiliconCounterexample, smt_manager::SmtManager, verification_backend::VerificationBackend, - verification_result::{VerificationError, VerificationResult}, ConsistencyError, + verification_result::{VerificationError, VerificationResult}, + ConsistencyError, }; use jni::{errors::Result, objects::JObject, JNIEnv}; use log::{debug, error, info}; @@ -173,10 +174,8 @@ impl<'a> Verifier<'a> { .is_instance_of(pos, "viper/silver/ast/HasIdentifier") { Some( - self.jni.get_string( - self.jni - .unwrap_result(has_identifier_wrapper.call_id(pos)), - ), + self.jni + .get_string(self.jni.unwrap_result(has_identifier_wrapper.call_id(pos))), ) } else { None diff --git a/viper/tests/complex_program.rs b/viper/tests/complex_program.rs index 7ac2ab01520..2ebdbcb34f5 100644 --- a/viper/tests/complex_program.rs +++ b/viper/tests/complex_program.rs @@ -89,7 +89,10 @@ fn success_with_complex_program() { Some( // x % 2 == 0 ast.eq_cmp( - ast.module(ast.local_var("v", ast.int_type(), ast.no_position()), ast.int_lit(2)), + ast.mod_( + ast.local_var("v", ast.int_type(), ast.no_position()), + ast.int_lit(2), + ), ast.int_lit(0), ), ), @@ -137,7 +140,10 @@ fn success_with_complex_program() { &[ // EvenNumBox(box) ast.predicate_access_predicate( - ast.predicate_access(&[ast.local_var("box", ast.ref_type(), ast.no_position())], "EvenNumBox"), + ast.predicate_access( + &[ast.local_var("box", ast.ref_type(), ast.no_position())], + "EvenNumBox", + ), ast.full_perm(), ), ], @@ -166,7 +172,10 @@ fn success_with_complex_program() { ), // fold EvenNumBox(box) ast.fold(ast.predicate_access_predicate( - ast.predicate_access(&[ast.local_var("box", ast.ref_type(), ast.no_position())], "EvenNumBox"), + ast.predicate_access( + &[ast.local_var("box", ast.ref_type(), ast.no_position())], + "EvenNumBox", + ), ast.full_perm(), )), ], diff --git a/vir/src/callable_idents.rs b/vir/src/callable_idents.rs index f2670577f11..ecbfdc345e1 100644 --- a/vir/src/callable_idents.rs +++ b/vir/src/callable_idents.rs @@ -1,10 +1,9 @@ +#![allow(clippy::len_without_is_empty)] + use crate::{ - debug_info::DebugInfo, viper_ident::ViperIdent, with_vcx, DomainParamData, ExprGen, LocalDecl, MethodCallGenData, PredicateAppGen, PredicateAppGenData, StmtGenData, Type, TypeData, VirCtxt, typecheck_error, + data::*, debug_info::DebugInfo, gendata::*, genrefs::*, refs::*, typecheck_error, + viper_ident::ViperIdent, with_vcx, VirCtxt, }; -use crate::data::*; -use crate::refs::*; -use crate::gendata::*; -use crate::genrefs::*; use sealed::sealed; use std::fmt::Debug; @@ -17,8 +16,16 @@ pub trait CallableIdent<'vir, A: Arity<'vir>, ResultTy> { fn arity(&self) -> &A; fn result_ty(&self) -> ResultTy; } -pub trait ToKnownArity<'vir, T: 'vir, ResultTy>: CallableIdent<'vir, UnknownArityAny<'vir, T>, ResultTy> + Sized { - fn to_known<'tcx, K: CallableIdent<'vir, KnownArityAny<'vir, T, N>, ResultTy>, const N: usize>(self) -> K { +pub trait ToKnownArity<'vir, T: 'vir, ResultTy>: + CallableIdent<'vir, UnknownArityAny<'vir, T>, ResultTy> + Sized +{ + fn to_known< + 'tcx, + K: CallableIdent<'vir, KnownArityAny<'vir, T, N>, ResultTy>, + const N: usize, + >( + self, + ) -> K { K::new( self.name(), KnownArityAny::new(self.arity().args().try_into().unwrap()), @@ -78,18 +85,16 @@ impl<'vir, A: Arity<'vir>> CallableIdent<'vir, A, ()> for MethodIdent<'vir, A> { fn arity(&self) -> &A { &self.1 } - fn result_ty(&self) -> () { - () - } + fn result_ty(&self) {} } -impl <'vir, A: Arity<'vir>> MethodIdent<'vir, A> { +impl<'vir, A: Arity<'vir>> MethodIdent<'vir, A> { pub fn debug_info(&self) -> DebugInfo<'vir> { self.2 } } -impl <'vir, A: Arity<'vir>> MethodIdent<'vir, A> { +impl<'vir, A: Arity<'vir>> MethodIdent<'vir, A> { pub fn new(name: ViperIdent<'vir>, args: A) -> Self { Self(name, args, with_vcx(DebugInfo::new)) } @@ -97,7 +102,11 @@ impl <'vir, A: Arity<'vir>> MethodIdent<'vir, A> { impl<'vir, A: Arity<'vir, Arg = Type<'vir>>> MethodIdent<'vir, A> { pub fn as_unknown_arity(self) -> MethodIdent<'vir, UnknownArity<'vir>> { - MethodIdent(self.name(), UnknownArity::new(self.1.args()), self.debug_info()) + MethodIdent( + self.name(), + UnknownArity::new(self.1.args()), + self.debug_info(), + ) } } @@ -113,12 +122,10 @@ impl<'vir, A: Arity<'vir>> CallableIdent<'vir, A, ()> for PredicateIdent<'vir, A fn arity(&self) -> &A { &self.1 } - fn result_ty(&self) -> () { - () - } + fn result_ty(&self) {} } -impl <'vir, A: Arity<'vir>> PredicateIdent<'vir, A> { +impl<'vir, A: Arity<'vir>> PredicateIdent<'vir, A> { pub fn debug_info(&self) -> DebugInfo<'vir> { self.2 } @@ -145,9 +152,7 @@ impl<'vir, A: Arity<'vir>> CallableIdent<'vir, A, ()> for DomainIdent<'vir, A> { fn arity(&self) -> &A { &self.1 } - fn result_ty(&self) -> () { - () - } + fn result_ty(&self) {} } impl<'vir> DomainIdent<'vir, KnownArityAny<'vir, DomainParamData<'vir>, 0>> { @@ -177,7 +182,7 @@ pub trait Arity<'vir>: Copy { impl<'vir, T, const N: usize> Arity<'vir> for KnownArityAny<'vir, T, N> { type Arg = T; fn args(&self) -> &'vir [T] { - &self.0 + self.0 } fn len_matches(&self, _len: usize) -> bool { true @@ -187,7 +192,7 @@ impl<'vir, T, const N: usize> Arity<'vir> for KnownArityAny<'vir, T, N> { impl<'vir, T> Arity<'vir> for UnknownArityAny<'vir, T> { type Arg = T; fn args(&self) -> &'vir [T] { - &self.0 + self.0 } fn len_matches(&self, len: usize) -> bool { @@ -222,7 +227,7 @@ impl<'vir, A: Arity<'vir, Arg = Type<'vir>>> CheckTypes<'vir> for A { return false; } args.iter() - .zip(self.args().into_iter()) + .zip(self.args()) .all(|(a, expected)| a.typ() == *expected) } } @@ -236,7 +241,7 @@ impl<'vir, T, const N: usize> KnownArityAny<'vir, T, N> { } impl<'vir, T, const N: usize> Clone for KnownArityAny<'vir, T, N> { fn clone(&self) -> Self { - Self(self.0) + *self } } pub type NullaryArityAny<'vir, T> = KnownArityAny<'vir, T, 0>; @@ -260,7 +265,7 @@ impl<'vir, T> UnknownArityAny<'vir, T> { } impl<'vir, T> Clone for UnknownArityAny<'vir, T> { fn clone(&self) -> Self { - Self(self.0) + *self } } impl<'vir, T> Copy for UnknownArityAny<'vir, T> {} @@ -361,7 +366,6 @@ impl<'vir, const N: usize> DomainIdent<'vir, KnownArityAny<'vir, DomainParamData } } - // Func arity checked at runtime impl<'vir> FunctionIdent<'vir, UnknownArity<'vir>> { diff --git a/vir/src/context.rs b/vir/src/context.rs index fd2a76d9d58..d479b121e25 100644 --- a/vir/src/context.rs +++ b/vir/src/context.rs @@ -1,11 +1,9 @@ use prusti_interface::environment::EnvBody; use prusti_rustc_interface::middle::ty; -use std::cell::RefCell; -use std::fmt::Debug; +use std::{cell::RefCell, fmt::Debug}; use crate::{data::*, refs::*}; - /// The VIR context is a data structure used throughout the encoding process. pub struct VirCtxt<'tcx> { /// The arena used for bump allocating all VIR AST data. Anything allocated @@ -75,14 +73,21 @@ impl<'tcx> VirCtxt<'tcx> { self.arena.reset(); } - pub fn apply_ty_substs<'vir>(&'vir self, ty: Type<'vir>, substs: &TySubsts<'vir>) -> Type<'vir> { + pub fn apply_ty_substs<'vir>( + &'vir self, + ty: Type<'vir>, + substs: &TySubsts<'vir>, + ) -> Type<'vir> { match ty { TypeData::DomainTypeParam(p) => substs.get(p.name).unwrap_or(&ty), TypeData::Domain(name, args) => { - let args = args.iter().map(|t| self.apply_ty_substs(t, substs)).collect::>(); - self.alloc(TypeData::Domain(name, &self.alloc(args))) + let args = args + .iter() + .map(|t| self.apply_ty_substs(t, substs)) + .collect::>(); + self.alloc(TypeData::Domain(name, self.alloc(args))) } - other => other + other => other, } } @@ -106,16 +111,25 @@ impl ProgramRef { self.hash } - pub fn get_name(&self) -> &str { "program" } - pub fn get_rust_name(&self) -> &str { "rustprogram" } - pub fn get_check_mode(&self) -> &str { "check" } - pub fn get_name_with_check_mode(&self) -> &str { "program-check" } + pub fn get_name(&self) -> &str { + "program" + } + pub fn get_rust_name(&self) -> &str { + "rustprogram" + } + pub fn get_check_mode(&self) -> &str { + "check" + } + pub fn get_name_with_check_mode(&self) -> &str { + "program-check" + } pub fn set_name(&mut self, _name: &str) {} } impl serde::Serialize for ProgramRef { fn serialize(&self, s: S) -> Result - where S: serde::Serializer + where + S: serde::Serializer, { with_vcx(|vcx| { let program = vcx.get_program(*self); @@ -125,7 +139,8 @@ impl serde::Serialize for ProgramRef { } impl<'de> serde::Deserialize<'de> for ProgramRef { fn deserialize(d: D) -> Result - where D: serde::Deserializer<'de> + where + D: serde::Deserializer<'de>, { let program = Program::deserialize(d)?; Ok(program.to_ref()) @@ -133,17 +148,23 @@ impl<'de> serde::Deserialize<'de> for ProgramRef { } thread_local! { - static VCTX: RefCell>> = RefCell::new(None); + static VCTX: RefCell>> = const { RefCell::new(None) }; } /// Initialises the VIR context. Should only be called once, when the type /// context is available. pub fn init_vcx<'tcx>(vcx: VirCtxt<'tcx>) { - VCTX.replace(Some(unsafe { std::mem::transmute(vcx) })); + VCTX.replace(Some(unsafe { + std::mem::transmute::, VirCtxt<'_>>(vcx) + })); } +#[cfg(test)] pub(crate) fn replace_vcx<'tcx>(vcx: VirCtxt<'tcx>) -> Option> { - unsafe { std::mem::transmute(VCTX.replace(Some(std::mem::transmute(vcx)))) } + let old = VCTX.replace(Some(unsafe { + std::mem::transmute::, VirCtxt<'_>>(vcx) + })); + unsafe { std::mem::transmute::>, Option>>(old) } } /// Perform an action with the VIR context. @@ -156,7 +177,7 @@ where // the same (or shorter) than the lifetimes of the VIR arena and // the rustc type context, respectively let vcx = vcx.as_ref().expect("VIR context was not initialised"); - let vcx = unsafe { std::mem::transmute(vcx) }; + let vcx = unsafe { std::mem::transmute::<&VirCtxt<'_>, &VirCtxt<'_>>(vcx) }; f(vcx) }) } @@ -170,7 +191,7 @@ where // the same (or shorter) than the lifetimes of the VIR arena and // the rustc type context, respectively let vcx = vcx.as_mut().expect("VIR context was not initialised"); - let vcx = unsafe { std::mem::transmute(vcx) }; + let vcx = unsafe { std::mem::transmute::<&mut VirCtxt<'_>, &mut VirCtxt<'_>>(vcx) }; f(vcx) }) } diff --git a/vir/src/data.rs b/vir/src/data.rs index 263778094b3..cf6231b574a 100644 --- a/vir/src/data.rs +++ b/vir/src/data.rs @@ -1,23 +1,28 @@ -use std::collections::HashMap; -use std::fmt::Debug; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, fmt::Debug}; use prusti_rustc_interface::middle::mir; -use crate::{debug_info::DebugInfo, refs::*, viper_ident::ViperIdent, CallableIdent, FunctionIdent, UnknownArity}; +use crate::{ + debug_info::DebugInfo, refs::*, viper_ident::ViperIdent, CallableIdent, FunctionIdent, + UnknownArity, +}; #[derive(Serialize, Deserialize, Hash)] pub struct LocalData<'vir> { - #[serde(with = "crate::serde::serde_str")] pub name: &'vir str, // TODO: identifiers - #[serde(with = "crate::serde::serde_ref")] pub ty: Type<'vir>, - pub debug_info: DebugInfo<'vir> + #[serde(with = "crate::serde::serde_str")] + pub name: &'vir str, // TODO: identifiers + #[serde(with = "crate::serde::serde_ref")] + pub ty: Type<'vir>, + pub debug_info: DebugInfo<'vir>, } -#[derive(Eq, PartialEq)] -#[derive(Serialize, Deserialize, Hash)] +#[derive(Eq, PartialEq, Serialize, Deserialize, Hash)] pub struct LocalDeclData<'vir> { - #[serde(with = "crate::serde::serde_str")] pub name: &'vir str, // TODO: identifiers - #[serde(with = "crate::serde::serde_ref")] pub ty: Type<'vir>, + #[serde(with = "crate::serde::serde_str")] + pub name: &'vir str, // TODO: identifiers + #[serde(with = "crate::serde::serde_ref")] + pub ty: Type<'vir>, } #[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize, Hash)] @@ -61,12 +66,15 @@ pub enum BinOpKind { impl From for BinOpKind { fn from(value: mir::BinOp) -> Self { match value { - mir::BinOp::Add => BinOpKind::Add, - mir::BinOp::AddUnchecked => todo!(), - mir::BinOp::Sub => BinOpKind::Sub, - mir::BinOp::SubUnchecked => todo!(), - mir::BinOp::Mul => BinOpKind::Mul, - mir::BinOp::MulUnchecked => todo!(), + mir::BinOp::Add | mir::BinOp::AddUnchecked | mir::BinOp::AddWithOverflow => { + BinOpKind::Add + } + mir::BinOp::Sub | mir::BinOp::SubUnchecked | mir::BinOp::SubWithOverflow => { + BinOpKind::Sub + } + mir::BinOp::Mul | mir::BinOp::MulUnchecked | mir::BinOp::MulWithOverflow => { + BinOpKind::Mul + } mir::BinOp::Div => BinOpKind::Div, mir::BinOp::Rem => BinOpKind::Mod, mir::BinOp::BitXor => todo!(), @@ -86,9 +94,6 @@ impl From for BinOpKind { mir::BinOp::Ge => BinOpKind::CmpGe, mir::BinOp::Gt => BinOpKind::CmpGt, mir::BinOp::Offset => todo!(), - mir::BinOp::AddWithOverflow => todo!(), - mir::BinOp::SubWithOverflow => todo!(), - mir::BinOp::MulWithOverflow => todo!(), mir::BinOp::Cmp => todo!(), } } @@ -113,7 +118,7 @@ impl ConstData { ConstData::Bool(_) => &TypeData::Bool, ConstData::Int(_) => &TypeData::Int, ConstData::Wildcard => &TypeData::Perm, - ConstData::Null => &TypeData::Ref + ConstData::Null => &TypeData::Ref, } } } @@ -125,31 +130,35 @@ pub enum TypeData<'vir> { DomainTypeParam(DomainParamData<'vir>), // TODO: identifiers Domain( #[serde(with = "crate::serde::serde_str")] &'vir str, // TODO: identifiers - #[serde(with = "crate::serde::serde_slice")] &'vir [Type<'vir>] + #[serde(with = "crate::serde::serde_slice")] &'vir [Type<'vir>], ), // TODO: separate `TyParam` variant? `Domain` used for now Ref, // TODO: typed references ? Perm, Predicate, // The type of a predicate application - Unsupported(UnsupportedType<'vir>) + Unsupported(UnsupportedType<'vir>), } #[derive(PartialEq, Eq, Clone, Ord, PartialOrd, Serialize, Deserialize, Hash)] pub struct UnsupportedType<'vir> { - #[serde(with = "crate::serde::serde_str")] pub name: &'vir str, + #[serde(with = "crate::serde::serde_str")] + pub name: &'vir str, } pub type TySubsts<'vir> = HashMap<&'vir str, Type<'vir>>; #[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)] pub struct DomainParamData<'vir> { - #[serde(with = "crate::serde::serde_str")] pub name: &'vir str, // TODO: identifiers + #[serde(with = "crate::serde::serde_str")] + pub name: &'vir str, // TODO: identifiers } #[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Hash)] pub struct FieldData<'vir> { - #[serde(with = "crate::serde::serde_str")] pub name: &'vir str, // TODO: identifiers - #[serde(with = "crate::serde::serde_ref")] pub ty: Type<'vir>, + #[serde(with = "crate::serde::serde_str")] + pub name: &'vir str, // TODO: identifiers + #[serde(with = "crate::serde::serde_ref")] + pub ty: Type<'vir>, } #[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Hash)] @@ -157,17 +166,15 @@ pub struct FieldData<'vir> { pub struct DomainFunctionData<'vir> { pub unique: bool, pub name: ViperIdent<'vir>, - #[serde(with = "crate::serde::serde_slice")] pub args: &'vir [Type<'vir>], - #[serde(with = "crate::serde::serde_ref")] pub ret: Type<'vir>, + #[serde(with = "crate::serde::serde_slice")] + pub args: &'vir [Type<'vir>], + #[serde(with = "crate::serde::serde_ref")] + pub ret: Type<'vir>, } -impl <'vir> DomainFunctionData<'vir> { +impl<'vir> DomainFunctionData<'vir> { pub fn ident(&self) -> FunctionIdent<'vir, UnknownArity<'vir>> { - FunctionIdent::new( - self.name, - UnknownArity::new(self.args), - self.ret, - ) + FunctionIdent::new(self.name, UnknownArity::new(self.args), self.ret) } } @@ -194,7 +201,7 @@ pub type CfgBlockData<'vir> = crate::gendata::CfgBlockGenData<'vir, !, !>; pub type DomainAxiomData<'vir> = crate::gendata::DomainAxiomGenData<'vir, !, !>; pub type DomainData<'vir> = crate::gendata::DomainGenData<'vir, !, !>; pub type ExprData<'vir> = crate::gendata::ExprGenData<'vir, !, !>; -pub type ExprKindData<'vir> = crate::gendata::ExprKindGenData<'vir, ! ,!>; +pub type ExprKindData<'vir> = crate::gendata::ExprKindGenData<'vir, !, !>; pub type ForallData<'vir> = crate::gendata::ForallGenData<'vir, !, !>; pub type FuncAppData<'vir> = crate::gendata::FuncAppGenData<'vir, !, !>; pub type FunctionData<'vir> = crate::gendata::FunctionGenData<'vir, !, !>; diff --git a/vir/src/debug.rs b/vir/src/debug.rs index 8f5c14acc35..35842db2356 100644 --- a/vir/src/debug.rs +++ b/vir/src/debug.rs @@ -1,27 +1,22 @@ use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; -use crate::data::*; -use crate::gendata::*; -use crate::DomainAxiomGen; -use crate::DomainFunction; +use crate::{data::*, gendata::*}; fn fmt_comma_sep_display(f: &mut Formatter<'_>, els: &[T]) -> FmtResult { - els.iter() - .enumerate() - .map(|(idx, el)| { - if idx > 0 { write!(f, ", ")? } - el.fmt(f) - }) - .collect::() + els.iter().enumerate().try_for_each(|(idx, el)| { + if idx > 0 { + write!(f, ", ")? + } + el.fmt(f) + }) } fn fmt_comma_sep(f: &mut Formatter<'_>, els: &[T]) -> FmtResult { - els.iter() - .enumerate() - .map(|(idx, el)| { - if idx > 0 { write!(f, ", ")? } - el.fmt(f) - }) - .collect::() + els.iter().enumerate().try_for_each(|(idx, el)| { + if idx > 0 { + write!(f, ", ")? + } + el.fmt(f) + }) } fn fmt_comma_sep_lines(f: &mut Formatter<'_>, els: &[T]) -> FmtResult { for (idx, el) in els.iter().enumerate() { @@ -29,19 +24,14 @@ fn fmt_comma_sep_lines(f: &mut Formatter<'_>, els: &[T]) -> FmtResult if idx < els.len() - 1 { write!(f, ",")?; } - writeln!(f, "")?; + writeln!(f)?; } Ok(()) } fn indent(s: String) -> String { - s - .split("\n") - .intersperse("\n ") - .collect::() + s.split("\n").intersperse("\n ").collect::() } - - impl<'vir, Curr, Next> Debug for AccFieldGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "acc({:?}.{}", self.recv, self.field.name)?; @@ -56,22 +46,26 @@ impl<'vir, Curr, Next> Debug for BinOpGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "(")?; self.lhs.fmt(f)?; - write!(f, ") {} (", match self.kind { - BinOpKind::CmpEq => "==", - BinOpKind::CmpNe => "!=", - BinOpKind::CmpGt => ">", - BinOpKind::CmpGe => ">=", - BinOpKind::CmpLt => "<", - BinOpKind::CmpLe => "<=", - BinOpKind::And => "&&", - BinOpKind::Or => "||", - BinOpKind::Implies => "==>", - BinOpKind::Add => "+", - BinOpKind::Sub => "-", - BinOpKind::Mul => "*", - BinOpKind::Div => "\\", - BinOpKind::Mod => "%", - })?; + write!( + f, + ") {} (", + match self.kind { + BinOpKind::CmpEq => "==", + BinOpKind::CmpNe => "!=", + BinOpKind::CmpGt => ">", + BinOpKind::CmpGe => ">=", + BinOpKind::CmpLt => "<", + BinOpKind::CmpLe => "<=", + BinOpKind::And => "&&", + BinOpKind::Or => "||", + BinOpKind::Implies => "==>", + BinOpKind::Add => "+", + BinOpKind::Sub => "-", + BinOpKind::Mul => "*", + BinOpKind::Div => "\\", + BinOpKind::Mod => "%", + } + )?; self.rhs.fmt(f)?; write!(f, ")") } @@ -99,12 +93,12 @@ impl<'vir, Curr, Next> Debug for DomainGenData<'vir, Curr, Next> { write!(f, "domain {}", self.name)?; if !self.typarams.is_empty() { write!(f, "[")?; - fmt_comma_sep_display(f, &self.typarams)?; + fmt_comma_sep_display(f, self.typarams)?; write!(f, "]")?; } writeln!(f, " {{")?; - self.axioms.iter().map(|el| el.fmt(f)).collect::()?; - self.functions.iter().map(|el| el.fmt(f)).collect::()?; + self.axioms.iter().try_for_each(|el| el.fmt(f))?; + self.functions.iter().try_for_each(|el| el.fmt(f))?; writeln!(f, "}}") } } @@ -124,7 +118,7 @@ impl<'vir> Debug for DomainFunctionData<'vir> { write!(f, "unique ")?; } write!(f, "function {}(", self.name)?; - fmt_comma_sep(f, &self.args)?; + fmt_comma_sep(f, self.args)?; writeln!(f, "): {:?}", self.ret) } } @@ -171,7 +165,7 @@ impl<'vir> Debug for FieldData<'vir> { impl<'vir, Curr, Next> Debug for ForallGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "forall ")?; - fmt_comma_sep(f, &self.qvars)?; + fmt_comma_sep(f, self.qvars)?; write!(f, " ::")?; for trigger in self.triggers { write!(f, " {:?}", trigger)?; @@ -183,7 +177,7 @@ impl<'vir, Curr, Next> Debug for ForallGenData<'vir, Curr, Next> { impl<'vir, Curr, Next> Debug for ExistsGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "exists ")?; - fmt_comma_sep(f, &self.qvars)?; + fmt_comma_sep(f, self.qvars)?; write!(f, " ::")?; for trigger in self.triggers { write!(f, " {:?}", trigger)?; @@ -195,7 +189,7 @@ impl<'vir, Curr, Next> Debug for ExistsGenData<'vir, Curr, Next> { impl<'vir, Curr, Next> Debug for FuncAppGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "{}(", self.target)?; - fmt_comma_sep(f, &self.args)?; + fmt_comma_sep(f, self.args)?; write!(f, ")")?; Ok(()) } @@ -204,10 +198,14 @@ impl<'vir, Curr, Next> Debug for FuncAppGenData<'vir, Curr, Next> { impl<'vir, Curr, Next> Debug for FunctionGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { writeln!(f, "function {}(", self.name)?; - fmt_comma_sep_lines(f, &self.args)?; + fmt_comma_sep_lines(f, self.args)?; writeln!(f, "): {:?}", self.ret)?; - self.pres.iter().map(|el| writeln!(f, " requires {:?}", el)).collect::()?; - self.posts.iter().map(|el| writeln!(f, " ensures {:?}", el)).collect::()?; + self.pres + .iter() + .try_for_each(|el| writeln!(f, " requires {:?}", el))?; + self.posts + .iter() + .try_for_each(|el| writeln!(f, " ensures {:?}", el))?; if let Some(expr) = self.expr { write!(f, "{{\n ")?; expr.fmt(f)?; @@ -246,16 +244,20 @@ impl<'vir> Debug for LocalDeclData<'vir> { impl<'vir, Curr, Next> Debug for MethodGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { writeln!(f, "method {}(", self.name)?; - fmt_comma_sep_lines(f, &self.args)?; + fmt_comma_sep_lines(f, self.args)?; if !self.rets.is_empty() { writeln!(f, ") returns (")?; - fmt_comma_sep_lines(f, &self.rets)?; + fmt_comma_sep_lines(f, self.rets)?; writeln!(f, ")")?; } else { writeln!(f, ")")?; } - self.pres.iter().map(|el| writeln!(f, " requires {:?}", el)).collect::()?; - self.posts.iter().map(|el| writeln!(f, " ensures {:?}", el)).collect::()?; + self.pres + .iter() + .try_for_each(|el| writeln!(f, " requires {:?}", el))?; + self.posts + .iter() + .try_for_each(|el| writeln!(f, " ensures {:?}", el))?; if let Some(body) = self.body.as_ref() { writeln!(f, "{{")?; for block in body.blocks.iter() { @@ -274,14 +276,14 @@ impl<'vir, Curr, Next> Debug for MethodGenData<'vir, Curr, Next> { impl<'vir, Curr, Next> Debug for PredicateGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { write!(f, "predicate {}(", self.name)?; - fmt_comma_sep(f, &self.args)?; + fmt_comma_sep(f, self.args)?; write!(f, ")")?; if let Some(expr) = self.expr { write!(f, " {{\n ")?; expr.fmt(f)?; writeln!(f, "\n}}") } else { - writeln!(f, "") + writeln!(f) } } } @@ -292,7 +294,7 @@ impl<'vir, Curr, Next> Debug for PredicateAppGenData<'vir, Curr, Next> { write!(f, "acc(")?; } write!(f, "{}(", self.target)?; - fmt_comma_sep(f, &self.args)?; + fmt_comma_sep(f, self.args)?; write!(f, ")")?; if let Some(perm) = self.perm { write!(f, ", {perm:?})")?; @@ -327,11 +329,11 @@ impl<'vir, Curr, Next> Debug for StmtKindGenData<'vir, Curr, Next> { Self::Fold(data) => write!(f, "fold {:?}", data), Self::MethodCall(data) => { if !data.targets.is_empty() { - fmt_comma_sep(f, &data.targets)?; + fmt_comma_sep(f, data.targets)?; write!(f, " := ")?; } write!(f, "{}(", data.method)?; - fmt_comma_sep(f, &data.args)?; + fmt_comma_sep(f, data.args)?; write!(f, ")") } Self::Comment(info) => write!(f, "// {}", info), @@ -402,7 +404,7 @@ impl<'vir> Debug for TypeData<'vir> { write!(f, "{name}")?; if !params.is_empty() { write!(f, "[")?; - fmt_comma_sep(f, ¶ms)?; + fmt_comma_sep(f, params)?; write!(f, "]")?; } Ok(()) @@ -410,7 +412,7 @@ impl<'vir> Debug for TypeData<'vir> { Self::Ref => write!(f, "Ref"), Self::Perm => write!(f, "Perm"), Self::Predicate => write!(f, "Predicate"), - Self::Unsupported(u) => u.fmt(f) + Self::Unsupported(u) => u.fmt(f), } } } @@ -429,10 +431,15 @@ impl<'vir> Display for DomainParamData<'vir> { impl<'vir, Curr, Next> Debug for UnOpGenData<'vir, Curr, Next> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "{}({:?})", match self.kind { - UnOpKind::Neg => "-", - UnOpKind::Not => "!", - }, self.expr) + write!( + f, + "{}({:?})", + match self.kind { + UnOpKind::Neg => "-", + UnOpKind::Not => "!", + }, + self.expr + ) } } diff --git a/vir/src/debug_info.rs b/vir/src/debug_info.rs index 46c6acbfac6..3b1c4570105 100644 --- a/vir/src/debug_info.rs +++ b/vir/src/debug_info.rs @@ -1,5 +1,5 @@ -use cfg_if::cfg_if; use crate::VirCtxt; +use cfg_if::cfg_if; // Imports cfg_if! { @@ -38,24 +38,27 @@ cfg_if! { // serde and hash no-ops impl serde::Serialize for DebugInfo<'_> { fn serialize(&self, ser: S) -> Result - where S: serde::ser::Serializer + where + S: serde::ser::Serializer, { ser.serialize_unit() } } impl<'de> serde::Deserialize<'de> for DebugInfo<'_> { fn deserialize(deser: D) -> Result - where D: serde::de::Deserializer<'de> + where + D: serde::de::Deserializer<'de>, { deser.deserialize_unit(serde::de::IgnoredAny)?; Ok(DEBUGINFO_NONE) } } impl std::hash::Hash for DebugInfo<'_> { - fn hash(&self, state: &mut H) + fn hash(&self, _state: &mut H) where H: std::hash::Hasher, - {} + { + } } // DEBUGINFO_NONE @@ -99,7 +102,7 @@ cfg_if! { } } -impl <'vir> DebugInfo<'vir> { +impl<'vir> DebugInfo<'vir> { cfg_if! { if #[cfg(feature="vir_debug")] { pub fn new(vcx: &'vir VirCtxt<'_>) -> DebugInfo<'vir> { @@ -158,9 +161,7 @@ cfg_if! { } else { #[macro_export] macro_rules! add_debug_note { - ($debug_info:expr, $($arg:tt)*) => {{ - () - }}; + ($debug_info:expr, $($arg:tt)*) => {}; } } } diff --git a/vir/src/gendata.rs b/vir/src/gendata.rs index d0f8377ee43..eedc6165b20 100644 --- a/vir/src/gendata.rs +++ b/vir/src/gendata.rs @@ -201,18 +201,24 @@ impl<'vir, Curr, Next> ExprGenData<'vir, Curr, Next> { pub fn lift(&self) -> ExprGen<'vir, Prev, ExprKindGen<'vir, Curr, Next>> { match self.kind { ExprKindGenData::Lazy(_) => panic!("cannot lift lazy expression"), - _ => unsafe { std::mem::transmute(self) }, + _ => unsafe { + std::mem::transmute::< + &ExprGenData<'vir, Curr, Next>, + &ExprGenData<'vir, Prev, ExprKindGen<'vir, Curr, Next>>, + >(self) + }, } } } pub struct LazyGenData<'vir, Curr: 'vir, Next: 'vir> { pub name: &'vir str, + #[allow(clippy::type_complexity)] pub func: Box Fn(&'vir crate::VirCtxt<'a>, Curr) -> Next + 'vir>, } impl<'vir, Curr: 'vir, Next: 'vir> std::hash::Hash for LazyGenData<'vir, Curr, Next> { - fn hash(&self, state: &mut H) + fn hash(&self, _state: &mut H) where H: std::hash::Hasher, { @@ -293,10 +299,11 @@ pub struct MethodCallGenData<'vir, Curr, Next> { pub struct StmtGenData<'vir, Curr, Next> { pub kind: StmtKindGen<'vir, Curr, Next>, // #[vir(reify_pass)] pub debug_info: DebugInfo<'vir>, - #[vir(reify_pass)] pub span: Option<&'vir VirSpan<'vir>>, + #[vir(reify_pass)] + pub span: Option<&'vir VirSpan<'vir>>, } -impl <'vir, Curr: 'vir, Next: 'vir> StmtGenData<'vir, Curr, Next> { +impl<'vir, Curr: 'vir, Next: 'vir> StmtGenData<'vir, Curr, Next> { pub fn new(kind: StmtKindGen<'vir, Curr, Next>) -> Self { with_vcx(|vcx| Self { kind, @@ -395,7 +402,11 @@ impl<'vir> ProgramGenData<'vir, !, !> { // SAFETY: this transmutes a `'vir` (or shorter) reference to a // `'static` reference. The reference is not used except in // `VirCtxt::get_program`. See comment there. - program: unsafe { std::mem::transmute(self) }, + program: unsafe { + std::mem::transmute::<&ProgramGenData<'vir, !, !>, &ProgramGenData<'static, !, !>>( + self, + ) + }, } } } @@ -416,8 +427,6 @@ impl<'vir, Curr, Next> ProgramGenData<'vir, Curr, Next> { #[cfg(test)] mod tests { - use crate::debug_info::DebugInfo; - macro_rules! roundtrip_test_eq { ($name:ident, $vcx:ident, $val:expr) => { #[test] @@ -508,8 +517,8 @@ mod tests { roundtrip_test_match!( rt_stmt, _vcx, - crate::StmtGenData::::Dummy("hello",), - crate::StmtGenData::Dummy("hello",) + crate::StmtKindGenData::::Dummy("hello",), + crate::StmtKindGenData::Dummy("hello",) ); roundtrip_test_match!( rt_terminatorstmt, diff --git a/vir/src/genrefs.rs b/vir/src/genrefs.rs index bd8f4c03544..3a0fda91c9f 100644 --- a/vir/src/genrefs.rs +++ b/vir/src/genrefs.rs @@ -1,7 +1,8 @@ pub type AccFieldGen<'vir, Curr, Next> = &'vir crate::gendata::AccFieldGenData<'vir, Curr, Next>; pub type BinOpGen<'vir, Curr, Next> = &'vir crate::gendata::BinOpGenData<'vir, Curr, Next>; pub type CfgBlockGen<'vir, Curr, Next> = &'vir crate::gendata::CfgBlockGenData<'vir, Curr, Next>; -pub type DomainAxiomGen<'vir, Curr, Next> = &'vir crate::gendata::DomainAxiomGenData<'vir, Curr, Next>; +pub type DomainAxiomGen<'vir, Curr, Next> = + &'vir crate::gendata::DomainAxiomGenData<'vir, Curr, Next>; pub type DomainGen<'vir, Curr, Next> = &'vir crate::gendata::DomainGenData<'vir, Curr, Next>; pub type ExprGen<'vir, Curr, Next> = &'vir crate::gendata::ExprGenData<'vir, Curr, Next>; pub type ExprKindGen<'vir, Curr, Next> = &'vir crate::gendata::ExprKindGenData<'vir, Curr, Next>; @@ -10,19 +11,25 @@ pub type ForallGen<'vir, Curr, Next> = &'vir crate::gendata::ForallGenData<'vir, pub type FuncAppGen<'vir, Curr, Next> = &'vir crate::gendata::FuncAppGenData<'vir, Curr, Next>; pub type FunctionGen<'vir, Curr, Next> = &'vir crate::gendata::FunctionGenData<'vir, Curr, Next>; pub type GotoIfGen<'vir, Curr, Next> = &'vir crate::gendata::GotoIfGenData<'vir, Curr, Next>; -pub type GotoIfTargetGen<'vir, Curr, Next> = &'vir crate::gendata::GotoIfTargetGenData<'vir, Curr, Next>; +pub type GotoIfTargetGen<'vir, Curr, Next> = + &'vir crate::gendata::GotoIfTargetGenData<'vir, Curr, Next>; pub type LazyGen<'vir, Curr, Next> = &'vir crate::gendata::LazyGenData<'vir, Curr, Next>; pub type LetGen<'vir, Curr, Next> = &'vir crate::gendata::LetGenData<'vir, Curr, Next>; pub type MethodGen<'vir, Curr, Next> = &'vir crate::gendata::MethodGenData<'vir, Curr, Next>; -pub type MethodBodyGen<'vir, Curr, Next> = &'vir crate::gendata::MethodBodyGenData<'vir, Curr, Next>; -pub type MethodCallGen<'vir, Curr, Next> = &'vir crate::gendata::MethodCallGenData<'vir, Curr, Next>; +pub type MethodBodyGen<'vir, Curr, Next> = + &'vir crate::gendata::MethodBodyGenData<'vir, Curr, Next>; +pub type MethodCallGen<'vir, Curr, Next> = + &'vir crate::gendata::MethodCallGenData<'vir, Curr, Next>; pub type PredicateGen<'vir, Curr, Next> = &'vir crate::gendata::PredicateGenData<'vir, Curr, Next>; -pub type PredicateAppGen<'vir, Curr, Next> = &'vir crate::gendata::PredicateAppGenData<'vir, Curr, Next>; +pub type PredicateAppGen<'vir, Curr, Next> = + &'vir crate::gendata::PredicateAppGenData<'vir, Curr, Next>; pub type ProgramGen<'vir, Curr, Next> = &'vir crate::gendata::ProgramGenData<'vir, Curr, Next>; -pub type PureAssignGen<'vir, Curr, Next> = &'vir crate::gendata::PureAssignGenData<'vir, Curr, Next>; +pub type PureAssignGen<'vir, Curr, Next> = + &'vir crate::gendata::PureAssignGenData<'vir, Curr, Next>; pub type StmtGen<'vir, Curr, Next> = &'vir crate::gendata::StmtGenData<'vir, Curr, Next>; pub type StmtKindGen<'vir, Curr, Next> = &'vir crate::gendata::StmtKindGenData<'vir, Curr, Next>; -pub type TerminatorStmtGen<'vir, Curr, Next> = &'vir crate::gendata::TerminatorStmtGenData<'vir, Curr, Next>; +pub type TerminatorStmtGen<'vir, Curr, Next> = + &'vir crate::gendata::TerminatorStmtGenData<'vir, Curr, Next>; pub type TernaryGen<'vir, Curr, Next> = &'vir crate::gendata::TernaryGenData<'vir, Curr, Next>; pub type TriggerGen<'vir, Curr, Next> = &'vir crate::gendata::TriggerGenData<'vir, Curr, Next>; pub type UnOpGen<'vir, Curr, Next> = &'vir crate::gendata::UnOpGenData<'vir, Curr, Next>; diff --git a/vir/src/lib.rs b/vir/src/lib.rs index 50b82d12d3b..aebc29be4a6 100644 --- a/vir/src/lib.rs +++ b/vir/src/lib.rs @@ -1,6 +1,7 @@ #![feature(rustc_private)] #![feature(never_type)] #![feature(iter_intersperse)] +#![allow(clippy::needless_lifetimes)] mod context; mod data; @@ -17,6 +18,7 @@ mod spans; mod callable_idents; mod viper_ident; +pub use callable_idents::*; pub use context::*; pub use data::*; pub use gendata::*; @@ -24,7 +26,6 @@ pub use genrefs::*; pub use refs::*; pub use reify::*; pub use spans::VirSpan; -pub use callable_idents::*; pub use viper_ident::*; // for all arena-allocated types, there are two type definitions: one with diff --git a/vir/src/macros.rs b/vir/src/macros.rs index 6a78e001e12..cb5e7b3488e 100644 --- a/vir/src/macros.rs +++ b/vir/src/macros.rs @@ -112,8 +112,12 @@ macro_rules! vir_expr { #[macro_export] macro_rules! vir_ident { - ($vcx:expr; [ $name:expr ]) => { $name }; - ($vcx:expr; $name:ident ) => { $vcx.alloc_str(stringify!($name)) }; + ($vcx:expr; [ $name:expr ]) => { + $name + }; + ($vcx:expr; $name:ident ) => { + $vcx.alloc_str(stringify!($name)) + }; } #[macro_export] @@ -128,13 +132,32 @@ macro_rules! vir_format_identifier { #[macro_export] macro_rules! vir_type { - ($vcx:expr; Bool) => { & $crate::TypeData::Bool }; - ($vcx:expr; Ref) => { & $crate::TypeData::Ref }; - ($vcx:expr; Uint($bit_width:expr)) => { $vcx.alloc($crate::TypeData::Int { signed: false, bit_width: $bit_width }) }; - ($vcx:expr; Int($bit_width:expr)) => { $vcx.alloc($crate::TypeData::Int { signed: true, bit_width: $bit_width }) }; - ($vcx:expr; [ $ty:expr ]) => { $ty }; + ($vcx:expr; Bool) => { + &$crate::TypeData::Bool + }; + ($vcx:expr; Ref) => { + &$crate::TypeData::Ref + }; + ($vcx:expr; Uint($bit_width:expr)) => { + $vcx.alloc($crate::TypeData::Int { + signed: false, + bit_width: $bit_width, + }) + }; + ($vcx:expr; Int($bit_width:expr)) => { + $vcx.alloc($crate::TypeData::Int { + signed: true, + bit_width: $bit_width, + }) + }; + ($vcx:expr; [ $ty:expr ]) => { + $ty + }; ($vcx:expr; $name:ident) => { - $vcx.alloc($crate::TypeData::Domain($vcx.alloc_str(stringify!($name)), &[])) + $vcx.alloc($crate::TypeData::Domain( + $vcx.alloc_str(stringify!($name)), + &[], + )) }; } diff --git a/vir/src/make.rs b/vir/src/make.rs index 533ceb8ef7b..364e3b0282d 100644 --- a/vir/src/make.rs +++ b/vir/src/make.rs @@ -1,9 +1,15 @@ -use cfg_if::cfg_if; -use std::fmt::Debug; -use prusti_rustc_interface::middle::ty; use crate::{ - callable_idents::*, data::*, debug_info::{DebugInfo, DEBUGINFO_NONE}, gendata::*, genrefs::*, refs::*, typecheck_error, ViperIdent, VirCtxt + callable_idents::*, + data::*, + debug_info::{DebugInfo, DEBUGINFO_NONE}, + gendata::*, + genrefs::*, + refs::*, + typecheck_error, ViperIdent, VirCtxt, }; +use cfg_if::cfg_if; +use prusti_rustc_interface::middle::ty; +use std::fmt::Debug; macro_rules! const_expr { ($expr_kind:expr) => { @@ -154,10 +160,13 @@ cfg_if! { } } - impl<'tcx> VirCtxt<'tcx> { pub fn mk_local<'vir>(&'vir self, name: &'vir str, ty: Type<'vir>) -> Local<'vir> { - self.alloc(LocalData { name, ty, debug_info: DebugInfo::new(&self) }) + self.alloc(LocalData { + name, + ty, + debug_info: DebugInfo::new(self), + }) } pub fn mk_local_decl<'vir>(&'vir self, name: &'vir str, ty: Type<'vir>) -> LocalDecl<'vir> { @@ -165,19 +174,24 @@ impl<'tcx> VirCtxt<'tcx> { } pub fn mk_local_decl_local<'vir>(&'vir self, local: Local<'vir>) -> LocalDecl<'vir> { - self.alloc(LocalDeclData { name: local.name, ty: local.ty }) + self.alloc(LocalDeclData { + name: local.name, + ty: local.ty, + }) } pub fn mk_local_ex_local<'vir, Curr, Next>( &'vir self, local: Local<'vir>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Local(local)), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Local(local)))) } - pub fn mk_local_ex<'vir, Curr, Next>(&'vir self, name: &'vir str, ty: Type<'vir>) -> ExprGen<'vir, Curr, Next> { + pub fn mk_local_ex<'vir, Curr, Next>( + &'vir self, + name: &'vir str, + ty: Type<'vir>, + ) -> ExprGen<'vir, Curr, Next> { self.mk_local_ex_local(self.mk_local(name, ty)) } @@ -187,26 +201,24 @@ impl<'tcx> VirCtxt<'tcx> { src_args: &[ExprGen<'vir, Curr, Next>], result_ty: Type<'vir>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::FuncApp(self.arena.alloc(FuncAppGenData { + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::FuncApp( + self.arena.alloc(FuncAppGenData { target, args: self.alloc_slice(src_args), result_ty, - }))), - )) + }), + )))) } + #[allow(clippy::type_complexity)] pub fn mk_lazy_expr<'vir, Curr, Next>( &'vir self, name: &'vir str, func: Box Fn(&'vir VirCtxt<'a>, Curr) -> Next + 'vir>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Lazy(self.alloc(LazyGenData { - name, - func, - }))), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Lazy( + self.alloc(LazyGenData { name, func }), + )))) } pub fn mk_ternary_expr<'vir, Curr, Next>( @@ -215,13 +227,9 @@ impl<'tcx> VirCtxt<'tcx> { then: ExprGen<'vir, Curr, Next>, else_: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Ternary(self.alloc(TernaryGenData { - cond, - then, - else_, - }))), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Ternary( + self.alloc(TernaryGenData { cond, then, else_ }), + )))) } pub fn mk_unary_op_expr<'vir, Curr, Next>( @@ -229,20 +237,16 @@ impl<'tcx> VirCtxt<'tcx> { kind: UnOpKind, expr: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::UnOp( - self.alloc(UnOpGenData { kind, expr }), - )), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::UnOp( + self.alloc(UnOpGenData { kind, expr }), + )))) } pub fn mk_old_expr<'vir, Curr, Next>( &'vir self, expr: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Old(expr)), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Old(expr)))) } pub fn mk_forall_expr<'vir, Curr, Next>( @@ -251,13 +255,13 @@ impl<'tcx> VirCtxt<'tcx> { triggers: &'vir [TriggerGen<'vir, Curr, Next>], body: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Forall(self.alloc(ForallGenData { + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Forall( + self.alloc(ForallGenData { qvars, triggers, body, - }))), - )) + }), + )))) } pub fn mk_trigger<'vir, Curr, Next>( @@ -275,13 +279,9 @@ impl<'tcx> VirCtxt<'tcx> { val: ExprGen<'vir, Curr, Next>, expr: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - let let_expr = self.alloc( - ExprGenData::new( - self.alloc(ExprKindGenData::Let( - self.alloc(LetGenData { name, val, expr }) - )) - ) - ); + let let_expr = self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Let( + self.alloc(LetGenData { name, val, expr }), + )))); cfg_if! { if #[cfg(debug_assertions)] { check_expr_bindings(&mut HashMap::new(), let_expr); @@ -305,13 +305,9 @@ impl<'tcx> VirCtxt<'tcx> { lhs: ExprGen<'vir, Curr, Next>, rhs: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::BinOp(self.alloc(BinOpGenData { - kind, - lhs, - rhs, - }))), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::BinOp( + self.alloc(BinOpGenData { kind, lhs, rhs }), + )))) } pub fn mk_eq_expr<'vir, Curr, Next>( &'vir self, @@ -336,11 +332,9 @@ impl<'tcx> VirCtxt<'tcx> { target: PredicateAppGen<'vir, Curr, Next>, expr: ExprGen<'vir, Curr, Next>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Unfolding( - self.alloc(UnfoldingGenData { target, expr }), - )), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Unfolding( + self.alloc(UnfoldingGenData { target, expr }), + )))) } pub fn mk_acc_field_expr<'vir, Curr, Next>( @@ -349,9 +343,9 @@ impl<'tcx> VirCtxt<'tcx> { field: Field<'vir>, perm: Option>, ) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::AccField(self.alloc(AccFieldGenData { recv, field, perm }))), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::AccField( + self.alloc(AccFieldGenData { recv, field, perm }), + )))) } pub fn mk_const_expr<'vir, Curr, Next>( @@ -364,9 +358,7 @@ impl<'tcx> VirCtxt<'tcx> { } pub fn mk_todo_expr<'vir, Curr, Next>(&'vir self, msg: &'vir str) -> ExprGen<'vir, Curr, Next> { - self.alloc(ExprGenData::new( - self.alloc(ExprKindGenData::Todo(msg)), - )) + self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Todo(msg)))) } pub const fn mk_bool<'vir, const VALUE: bool>(&'vir self) -> Expr<'vir> { @@ -400,22 +392,18 @@ impl<'tcx> VirCtxt<'tcx> { self.alloc(ExprGenData::new(self.alloc(ExprKindGenData::Result(ty)))) } - pub fn mk_field<'vir>( - &'vir self, - name: &'vir str, - ty: Type<'vir>, - ) -> Field<'vir> { + pub fn mk_field<'vir>(&'vir self, name: &'vir str, ty: Type<'vir>) -> Field<'vir> { self.alloc(FieldData { name, ty }) } pub fn mk_domain_axiom<'vir, Curr, Next>( &'vir self, name: ViperIdent<'vir>, - expr: ExprGen<'vir, Curr, Next> + expr: ExprGen<'vir, Curr, Next>, ) -> DomainAxiomGen<'vir, Curr, Next> { self.alloc(DomainAxiomGenData { name: name.to_str(), - expr + expr, }) } @@ -439,7 +427,7 @@ impl<'tcx> VirCtxt<'tcx> { ret: Type<'vir>, pres: &'vir [ExprGen<'vir, Curr, Next>], posts: &'vir [ExprGen<'vir, Curr, Next>], - expr: Option> + expr: Option>, ) -> FunctionGen<'vir, Curr, Next> { // TODO: Typecheck pre and post conditions if let Some(body) = expr { @@ -467,7 +455,7 @@ impl<'tcx> VirCtxt<'tcx> { ret, pres, posts, - expr + expr, }) } @@ -475,7 +463,7 @@ impl<'tcx> VirCtxt<'tcx> { &'vir self, ident: PredicateIdent<'vir, A>, args: &'vir [LocalDecl<'vir>], - expr: Option> + expr: Option>, ) -> PredicateGen<'vir, Curr, Next> { if !ident.arity().types_match(args) { typecheck_error!( @@ -489,24 +477,16 @@ impl<'tcx> VirCtxt<'tcx> { ident.debug_info() ); } - self.mk_predicate_unchecked( - ident.name().to_str(), - args, - expr - ) + self.mk_predicate_unchecked(ident.name().to_str(), args, expr) } pub fn mk_predicate_unchecked<'vir, Curr, Next>( &'vir self, name: &'vir str, args: &'vir [LocalDecl<'vir>], - expr: Option> + expr: Option>, ) -> PredicateGen<'vir, Curr, Next> { - self.alloc(PredicateGenData { - name, - args, - expr - }) + self.alloc(PredicateGenData { name, args, expr }) } pub fn mk_domain<'vir, Curr, Next>( @@ -514,28 +494,26 @@ impl<'tcx> VirCtxt<'tcx> { name: ViperIdent<'vir>, typarams: &'vir [DomainParam<'vir>], axioms: &'vir [DomainAxiomGen<'vir, Curr, Next>], - functions: &'vir [DomainFunction<'vir>] + functions: &'vir [DomainFunction<'vir>], ) -> DomainGen<'vir, Curr, Next> { self.alloc(DomainGenData { name: name.to_str(), typarams, axioms, - functions + functions, }) } pub fn mk_exhale_stmt<'vir, Curr, Next>( &'vir self, - expr: ExprGen<'vir, Curr, Next> + expr: ExprGen<'vir, Curr, Next>, ) -> StmtGen<'vir, Curr, Next> { - self.alloc(StmtGenData::new( - self.alloc(StmtKindGenData::Exhale(expr)), - )) + self.alloc(StmtGenData::new(self.alloc(StmtKindGenData::Exhale(expr)))) } pub fn mk_unfold_stmt<'vir, Curr, Next>( &'vir self, - pred_app: PredicateAppGen<'vir, Curr, Next> + pred_app: PredicateAppGen<'vir, Curr, Next>, ) -> StmtGen<'vir, Curr, Next> { self.alloc(StmtGenData::new( self.alloc(StmtKindGenData::Unfold(pred_app)), @@ -544,7 +522,7 @@ impl<'tcx> VirCtxt<'tcx> { pub fn mk_fold_stmt<'vir, Curr, Next>( &'vir self, - pred_app: PredicateAppGen<'vir, Curr, Next> + pred_app: PredicateAppGen<'vir, Curr, Next>, ) -> StmtGen<'vir, Curr, Next> { self.alloc(StmtGenData::new( self.alloc(StmtKindGenData::Fold(pred_app)), @@ -554,7 +532,7 @@ impl<'tcx> VirCtxt<'tcx> { pub fn mk_pure_assign_stmt<'vir, Curr, Next>( &'vir self, lhs: ExprGen<'vir, Curr, Next>, - rhs: ExprGen<'vir, Curr, Next> + rhs: ExprGen<'vir, Curr, Next>, ) -> StmtGen<'vir, Curr, Next> { if lhs.ty() != rhs.ty() { typecheck_error!( @@ -563,59 +541,46 @@ impl<'tcx> VirCtxt<'tcx> { rhs.ty() ); } - self.alloc(StmtGenData::new( - self.alloc(StmtKindGenData::PureAssign( - self.alloc(PureAssignGenData { - lhs, - rhs, - }), - )), - )) + self.alloc(StmtGenData::new(self.alloc(StmtKindGenData::PureAssign( + self.alloc(PureAssignGenData { lhs, rhs }), + )))) } pub fn mk_local_decl_stmt<'vir, Curr, Next>( &'vir self, local: LocalDecl<'vir>, - expr: Option> - ) -> StmtGen<'vir, Curr, Next> { + expr: Option>, + ) -> StmtGen<'vir, Curr, Next> { self.alloc(StmtGenData::new( self.alloc(StmtKindGenData::LocalDecl(local, expr)), )) } pub fn mk_assume_false_stmt<'vir, Curr, Next>( - &'vir self + &'vir self, ) -> TerminatorStmtGen<'vir, Curr, Next> { - self.alloc( - TerminatorStmtGenData::AssumeFalse - ) + self.alloc(TerminatorStmtGenData::AssumeFalse) } pub fn mk_goto_stmt<'vir, Curr, Next>( &'vir self, - block: CfgBlockLabel<'vir> + block: CfgBlockLabel<'vir>, ) -> TerminatorStmtGen<'vir, Curr, Next> { - self.alloc( - TerminatorStmtGenData::Goto(block) - ) + self.alloc(TerminatorStmtGenData::Goto(block)) } pub fn mk_dummy_stmt<'vir, Curr, Next>( &'vir self, - msg: &'vir str + msg: &'vir str, ) -> TerminatorStmtGen<'vir, Curr, Next> { - self.alloc( - TerminatorStmtGenData::Dummy(msg) - ) + self.alloc(TerminatorStmtGenData::Dummy(msg)) } pub fn mk_comment_stmt<'vir, Curr, Next>( &'vir self, - msg: &'vir str + msg: &'vir str, ) -> StmtGen<'vir, Curr, Next> { - self.alloc(StmtGenData::new( - self.alloc(StmtKindGenData::Comment(msg)), - )) + self.alloc(StmtGenData::new(self.alloc(StmtKindGenData::Comment(msg)))) } pub fn mk_goto_if_stmt<'vir, Curr, Next>( @@ -625,14 +590,12 @@ impl<'tcx> VirCtxt<'tcx> { otherwise: CfgBlockLabel<'vir>, otherwise_statements: &'vir [StmtGen<'vir, Curr, Next>], ) -> TerminatorStmtGen<'vir, Curr, Next> { - self.alloc( - TerminatorStmtGenData::GotoIf(self.alloc(GotoIfGenData { - value, - targets, - otherwise, - otherwise_statements, - })) - ) + self.alloc(TerminatorStmtGenData::GotoIf(self.alloc(GotoIfGenData { + value, + targets, + otherwise, + otherwise_statements, + }))) } pub fn mk_goto_if_target<'vir, Curr, Next>( @@ -641,13 +604,11 @@ impl<'tcx> VirCtxt<'tcx> { label: CfgBlockLabel<'vir>, statements: &'vir [StmtGen<'vir, Curr, Next>], ) -> GotoIfTargetGen<'vir, Curr, Next> { - self.alloc( - GotoIfTargetGenData { - value, - label, - statements, - } - ) + self.alloc(GotoIfTargetGenData { + value, + label, + statements, + }) } pub fn mk_cfg_block<'vir, Curr, Next>( @@ -659,7 +620,7 @@ impl<'tcx> VirCtxt<'tcx> { self.alloc(CfgBlockGenData { label, stmts, - terminator + terminator, }) } @@ -679,14 +640,7 @@ impl<'tcx> VirCtxt<'tcx> { ident.arity() ); } - self.mk_method_unchecked( - ident.name().to_str(), - args, - rets, - pres, - posts, - blocks - ) + self.mk_method_unchecked(ident.name().to_str(), args, rets, pres, posts, blocks) } pub fn mk_method_unchecked<'vir, Curr, Next>( @@ -719,44 +673,45 @@ impl<'tcx> VirCtxt<'tcx> { rets, pres, posts, - body: blocks.map(|blocks| self.alloc(MethodBodyGenData { - blocks, - })), + body: blocks.map(|blocks| self.alloc(MethodBodyGenData { blocks })), }) } - pub fn mk_program<'vir, Curr, Next>( &'vir self, fields: &'vir [Field<'vir>], domains: &'vir [DomainGen<'vir, Curr, Next>], predicates: &'vir [PredicateGen<'vir, Curr, Next>], functions: &'vir [FunctionGen<'vir, Curr, Next>], - methods: &'vir [MethodGen<'vir, Curr, Next>] + methods: &'vir [MethodGen<'vir, Curr, Next>], ) -> ProgramGen<'vir, Curr, Next> { self.alloc(ProgramGenData { fields, domains, predicates, functions, - methods + methods, }) } pub fn mk_conj<'vir>(&'vir self, elems: &[Expr<'vir>]) -> Expr<'vir> { - elems.split_last().map(|(last, rest)| { - rest.iter().rfold(*last, |acc, e| { - self.mk_bin_op_expr(BinOpKind::And, *e, acc) + elems + .split_last() + .map(|(last, rest)| { + rest.iter() + .rfold(*last, |acc, e| self.mk_bin_op_expr(BinOpKind::And, *e, acc)) }) - }).unwrap_or_else(|| self.mk_bool::()) + .unwrap_or_else(|| self.mk_bool::()) } pub fn mk_disj<'vir>(&'vir self, elems: &[Expr<'vir>]) -> Expr<'vir> { - elems.split_last().map(|(last, rest)| { - rest.iter().rfold(*last, |acc, e| { - self.mk_bin_op_expr(BinOpKind::Or, *e, acc) + elems + .split_last() + .map(|(last, rest)| { + rest.iter() + .rfold(*last, |acc, e| self.mk_bin_op_expr(BinOpKind::Or, *e, acc)) }) - }).unwrap_or_else(|| self.mk_bool::()) + .unwrap_or_else(|| self.mk_bool::()) } const fn get_int_data(rust_ty: &ty::TyKind) -> (u32, bool) { @@ -776,7 +731,7 @@ impl<'tcx> VirCtxt<'tcx> { _ => unreachable!(), } } - pub const fn get_min_int<'vir>(&'vir self, ty: Type, rust_ty: &ty::TyKind) -> Expr<'vir> { + pub const fn get_min_int<'vir>(&'vir self, rust_ty: &ty::TyKind) -> Expr<'vir> { match Self::get_int_data(rust_ty) { (_, false) => self.mk_uint::<0>(), (i8::BITS, true) => self.mk_int::<{ i8::MIN as i128 }>(), @@ -787,7 +742,7 @@ impl<'tcx> VirCtxt<'tcx> { (_, true) => unreachable!(), } } - pub const fn get_max_int<'vir>(&'vir self, ty: Type, rust_ty: &ty::TyKind) -> Expr<'vir> { + pub const fn get_max_int<'vir>(&'vir self, rust_ty: &ty::TyKind) -> Expr<'vir> { match Self::get_int_data(rust_ty) { (u8::BITS, false) => self.mk_uint::<{ u8::MAX as u128 }>(), (u16::BITS, false) => self.mk_uint::<{ u16::MAX as u128 }>(), @@ -802,7 +757,7 @@ impl<'tcx> VirCtxt<'tcx> { _ => unreachable!(), } } - pub fn get_modulo_int<'vir>(&'vir self, ty: Type, rust_ty: &ty::TyKind) -> Expr<'vir> { + pub fn get_modulo_int<'vir>(&'vir self, rust_ty: &ty::TyKind) -> Expr<'vir> { match Self::get_int_data(rust_ty) { (u8::BITS, _) => self.mk_uint::<{ 1_u128 << u8::BITS }>(), (u16::BITS, _) => self.mk_uint::<{ 1_u128 << u16::BITS }>(), @@ -816,11 +771,7 @@ impl<'tcx> VirCtxt<'tcx> { _ => unreachable!(), } } - pub fn get_signed_shift_int<'vir>( - &'vir self, - ty: Type, - rust_ty: &ty::TyKind, - ) -> Option> { + pub fn get_signed_shift_int<'vir>(&'vir self, rust_ty: &ty::TyKind) -> Option> { let int = match Self::get_int_data(rust_ty) { (_, false) => return None, (u8::BITS, true) => self.mk_uint::<{ 1_u128 << (u8::BITS - 1) }>(), @@ -832,7 +783,7 @@ impl<'tcx> VirCtxt<'tcx> { }; Some(int) } - pub fn get_bit_width_int<'vir>(&'vir self, ty: Type, rust_ty: &ty::TyKind) -> Expr<'vir> { + pub fn get_bit_width_int<'vir>(&'vir self, rust_ty: &ty::TyKind) -> Expr<'vir> { match Self::get_int_data(rust_ty) { (u8::BITS, _) => self.mk_uint::<{ u8::BITS as u128 }>(), (u16::BITS, _) => self.mk_uint::<{ u16::BITS as u128 }>(), diff --git a/vir/src/reify.rs b/vir/src/reify.rs index e4dbb84e20d..5bfcee22631 100644 --- a/vir/src/reify.rs +++ b/vir/src/reify.rs @@ -1,22 +1,16 @@ -use crate::VirCtxt; -use crate::gendata::*; -use crate::genrefs::*; -use crate::refs::*; +use crate::{gendata::*, genrefs::*, refs::*, VirCtxt}; pub use vir_proc_macro::*; pub trait Reify<'vir, Curr> { type Next: Sized; - fn reify<'tcx>( - &self, - vcx: &'vir VirCtxt<'tcx>, - lctx: Curr, - ) -> Self::Next; + fn reify<'tcx>(&self, vcx: &'vir VirCtxt<'tcx>, lctx: Curr) -> Self::Next; } impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> - for ExprGen<'vir, Curr, ExprKindGen<'vir, NextA, NextB>> { + for ExprGen<'vir, Curr, ExprKindGen<'vir, NextA, NextB>> +{ type Next = ExprGen<'vir, NextA, NextB>; fn reify<'tcx>(&self, vcx: &'vir VirCtxt<'tcx>, lctx: Curr) -> Self::Next { vcx.alloc(ExprGenData { @@ -33,10 +27,16 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> type Next = ExprKindGen<'vir, NextA, NextB>; fn reify<'tcx>(&self, vcx: &'vir VirCtxt<'tcx>, lctx: Curr) -> Self::Next { match self { - ExprKindGenData::Field(v, f) => vcx.alloc(ExprKindGenData::Field(v.reify(vcx, lctx), f)), + ExprKindGenData::Field(v, f) => { + vcx.alloc(ExprKindGenData::Field(v.reify(vcx, lctx), f)) + } ExprKindGenData::Old(v) => vcx.alloc(ExprKindGenData::Old(v.reify(vcx, lctx))), - ExprKindGenData::AccField(v) => vcx.alloc(ExprKindGenData::AccField(v.reify(vcx, lctx))), - ExprKindGenData::Unfolding(v) => vcx.alloc(ExprKindGenData::Unfolding(v.reify(vcx, lctx))), + ExprKindGenData::AccField(v) => { + vcx.alloc(ExprKindGenData::AccField(v.reify(vcx, lctx))) + } + ExprKindGenData::Unfolding(v) => { + vcx.alloc(ExprKindGenData::Unfolding(v.reify(vcx, lctx))) + } ExprKindGenData::UnOp(v) => vcx.alloc(ExprKindGenData::UnOp(v.reify(vcx, lctx))), ExprKindGenData::BinOp(v) => vcx.alloc(ExprKindGenData::BinOp(v.reify(vcx, lctx))), ExprKindGenData::Ternary(v) => vcx.alloc(ExprKindGenData::Ternary(v.reify(vcx, lctx))), @@ -44,7 +44,9 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> ExprKindGenData::Exists(v) => vcx.alloc(ExprKindGenData::Exists(v.reify(vcx, lctx))), ExprKindGenData::Let(v) => vcx.alloc(ExprKindGenData::Let(v.reify(vcx, lctx))), ExprKindGenData::FuncApp(v) => vcx.alloc(ExprKindGenData::FuncApp(v.reify(vcx, lctx))), - ExprKindGenData::PredicateApp(v) => vcx.alloc(ExprKindGenData::PredicateApp(v.reify(vcx, lctx))), + ExprKindGenData::PredicateApp(v) => { + vcx.alloc(ExprKindGenData::PredicateApp(v.reify(vcx, lctx))) + } ExprKindGenData::Local(v) => vcx.alloc(ExprKindGenData::Local(v)), ExprKindGenData::Const(v) => vcx.alloc(ExprKindGenData::Const(v)), @@ -56,7 +58,6 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> } } - // TODO: how to make these generic? i.e. how to implement `Reify` for *any* // slice of reify-able elements? same for an Option of a slice; // for now these implementations are generated in the Reify derive macro @@ -66,9 +67,12 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> { type Next = &'vir [ExprGen<'vir, NextA, NextB>]; fn reify<'tcx>(&self, vcx: &'vir VirCtxt<'tcx>, lctx: Curr) -> Self::Next { - vcx.alloc_slice(&self.iter() - .map(|elem| elem.reify(vcx, lctx)) - .collect::>()) + vcx.alloc_slice( + &self + .iter() + .map(|elem| elem.reify(vcx, lctx)) + .collect::>(), + ) } } @@ -77,9 +81,12 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> { type Next = &'vir [&'vir [ExprGen<'vir, NextA, NextB>]]; fn reify<'tcx>(&self, vcx: &'vir VirCtxt<'tcx>, lctx: Curr) -> Self::Next { - vcx.alloc_slice(&self.iter() - .map(|elem| elem.reify(vcx, lctx)) - .collect::>()) + vcx.alloc_slice( + &self + .iter() + .map(|elem| elem.reify(vcx, lctx)) + .collect::>(), + ) } } @@ -96,11 +103,14 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> &'vir [StmtGen<'vir, NextA, NextB>], )]; fn reify<'tcx>(&self, vcx: &'vir VirCtxt<'tcx>, lctx: Curr) -> Self::Next { - vcx.alloc_slice(&self.iter() - .map(|(elem, label, extra_exprs)| { - (elem.reify(vcx, lctx), *label, extra_exprs.reify(vcx, lctx)) - }) - .collect::>()) + vcx.alloc_slice( + &self + .iter() + .map(|(elem, label, extra_exprs)| { + (elem.reify(vcx, lctx), *label, extra_exprs.reify(vcx, lctx)) + }) + .collect::>(), + ) } } @@ -131,7 +141,6 @@ impl<'vir, Curr: Copy, NextA, NextB> Reify<'vir, Curr> } } - /* impl< 'vir, diff --git a/vir/src/serde.rs b/vir/src/serde.rs index bcf14e0807f..4bac0b750c1 100644 --- a/vir/src/serde.rs +++ b/vir/src/serde.rs @@ -1,6 +1,6 @@ use serde::{ - ser::{Serialize, Serializer}, de::{Deserialize, Deserializer}, + ser::{Serialize, Serializer}, }; pub mod serde_slice { diff --git a/vir/src/spans.rs b/vir/src/spans.rs index 9e508878b2d..a136cf413df 100644 --- a/vir/src/spans.rs +++ b/vir/src/spans.rs @@ -1,7 +1,7 @@ -use std::collections::HashMap; +use crate::VirCtxt; use prusti_interface::PrustiError; use prusti_rustc_interface::span::Span; -use crate::VirCtxt; +use std::collections::HashMap; pub struct VirSpanHandler<'vir> { error_kind: &'static str, @@ -21,14 +21,16 @@ unsafe impl<'vir> Sync for VirSpan<'vir> {} impl serde::Serialize for VirSpan<'_> { fn serialize(&self, ser: S) -> Result - where S: serde::ser::Serializer + where + S: serde::ser::Serializer, { ser.serialize_u64(self.id as u64) } } impl<'de> serde::Deserialize<'de> for VirSpan<'_> { fn deserialize(deser: D) -> Result - where D: serde::de::Deserializer<'de> + where + D: serde::de::Deserializer<'de>, { let id = u64::deserialize(deser)? as usize; Ok(VirSpan { @@ -98,11 +100,14 @@ impl<'tcx> VirCtxt<'tcx> { let top_span_id = self.top_span().unwrap().id; let mut manager = self.spans.borrow_mut(); let previous = manager.handlers.remove(&top_span_id); - manager.handlers.insert(top_span_id, VirSpanHandler { - error_kind, - handler: Box::new(handler), - next: previous.map(Box::new), - }); + manager.handlers.insert( + top_span_id, + VirSpanHandler { + error_kind, + handler: Box::new(handler), + next: previous.map(Box::new), + }, + ); } // TODO: eventually, this should not be an Option @@ -116,7 +121,7 @@ impl<'tcx> VirCtxt<'tcx> { error_kind: &str, offending_pos_id: usize, reason_pos_id: Option, - ) -> Option> { + ) -> Option> { let manager = self.spans.borrow(); let reason_span_opt = reason_pos_id .and_then(|id| manager.all.get(id)) diff --git a/vir/src/viper_ident.rs b/vir/src/viper_ident.rs index 60b888bb7fe..f02609780b1 100644 --- a/vir/src/viper_ident.rs +++ b/vir/src/viper_ident.rs @@ -1,4 +1,4 @@ -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use crate::VirCtxt; use std::fmt::{self, Display, Formatter}; @@ -13,14 +13,13 @@ impl Display for ViperIdent<'_> { } } -impl <'vir> ViperIdent<'vir> { - +impl<'vir> ViperIdent<'vir> { pub fn new(ident: &'vir str) -> ViperIdent<'vir> { assert!(is_valid_identifier(ident)); ViperIdent(ident) } - pub fn sanitize(vcx: &'vir VirCtxt<'_>, ident: String) -> ViperIdent<'vir> { + pub fn sanitize(vcx: &'vir VirCtxt<'_>, ident: String) -> ViperIdent<'vir> { let ident = sanitize_str(&ident); // Just a sanity check, if this fails there is a problem in `sanitize` assert!(is_valid_identifier(ident.as_str())); diff --git a/x.py b/x.py index 4d02093296e..6ab76563eca 100755 --- a/x.py +++ b/x.py @@ -35,11 +35,9 @@ dry_run = False RUSTFMT_CRATES = [ - 'analysis', 'jni-gen', 'mir-state-analysis', 'prusti', - 'prusti-common', 'prusti-contracts/prusti-contracts', 'prusti-contracts/prusti-contracts-proc-macros', 'prusti-contracts/prusti-specs', @@ -52,31 +50,13 @@ 'prusti-smt-solver', 'prusti-tests', 'prusti-utils', - #'prusti-viper', + 'prusti-viper', 'smt-log-analyzer', + 'task-encoder', #'test-crates', 'viper', 'viper-sys', 'vir', - 'vir-gen', -] - -RUSTFMT_PATHS = [ - 'prusti-common/src/report/mod.rs', - 'prusti-common/src/utils/mod.rs', - 'prusti-common/src/vir/to_viper.rs', - 'prusti-common/src/vir/low_to_viper/mod.rs', - 'prusti-common/src/vir/optimizations/mod.rs', - 'prusti-viper/src/encoder/foldunfold/mod.rs', - 'prusti-viper/src/encoder/mir/mod.rs', - 'prusti-viper/src/encoder/high/mod.rs', - 'prusti-viper/src/encoder/typed/mod.rs', - 'prusti-viper/src/encoder/middle/mod.rs', - 'prusti-viper/src/encoder/snapshot/mod.rs', - 'prusti-viper/src/encoder/lifetimes/mod.rs', - 'prusti-viper/src/encoder/definition_collector.rs', - 'prusti-viper/src/encoder/counterexamples/mod.rs', - 'vir/defs/mod.rs', ] @@ -221,9 +201,6 @@ def fmt_all(): """Run rustfmt on all formatted files.""" for crate in RUSTFMT_CRATES: fmt_in(crate) - for path in RUSTFMT_PATHS: - for file in glob.glob(path, recursive=True): - run_command(['rustfmt', file]) def fmt_check_in(cwd): """Run cargo fmt check in the given subproject.""" @@ -233,9 +210,6 @@ def fmt_check_all(): """Run rustfmt check on all formatted files.""" for crate in RUSTFMT_CRATES: fmt_check_in(crate) - for path in RUSTFMT_PATHS: - for file in glob.glob(path, recursive=True): - run_command(['rustfmt', '--check', file]) def check_smir(): """Check that `extern crate` is used only in `prusti_rustc_interface` (TODO: `prusti_interface` is also ignored for now)."""