From 6c94c6bafeee5322a4502f48fd53bf0269f144cc Mon Sep 17 00:00:00 2001 From: Haibo Huang Date: Wed, 18 Nov 2020 15:37:31 -0800 Subject: Upgrade rust/crates/pin-project to 1.0.2 Test: make Change-Id: Ia85e48e7fd669c568d9abc6a68934b8cfdb13f09 --- .cargo_vcs_info.json | 2 +- .editorconfig | 4 + .gitattributes | 4 +- .github/FUNDING.yml | 1 + .github/workflows/ci.yml | 118 ++++----- .github/workflows/release.yml | 16 ++ Android.bp | 2 +- CHANGELOG.md | 39 ++- CODE_OF_CONDUCT.md | 9 - Cargo.toml | 4 +- Cargo.toml.orig | 4 +- METADATA | 8 +- README.md | 7 +- ci/install-component.sh | 27 -- ci/install-rust.sh | 12 - examples/enum-default-expanded.rs | 4 +- rustfmt.toml | 2 + scripts/check-minimal-versions.sh | 45 +++- scripts/ci.sh | 26 +- scripts/expandtest.sh | 35 --- src/lib.rs | 9 +- src/lib.rs.orig | 288 +++++++++++++++++++++ tests/cfg.rs | 32 +-- tests/compiletest.rs | 9 +- tests/drop_order.rs | 50 ++-- tests/include/basic-safe-part.rs | 38 +++ tests/lint.rs | 271 +++++++++++++++++-- tests/lint.txt | 10 +- tests/pin_project.rs | 102 ++++---- tests/pinned_drop.rs | 6 +- tests/proper_unpin.rs | 42 ++- tests/ui/cfg/cfg_attr-resolve.rs | 2 +- tests/ui/cfg/cfg_attr-resolve.stderr | 6 +- tests/ui/pin_project/packed-enum.stderr | 6 +- tests/ui/pin_project/private_in_public-enum.stderr | 4 +- .../ui/pin_project/project_replace_unsized.stderr | 6 +- .../project_replace_unsized_fn_params.rs | 13 + .../project_replace_unsized_fn_params.stderr | 53 ++++ .../pin_project/project_replace_unsized_locals.rs | 13 - .../project_replace_unsized_locals.stderr | 53 ---- tests/ui/pinned_drop/call-drop-inner.stderr | 10 +- 41 files changed, 977 insertions(+), 415 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/release.yml delete mode 100644 CODE_OF_CONDUCT.md delete mode 100755 ci/install-component.sh delete mode 100755 ci/install-rust.sh delete mode 100755 scripts/expandtest.sh create mode 100644 src/lib.rs.orig create mode 100644 tests/ui/pin_project/project_replace_unsized_fn_params.rs create mode 100644 tests/ui/pin_project/project_replace_unsized_fn_params.stderr delete mode 100644 tests/ui/pin_project/project_replace_unsized_locals.rs delete mode 100644 tests/ui/pin_project/project_replace_unsized_locals.stderr diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index da3735d..9b071c7 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "a69b3004032bfabf8cac8ac809d56ff32e66ed82" + "sha1": "9bdd6cf28180109a9add57d27428c66470f19c09" } } diff --git a/.editorconfig b/.editorconfig index c93ffc7..ea2a033 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,3 +14,7 @@ indent_size = 4 [*.{json,yml,md}] indent_size = 2 + +[*.sh] +indent_size = 2 +switch_case_indent = true diff --git a/.gitattributes b/.gitattributes index 45bca84..7e4a4f0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,2 @@ -[attr]rust text eol=lf whitespace=tab-in-indent,trailing-space,tabwidth=4 - * text=auto eol=lf -*.rs rust +*.rs text eol=lf whitespace=tab-in-indent,trailing-space,tabwidth=4 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..8204219 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: taiki-e diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a7da1d..6932c06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,12 +6,12 @@ on: branches: - master - staging - - trying schedule: - cron: '0 1 * * *' env: - RUSTFLAGS: -Dwarnings + CARGO_INCREMENTAL: 0 + RUSTFLAGS: -D warnings RUST_BACKTRACE: 1 defaults: @@ -20,7 +20,6 @@ defaults: jobs: test: - name: test strategy: matrix: rust: @@ -40,99 +39,82 @@ jobs: runs-on: ${{ matrix.os || 'ubuntu-latest' }} steps: - uses: actions/checkout@v2 - - name: Install Rust - run: ci/install-rust.sh ${{ matrix.rust }} - - name: Install cargo-hack - if: matrix.rust == 'nightly' - run: | - cargo install cargo-hack - - name: Add targets - if: matrix.rust == 'nightly' - run: | - rustup target add thumbv7m-none-eabi - - name: cargo test - run: | - cargo test --all --all-features --exclude expandtest - - name: cargo check (no-std) - if: matrix.rust == 'nightly' - run: | - cargo check --target thumbv7m-none-eabi --manifest-path tests/no-std/Cargo.toml - cargo check --target thumbv7m-none-eabi --manifest-path tests/rust-2015/Cargo.toml - - name: cargo check (minimal versions) - if: matrix.rust == 'nightly' - run: | - bash scripts/check-minimal-versions.sh + - uses: taiki-e/github-actions/install-rust@main + with: + toolchain: ${{ matrix.rust }} + - if: startsWith(matrix.rust, 'nightly') + run: cargo install cargo-hack + - run: rustup target add thumbv7m-none-eabi + - run: cargo test --all --all-features --exclude expandtest + - run: cargo check --manifest-path tests/no-std/Cargo.toml --target thumbv7m-none-eabi + - run: cargo check --manifest-path tests/rust-2015/Cargo.toml --target thumbv7m-none-eabi + - if: startsWith(matrix.rust, 'nightly') + run: bash scripts/check-minimal-versions.sh expandtest: - name: expandtest runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust and Rustfmt - run: ci/install-component.sh rustfmt - - name: Install cargo-expand + - uses: taiki-e/github-actions/install-rust@main + with: + component: rustfmt + - name: Fetch latest release version of cargo-expand run: | - cargo install cargo-expand - - name: cargo test (expandtest) - run: | - bash scripts/expandtest.sh + mkdir -p .github/caching + curl -LsSf https://api.github.com/repos/dtolnay/cargo-expand/releases/latest | jq -r '.name' > .github/caching/cargo-expand.lock + - name: Cache cargo-expand + id: cache-cargo-expand + uses: actions/cache@v2 + with: + path: ${{ runner.tool_cache }}/cargo-expand/bin + key: cargo-expand-bin-${{ hashFiles('.github/caching/cargo-expand.lock') }} + - name: Install cargo-expand + if: steps.cache-cargo-expand.outputs.cache-hit != 'true' + run: cargo install -f cargo-expand --root ${{ runner.tool_cache }}/cargo-expand + - run: echo "${{ runner.tool_cache }}/cargo-expand/bin" >> "${GITHUB_PATH}" + - run: cargo test -p expandtest miri: - name: miri runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust and Miri - run: | - ci/install-component.sh miri - cargo miri setup - - name: cargo miri test - run: | - cargo miri test + - uses: taiki-e/github-actions/install-rust@main + with: + component: miri + - run: cargo miri test clippy: - name: clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust and Clippy - run: ci/install-component.sh clippy - - name: cargo clippy - run: | - cargo clippy --all --all-features --all-targets + - uses: taiki-e/github-actions/install-rust@main + with: + component: clippy + - run: cargo clippy --all --all-features --all-targets rustfmt: - name: rustfmt runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust and Rustfmt - run: ci/install-component.sh rustfmt - - name: cargo fmt --check - run: | - cargo fmt --all -- --check + - uses: taiki-e/github-actions/install-rust@main + with: + component: rustfmt + - run: cargo fmt --all -- --check rustdoc: - name: rustdoc env: - RUSTDOCFLAGS: -Dwarnings + RUSTDOCFLAGS: -D warnings runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust - run: ci/install-rust.sh - - name: cargo doc - run: | - cargo doc --no-deps --all --all-features + - uses: taiki-e/github-actions/install-rust@main + - run: cargo doc --no-deps --all --all-features shellcheck: - name: shellcheck runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: shellcheck - run: | - shellcheck ci/*.sh scripts/*.sh + - run: shellcheck **/*.sh # These jobs don't actually test anything, but they're used to tell bors the # build completed, as there is no practical way to detect when a workflow is @@ -145,11 +127,11 @@ jobs: if: github.event_name == 'push' && success() needs: - test + - expandtest + - miri - clippy - rustfmt - rustdoc - - expandtest - - miri - shellcheck runs-on: ubuntu-latest steps: @@ -160,11 +142,11 @@ jobs: if: github.event_name == 'push' && !success() needs: - test + - expandtest + - miri - clippy - rustfmt - rustdoc - - expandtest - - miri - shellcheck runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5f7c998 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,16 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + create-release: + if: github.repository_owner == 'taiki-e' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: taiki-e/github-actions/create-release@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Android.bp b/Android.bp index f20d8c1..1ed91d5 100644 --- a/Android.bp +++ b/Android.bp @@ -10,7 +10,7 @@ rust_library { } // dependent_library ["feature_list"] -// pin-project-internal-1.0.1 +// pin-project-internal-1.0.2 // proc-macro2-1.0.24 "default,proc-macro" // quote-1.0.7 "default,proc-macro" // syn-1.0.48 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit,visit-mut" diff --git a/CHANGELOG.md b/CHANGELOG.md index f68f7b4..0810aae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](https://semver.org). ## [Unreleased] +## [1.0.2] - 2020-10-19 + +* [Suppress `clippy::unknown_clippy_lints` lint in generated code.](https://github.com/taiki-e/pin-project/pull/303) + ## [1.0.1] - 2020-10-15 * [Fix warnings when `#[pin_project]` attribute used within `macro_rules!` macros.](https://github.com/taiki-e/pin-project/pull/298) @@ -292,7 +296,9 @@ See also [tracking issue for 1.0 release](https://github.com/taiki-e/pin-project [206]: https://github.com/taiki-e/pin-project/issues/206 -## [0.4.11] - 2020-05-07 - YANKED +## [0.4.11] - 2020-05-07 + +**Note: This release has been yanked.** See [#206][206] for details. * [Fixed an issue that `#[project]` on non-statement expression does not work without unstable features.][197] @@ -367,7 +373,9 @@ See also [tracking issue for 1.0 release](https://github.com/taiki-e/pin-project [149]: https://github.com/taiki-e/pin-project/pull/149 -## [0.4.3] - 2019-10-15 - YANKED +## [0.4.3] - 2019-10-15 + +**Note: This release has been yanked.** See [#148] for details. * [`#[pin_project]` can now interoperate with `#[cfg_attr()]`.][135] @@ -377,22 +385,29 @@ See also [tracking issue for 1.0 release](https://github.com/taiki-e/pin-project * Diagnostic improvements. +[#148]: https://github.com/taiki-e/pin-project/pull/148 [120]: https://github.com/taiki-e/pin-project/pull/120 [135]: https://github.com/taiki-e/pin-project/pull/135 -## [0.4.2] - 2019-09-29 - YANKED +## [0.4.2] - 2019-09-29 + +**Note: This release has been yanked.** See [#148] for details. * [Fixed support for DSTs(Dynamically Sized Types).][113] [113]: https://github.com/taiki-e/pin-project/pull/113 -## [0.4.1] - 2019-09-26 - YANKED +## [0.4.1] - 2019-09-26 + +**Note: This release has been yanked.** See [#148] for details. * [Fixed an issue that caused an error when using `#[pin_project]` on a type that has `#[pin]` + `!Unpin` field with no generics or lifetime.][111] [111]: https://github.com/taiki-e/pin-project/pull/111 -## [0.4.0] - 2019-09-25 - YANKED +## [0.4.0] - 2019-09-25 + +**Note: This release has been yanked.** See [#148] for details. * [**Pin projection has become a safe operation.**][18] In the absence of other unsafe code that you write, it is impossible to cause undefined behavior. @@ -481,6 +496,7 @@ Changes since the 0.4.0-beta.1 release: ## [0.4.0-alpha.9] - 2019-09-05 * [Added 'project_into' method to `#[pin_project]` types][69]. This can be useful when returning a pin projection from a method. + ```rust fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> { self.project_into().pinned @@ -565,10 +581,14 @@ See also [tracking issue for 0.4 release][21]. * Diagnostic improvements. -## [0.3.3] - 2019-07-15 - YANKED +## [0.3.3] - 2019-07-15 + +**Note: This release has been yanked.** See [#16] for details. * Diagnostic improvements. +[#16]: https://github.com/taiki-e/pin-project/issues/16 + ## [0.3.2] - 2019-03-30 * Avoided suffixes on tuple index. @@ -637,11 +657,14 @@ See also [tracking issue for 0.4 release][21]. * Renamed from `unsafe_pin_project` to `unsafe_project`. -## [0.1.0] - 2019-01-08 - YANKED +## [0.1.0] - 2019-01-08 + +**Note: This release has been yanked.** Initial release -[Unreleased]: https://github.com/taiki-e/pin-project/compare/v1.0.1...HEAD +[Unreleased]: https://github.com/taiki-e/pin-project/compare/v1.0.2...HEAD +[1.0.2]: https://github.com/taiki-e/pin-project/compare/v1.0.1...v1.0.2 [1.0.1]: https://github.com/taiki-e/pin-project/compare/v1.0.0...v1.0.1 [1.0.0]: https://github.com/taiki-e/pin-project/compare/v1.0.0-alpha.1...v1.0.0 [1.0.0-alpha.1]: https://github.com/taiki-e/pin-project/compare/v0.4.23...v1.0.0-alpha.1 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 70c2090..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,9 +0,0 @@ -# Code of Conduct - -This project adheres to the [Rust Code of Conduct]. - -## Enforcement - -If you believe someone is violating the code of conduct, we ask that you report it by contacting taiki-e (te316e89@gmail.com). - -[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct diff --git a/Cargo.toml b/Cargo.toml index 5d73386..88db287 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ [package] edition = "2018" name = "pin-project" -version = "1.0.1" +version = "1.0.2" authors = ["Taiki Endo "] description = "A crate for safe and ergonomic pin-projection.\n" homepage = "https://github.com/taiki-e/pin-project" @@ -26,7 +26,7 @@ repository = "https://github.com/taiki-e/pin-project" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies.pin-project-internal] -version = "=1.0.1" +version = "=1.0.2" default-features = false [dev-dependencies.pin-project-auxiliary-macro] version = "0" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index ef428f0..7d31bb0 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "pin-project" -version = "1.0.1" +version = "1.0.2" authors = ["Taiki Endo "] edition = "2018" license = "Apache-2.0 OR MIT" @@ -29,7 +29,7 @@ members = [ ] [dependencies] -pin-project-internal = { version = "=1.0.1", path = "pin-project-internal", default-features = false } +pin-project-internal = { version = "=1.0.2", path = "pin-project-internal", default-features = false } [dev-dependencies] pin-project-auxiliary-macro = { version = "0", path = "tests/auxiliary/macro" } diff --git a/METADATA b/METADATA index d4ac624..4490183 100644 --- a/METADATA +++ b/METADATA @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/pin-project/pin-project-1.0.1.crate" + value: "https://static.crates.io/crates/pin-project/pin-project-1.0.2.crate" } - version: "1.0.1" + version: "1.0.2" license_type: NOTICE last_upgrade_date { year: 2020 - month: 10 - day: 26 + month: 11 + day: 18 } } diff --git a/README.md b/README.md index 0d5f5d7..689ec95 100644 --- a/README.md +++ b/README.md @@ -100,12 +100,7 @@ see [examples] directory for more examples and generated code. ## License -Licensed under either of - -* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) -* MIT license ([LICENSE-MIT](LICENSE-MIT) or ) - -at your option. +Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option. ### Contribution diff --git a/ci/install-component.sh b/ci/install-component.sh deleted file mode 100755 index dbba7b1..0000000 --- a/ci/install-component.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Install nightly Rust with a given component. -# -# If the component is unavailable on the latest nightly, -# use the latest toolchain with the component available. -# -# When using stable Rust, this script is basically unnecessary as almost components available. -# -# Refs: https://github.com/rust-lang/rustup-components-history#the-web-part - -set -euo pipefail - -package="${1:?}" -target="${2:-x86_64-unknown-linux-gnu}" - -date=$(curl -sSf https://rust-lang.github.io/rustup-components-history/"${target}"/"${package}") - -# shellcheck disable=1090 -"$(cd "$(dirname "${0}")" && pwd)"/install-rust.sh nightly-"${date}" - -rustup component add "${package}" - -case "${package}" in - rustfmt) "${package}" -V ;; - *) cargo "${package}" -V ;; -esac diff --git a/ci/install-rust.sh b/ci/install-rust.sh deleted file mode 100755 index 92c5877..0000000 --- a/ci/install-rust.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -toolchain="${1:-nightly}" - -rustup toolchain install "${toolchain}" --no-self-update --profile minimal -rustup default "${toolchain}" - -rustup -V -rustc -V -cargo -V diff --git a/examples/enum-default-expanded.rs b/examples/enum-default-expanded.rs index f234b51..2153592 100644 --- a/examples/enum-default-expanded.rs +++ b/examples/enum-default-expanded.rs @@ -45,10 +45,10 @@ const _: () = { ) -> EnumProj<'pin, T, U> { unsafe { match self.get_unchecked_mut() { - Enum::Pinned(_0) => { + Self::Pinned(_0) => { EnumProj::Pinned(::pin_project::__private::Pin::new_unchecked(_0)) } - Enum::Unpinned(_0) => EnumProj::Unpinned(_0), + Self::Unpinned(_0) => EnumProj::Unpinned(_0), } } } diff --git a/rustfmt.toml b/rustfmt.toml index 18c6d2a..75456c3 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -24,4 +24,6 @@ format_code_in_doc_comments = true # Set the default settings again to always apply the proper formatting without # being affected by the editor settings. edition = "2018" +hard_tabs = false +newline_style = "Unix" tab_spaces = 4 diff --git a/scripts/check-minimal-versions.sh b/scripts/check-minimal-versions.sh index 6c7fa7b..56fadee 100755 --- a/scripts/check-minimal-versions.sh +++ b/scripts/check-minimal-versions.sh @@ -3,7 +3,7 @@ # Check all public crates with minimal version dependencies. # # Usage: -# bash scripts/check-minimal-versions.sh +# bash scripts/check-minimal-versions.sh [+toolchain] [check|test] # # Note: # - This script modifies Cargo.toml and Cargo.lock while running @@ -13,19 +13,34 @@ # Refs: https://github.com/rust-lang/cargo/issues/5657 set -euo pipefail +IFS=$'\n\t' cd "$(cd "$(dirname "${0}")" && pwd)"/.. -if [[ "${1:-none}" == "+"* ]]; then - toolchain="${1}" -elif [[ "${CI:-false}" != "true" ]]; then - cargo +nightly -V >/dev/null || exit 1 - toolchain="+nightly" +# Decide Rust toolchain. +# Nightly is used by default if the `CI` environment variable is unset. +if [[ "${1:-}" == "+"* ]]; then + toolchain="${1}" + shift +elif [[ -z "${CI:-}" ]]; then + toolchain="+nightly" fi - +# Make sure toolchain is installed. +cargo ${toolchain:-} -V >/dev/null +# This script requires nightly Rust and cargo-hack if [[ "${toolchain:-+nightly}" != "+nightly"* ]] || ! cargo hack -V &>/dev/null; then - echo "error: check-minimal-versions.sh requires nightly Rust and cargo-hack" - exit 1 + echo "error: check-minimal-versions.sh requires nightly Rust and cargo-hack" + exit 1 +fi + +# Parse subcommand. +subcmd="${1:-check}" +if [[ ! "${subcmd}" =~ ^(check|test)$ ]]; then + echo "error: invalid argument: ${1}" + exit 1 +elif [[ -n "${2:-}" ]]; then + echo "error: invalid argument: ${2}" + exit 1 fi # This script modifies Cargo.toml and Cargo.lock, so make sure there are no @@ -34,11 +49,13 @@ git diff --exit-code # Restore original Cargo.toml and Cargo.lock on exit. trap 'git checkout .' EXIT -# Remove dev-dependencies from Cargo.toml to prevent the next `cargo update` -# from determining minimal versions based on dev-dependencies. -cargo hack --remove-dev-deps --workspace +if [[ "${subcmd}" == "check" ]]; then + # Remove dev-dependencies from Cargo.toml to prevent the next `cargo update` + # from determining minimal versions based on dev-dependencies. + cargo hack --remove-dev-deps --workspace +fi # Update Cargo.lock to minimal version dependencies. -cargo ${toolchain:-} update -Zminimal-versions +cargo ${toolchain:-} update -Z minimal-versions # Run check for all public members of the workspace. -cargo ${toolchain:-} hack check --workspace --all-features --ignore-private -Zfeatures=all +cargo ${toolchain:-} hack "${subcmd}" --workspace --all-features --ignore-private -Z features=all diff --git a/scripts/ci.sh b/scripts/ci.sh index ec08568..b6a1a74 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -8,30 +8,30 @@ # Note: This script requires nightly Rust, rustfmt, clippy, and cargo-expand set -euo pipefail +IFS=$'\n\t' -if [[ "${1:-none}" == "+"* ]]; then - toolchain="${1}" -else - cargo +nightly -V >/dev/null || exit 1 - toolchain="+nightly" +# Decide Rust toolchain. Nightly is used by default. +toolchain="+nightly" +if [[ "${1:-}" == "+"* ]]; then + toolchain="${1}" + shift fi +# Make sure toolchain is installed. +cargo "${toolchain}" -V >/dev/null if [[ "${toolchain:-+nightly}" != "+nightly"* ]] || ! rustfmt -V &>/dev/null || ! cargo clippy -V &>/dev/null || ! cargo expand -V &>/dev/null; then - echo "error: ci.sh requires nightly Rust, rustfmt, clippy, and cargo-expand" - exit 1 + echo "error: ci.sh requires nightly Rust, rustfmt, clippy, and cargo-expand" + exit 1 fi echo "Running 'cargo ${toolchain} fmt --all'" cargo "${toolchain}" fmt --all echo "Running 'cargo ${toolchain} clippy --all --all-targets'" -cargo "${toolchain}" clippy --all --all-features --all-targets -Zunstable-options +cargo "${toolchain}" clippy --all --all-features --all-targets -Z unstable-options -echo "Running 'cargo ${toolchain} test --all --exclude expandtest'" -TRYBUILD=overwrite cargo "${toolchain}" test --all --all-features --exclude expandtest - -echo "Running 'bash scripts/expandtest.sh ${toolchain}'" -"$(cd "$(dirname "${0}")" && pwd)"/expandtest.sh "${toolchain}" +echo "Running 'cargo ${toolchain} test --all'" +cargo "${toolchain}" test --all --all-features echo "Running 'cargo ${toolchain} doc --no-deps --all'" cargo "${toolchain}" doc --no-deps --all --all-features diff --git a/scripts/expandtest.sh b/scripts/expandtest.sh deleted file mode 100755 index 844ace6..0000000 --- a/scripts/expandtest.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -# A script to run expandtest. -# -# Usage: -# bash scripts/expandtest.sh -# -# Note: This script requires nightly Rust, rustfmt, and cargo-expand - -set -euo pipefail - -script_dir="$(cd "$(dirname "${0}")" && pwd)" - -if [[ "${1:-none}" == "+"* ]]; then - toolchain="${1}" -elif [[ "${CI:-false}" != "true" ]]; then - cargo +nightly -V >/dev/null || exit 1 - toolchain="+nightly" -fi - -if [[ "${toolchain:-+nightly}" != "+nightly"* ]] || ! rustfmt -V &>/dev/null || ! cargo expand -V &>/dev/null; then - echo "error: expandtest.sh requires nightly Rust, rustfmt, and cargo-expand" - exit 1 -fi - -if [[ "${CI:-false}" != "true" ]]; then - # First, check if the compile fails for another reason. - cargo ${toolchain} check --tests --manifest-path "${script_dir}"/../tests/expand/Cargo.toml - - # Next, remove the `*.expanded.rs` files to allow updating those files. - # Refs: https://docs.rs/macrotest/1/macrotest/#updating-expandedrs - rm -rf "${script_dir}"/../tests/expand/tests/expand/*.expanded.rs -fi - -cargo ${toolchain:-} test --manifest-path "${script_dir}"/../tests/expand/Cargo.toml diff --git a/src/lib.rs b/src/lib.rs index 016a0c7..39e8faa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ //! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs #![no_std] -#![doc(html_root_url = "https://docs.rs/pin-project/1.0.1")] +#![doc(html_root_url = "https://docs.rs/pin-project/1.0.2")] #![doc(test( no_crate_inject, attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code)) @@ -73,11 +73,14 @@ #![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)] #![warn(missing_docs)] #![warn(clippy::all, clippy::default_trait_access)] -// mem::take and #[non_exhaustive] requires Rust 1.40, matches! requires Rust 1.42 +// mem::take, #[non_exhaustive], and Option::{as_deref, as_deref_mut} require Rust 1.40, +// matches! requires Rust 1.42, str::{strip_prefix, strip_suffix} requires Rust 1.45 #![allow( clippy::mem_replace_with_default, clippy::manual_non_exhaustive, - clippy::match_like_matches_macro + clippy::option_as_ref_deref, + clippy::match_like_matches_macro, + clippy::manual_strip )] #![allow(clippy::needless_doctest_main)] diff --git a/src/lib.rs.orig b/src/lib.rs.orig new file mode 100644 index 0000000..5750c2b --- /dev/null +++ b/src/lib.rs.orig @@ -0,0 +1,288 @@ +//! A crate for safe and ergonomic [pin-projection]. +//! +//! # Examples +//! +//! [`#[pin_project]`][`pin_project`] attribute creates projection types +//! covering all the fields of struct or enum. +//! +//! ```rust +//! use pin_project::pin_project; +//! use std::pin::Pin; +//! +//! #[pin_project] +//! struct Struct { +//! #[pin] +//! pinned: T, +//! unpinned: U, +//! } +//! +//! impl Struct { +//! fn method(self: Pin<&mut Self>) { +//! let this = self.project(); +//! let _: Pin<&mut T> = this.pinned; // Pinned reference to the field +//! let _: &mut U = this.unpinned; // Normal reference to the field +//! } +//! } +//! ``` +//! +//! [*code like this will be generated*][struct-default-expanded] +//! +//! To use `#[pin_project]` on enums, you need to name the projection type +//! returned from the method. +//! +//! ```rust +//! use pin_project::pin_project; +//! use std::pin::Pin; +//! +//! #[pin_project(project = EnumProj)] +//! enum Enum { +//! Pinned(#[pin] T), +//! Unpinned(U), +//! } +//! +//! impl Enum { +//! fn method(self: Pin<&mut Self>) { +//! match self.project() { +//! EnumProj::Pinned(x) => { +//! let _: Pin<&mut T> = x; +//! } +//! EnumProj::Unpinned(y) => { +//! let _: &mut U = y; +//! } +//! } +//! } +//! } +//! ``` +//! +//! [*code like this will be generated*][enum-default-expanded] +//! +//! See [`#[pin_project]`][`pin_project`] attribute for more details, and +//! see [examples] directory for more examples and generated code. +//! +//! [examples]: https://github.com/taiki-e/pin-project/blob/master/examples/README.md +//! [enum-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/enum-default-expanded.rs +//! [pin-projection]: core::pin#projections-and-structural-pinning +//! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs + +#![no_std] +#![doc(html_root_url = "https://docs.rs/pin-project/1.0.2")] +#![doc(test( + no_crate_inject, + attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code)) +))] +#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)] +#![warn(missing_docs)] +#![warn(clippy::all, clippy::default_trait_access)] +// mem::take, #[non_exhaustive], and Option::{as_deref, as_deref_mut} require Rust 1.40, +// matches! requires Rust 1.42, str::{strip_prefix, strip_suffix} requires Rust 1.45 +#![allow( + clippy::mem_replace_with_default, + clippy::manual_non_exhaustive, + clippy::option_as_ref_deref, + clippy::match_like_matches_macro, + clippy::manual_strip +)] +#![allow(clippy::needless_doctest_main)] + +#[doc(inline)] +pub use pin_project_internal::pin_project; + +#[doc(inline)] +pub use pin_project_internal::pinned_drop; + +/// A trait used for custom implementations of [`Unpin`]. +/// +/// This trait is used in conjunction with the `UnsafeUnpin` argument to +/// the [`#[pin_project]`][macro@pin_project] attribute. +/// +/// The Rust [`Unpin`] trait is safe to implement - by itself, +/// implementing it cannot lead to [undefined behavior][undefined-behavior]. +/// Undefined behavior can only occur when other unsafe code is used. +/// +/// It turns out that using pin projections, which requires unsafe code, +/// imposes additional requirements on an [`Unpin`] impl. Normally, all of this +/// unsafety is contained within this crate, ensuring that it's impossible for +/// you to violate any of the guarantees required by pin projection. +/// +/// However, things change if you want to provide a custom [`Unpin`] impl +/// for your `#[pin_project]` type. As stated in [the Rust +/// documentation][pin-projection], you must be sure to only implement [`Unpin`] +/// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also +/// [`Unpin`]. +/// +/// To help highlight this unsafety, the `UnsafeUnpin` trait is provided. +/// Implementing this trait is logically equivalent to implementing [`Unpin`] - +/// this crate will generate an [`Unpin`] impl for your type that 'forwards' to +/// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type +/// uses structural pinning (otherwise, you wouldn't be using this crate!), +/// you must be sure that your `UnsafeUnpin` impls follows all of +/// the requirements for an [`Unpin`] impl of a structurally-pinned type. +/// +/// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not* +/// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`]. +/// This is effectively the same thing as adding a [`PhantomPinned`] to your +/// type. +/// +/// Since this trait is `unsafe`, impls of it will be detected by the +/// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger]. +/// +/// # Examples +/// +/// An `UnsafeUnpin` impl which, in addition to requiring that structurally +/// pinned fields be [`Unpin`], imposes an additional requirement: +/// +/// ```rust +/// use pin_project::{pin_project, UnsafeUnpin}; +/// +/// #[pin_project(UnsafeUnpin)] +/// struct Struct { +/// #[pin] +/// field_1: K, +/// field_2: V, +/// } +/// +/// unsafe impl UnsafeUnpin for Struct where K: Unpin + Clone {} +/// ``` +/// +/// [`PhantomPinned`]: core::marker::PhantomPinned +/// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger +/// [pin-projection]: core::pin#projections-and-structural-pinning +/// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html +pub unsafe trait UnsafeUnpin {} + +// Not public API. +#[doc(hidden)] +pub mod __private { + #[doc(hidden)] + pub use core::{ + marker::{PhantomData, PhantomPinned, Unpin}, + mem::ManuallyDrop, + ops::Drop, + pin::Pin, + ptr, + }; + + use super::UnsafeUnpin; + + #[doc(hidden)] + pub use pin_project_internal::__PinProjectInternalDerive; + + // An internal trait used for custom implementations of [`Drop`]. + // + // **Do not call or implement this trait directly.** + // + // # Why this trait is private and `#[pinned_drop]` attribute is needed? + // + // Implementing `PinnedDrop::drop` is safe, but calling it is not safe. + // This is because destructors can be called multiple times in safe code and + // [double dropping is unsound][rust-lang/rust#62360]. + // + // Ideally, it would be desirable to be able to forbid manual calls in + // the same way as [`Drop::drop`], but the library cannot do it. So, by using + // macros and replacing them with private traits, + // this crate prevent users from calling `PinnedDrop::drop` in safe code. + // + // This allows implementing [`Drop`] safely using `#[pinned_drop]`. + // Also by using the [`drop`] function just like dropping a type that directly + // implements [`Drop`], can drop safely a type that implements `PinnedDrop`. + // + // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360 + #[doc(hidden)] + pub trait PinnedDrop { + #[doc(hidden)] + unsafe fn drop(self: Pin<&mut Self>); + } + + // This is an internal helper struct used by `pin-project-internal`. + // This allows us to force an error if the user tries to provide + // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument. + // This is why we need Wrapper: + // + // Supposed we have the following code: + // + // ```rust + // #[pin_project(UnsafeUnpin)] + // struct MyStruct { + // #[pin] field: T + // } + // + // impl Unpin for MyStruct where MyStruct: UnsafeUnpin {} // generated by pin-project-internal + // impl Unpin for MyStruct where T: Copy // written by the user + // ``` + // + // We want this code to be rejected - the user is completely bypassing + // `UnsafeUnpin`, and providing an unsound Unpin impl in safe code! + // + // Unfortunately, the Rust compiler will accept the above code. + // Because MyStruct is declared in the same crate as the user-provided impl, + // the compiler will notice that `MyStruct: UnsafeUnpin` never holds. + // + // The solution is to introduce the `Wrapper` struct, which is defined + // in the `pin-project` crate. + // + // We now have code that looks like this: + // + // ```rust + // impl Unpin for MyStruct where Wrapper>: UnsafeUnpin {} // generated by pin-project-internal + // impl Unpin for MyStruct where T: Copy // written by the user + // ``` + // + // We also have `unsafe impl UnsafeUnpin for Wrapper where T: UnsafeUnpin {}` + // in the `pin-project` crate. + // + // Now, our generated impl has a bound involving a type defined in another + // crate - Wrapper. This will cause rust to conservatively assume that + // `Wrapper>: UnsafeUnpin` holds, in the interest of preserving + // forwards compatibility (in case such an impl is added for Wrapper in + // a new version of the crate). + // + // This will cause rust to reject any other `Unpin` impls for MyStruct, + // since it will assume that our generated impl could potentially apply in + // any situation. + // + // This achieves the desired effect - when the user writes + // `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of + // `UnsafeUnpin` (which is equivalent to making the type never implement + // Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to + // provide an impl of `Unpin` + #[doc(hidden)] + pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T); + + unsafe impl UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {} + + // This is an internal helper struct used by `pin-project-internal`. + // + // See https://github.com/taiki-e/pin-project/pull/53 for more details. + #[doc(hidden)] + pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData); + + impl Unpin for AlwaysUnpin<'_, T> {} + + // This is an internal helper used to ensure a value is dropped. + #[doc(hidden)] + pub struct UnsafeDropInPlaceGuard(pub *mut T); + + impl Drop for UnsafeDropInPlaceGuard { + fn drop(&mut self) { + unsafe { + ptr::drop_in_place(self.0); + } + } + } + + // This is an internal helper used to ensure a value is overwritten without + // its destructor being called. + #[doc(hidden)] + pub struct UnsafeOverwriteGuard { + pub value: ManuallyDrop, + pub target: *mut T, + } + + impl Drop for UnsafeOverwriteGuard { + fn drop(&mut self) { + unsafe { + ptr::write(self.target, ptr::read(&*self.value)); + } + } + } +} diff --git a/tests/cfg.rs b/tests/cfg.rs index 9fde697..2fdcfbb 100644 --- a/tests/cfg.rs +++ b/tests/cfg.rs @@ -37,9 +37,9 @@ fn cfg() { assert_unpin!(SameName); #[cfg(target_os = "linux")] - let _x = SameName { inner: Linux }; + let _ = SameName { inner: Linux }; #[cfg(not(target_os = "linux"))] - let _x = SameName { inner: Other }; + let _ = SameName { inner: Other }; #[pin_project(project_replace)] struct DifferentName { @@ -57,9 +57,9 @@ fn cfg() { assert_unpin!(DifferentName); #[cfg(target_os = "linux")] - let _x = DifferentName { l: Linux }; + let _ = DifferentName { l: Linux }; #[cfg(not(target_os = "linux"))] - let _x = DifferentName { o: Other }; + let _ = DifferentName { o: Other }; #[pin_project(project_replace)] struct TupleStruct( @@ -77,9 +77,9 @@ fn cfg() { assert_unpin!(TupleStruct); #[cfg(target_os = "linux")] - let _x = TupleStruct(Linux); + let _ = TupleStruct(Linux); #[cfg(not(target_os = "linux"))] - let _x = TupleStruct(Other); + let _ = TupleStruct(Other); // enums @@ -105,14 +105,14 @@ fn cfg() { assert_unpin!(Variant); #[cfg(target_os = "linux")] - let _x = Variant::Inner(Linux); + let _ = Variant::Inner(Linux); #[cfg(not(target_os = "linux"))] - let _x = Variant::Inner(Other); + let _ = Variant::Inner(Other); #[cfg(target_os = "linux")] - let _x = Variant::Linux(Linux); + let _ = Variant::Linux(Linux); #[cfg(not(target_os = "linux"))] - let _x = Variant::Other(Other); + let _ = Variant::Other(Other); #[pin_project( project = FieldProj, @@ -158,19 +158,19 @@ fn cfg() { assert_unpin!(Field); #[cfg(target_os = "linux")] - let _x = Field::SameName { inner: Linux }; + let _ = Field::SameName { inner: Linux }; #[cfg(not(target_os = "linux"))] - let _x = Field::SameName { inner: Other }; + let _ = Field::SameName { inner: Other }; #[cfg(target_os = "linux")] - let _x = Field::DifferentName { l: Linux }; + let _ = Field::DifferentName { l: Linux }; #[cfg(not(target_os = "linux"))] - let _x = Field::DifferentName { w: Other }; + let _ = Field::DifferentName { w: Other }; #[cfg(target_os = "linux")] - let _x = Field::TupleVariant(Linux); + let _ = Field::TupleVariant(Linux); #[cfg(not(target_os = "linux"))] - let _x = Field::TupleVariant(Other); + let _ = Field::TupleVariant(Other); } #[test] diff --git a/tests/compiletest.rs b/tests/compiletest.rs index be01ba8..057df7c 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -1,9 +1,16 @@ #![cfg(not(miri))] #![warn(rust_2018_idioms, single_use_lifetimes)] -#[rustversion::attr(not(nightly), ignore)] +use std::env; + +// Run `./dev.sh +$toolchain test --test compiletest` to update this. +#[rustversion::attr(before(2020-10-28), ignore)] // Note: This date is commit-date and the day before the toolchain date. #[test] fn ui() { + if env::var_os("CI").is_none() { + env::set_var("TRYBUILD", "overwrite"); + } + let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/cfg/*.rs"); t.compile_fail("tests/ui/not_unpin/*.rs"); diff --git a/tests/drop_order.rs b/tests/drop_order.rs index 1931b68..1557188 100644 --- a/tests/drop_order.rs +++ b/tests/drop_order.rs @@ -38,12 +38,14 @@ struct TupleUnpinned<'a>(D<'a>, D<'a>); #[pin_project(project_replace = EnumProj)] enum Enum<'a> { + #[allow(dead_code)] // false positive that fixed in Rust 1.38 StructPinned { #[pin] f1: D<'a>, #[pin] f2: D<'a>, }, + #[allow(dead_code)] // false positive that fixed in Rust 1.38 StructUnpinned { f1: D<'a>, f2: D<'a>, @@ -60,9 +62,9 @@ fn struct_pinned() { } { let c = Cell::new(0); - let mut _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) }); + let mut x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) }); } } @@ -74,9 +76,9 @@ fn struct_unpinned() { } { let c = Cell::new(0); - let mut _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) }); + let mut x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) }); } } @@ -88,9 +90,9 @@ fn tuple_pinned() { } { let c = Cell::new(0); - let mut _x = TuplePinned(D(&c, 1), D(&c, 2)); - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(TuplePinned(D(&c, 3), D(&c, 4))); + let mut x = TuplePinned(D(&c, 1), D(&c, 2)); + let y = Pin::new(&mut x); + let _z = y.project_replace(TuplePinned(D(&c, 3), D(&c, 4))); } } @@ -102,9 +104,9 @@ fn tuple_unpinned() { } { let c = Cell::new(0); - let mut _x = TupleUnpinned(D(&c, 1), D(&c, 2)); - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(TupleUnpinned(D(&c, 3), D(&c, 4))); + let mut x = TupleUnpinned(D(&c, 1), D(&c, 2)); + let y = Pin::new(&mut x); + let _z = y.project_replace(TupleUnpinned(D(&c, 3), D(&c, 4))); } } @@ -116,9 +118,9 @@ fn enum_struct() { } { let c = Cell::new(0); - let mut _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) }); + let mut x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) }); } { @@ -127,9 +129,9 @@ fn enum_struct() { } { let c = Cell::new(0); - let mut _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) }); + let mut x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) }; + let y = Pin::new(&mut x); + let _z = y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) }); } } @@ -141,9 +143,9 @@ fn enum_tuple() { } { let c = Cell::new(0); - let mut _x = Enum::TuplePinned(D(&c, 1), D(&c, 2)); - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(Enum::TuplePinned(D(&c, 3), D(&c, 4))); + let mut x = Enum::TuplePinned(D(&c, 1), D(&c, 2)); + let y = Pin::new(&mut x); + let _z = y.project_replace(Enum::TuplePinned(D(&c, 3), D(&c, 4))); } { @@ -152,8 +154,8 @@ fn enum_tuple() { } { let c = Cell::new(0); - let mut _x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2)); - let _y = Pin::new(&mut _x); - let _z = _y.project_replace(Enum::TupleUnpinned(D(&c, 3), D(&c, 4))); + let mut x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2)); + let y = Pin::new(&mut x); + let _z = y.project_replace(Enum::TupleUnpinned(D(&c, 3), D(&c, 4))); } } diff --git a/tests/include/basic-safe-part.rs b/tests/include/basic-safe-part.rs index c8d24bd..0b7c43e 100644 --- a/tests/include/basic-safe-part.rs +++ b/tests/include/basic-safe-part.rs @@ -8,10 +8,28 @@ pub struct DefaultStruct { pub unpinned: U, } +#[::pin_project::pin_project( + project = DefaultStructNamedProj, + project_ref = DefaultStructNamedProjRef, +)] +#[derive(Debug)] +pub struct DefaultStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, +} + #[::pin_project::pin_project] #[derive(Debug)] pub struct DefaultTupleStruct(#[pin] pub T, pub U); +#[::pin_project::pin_project( + project = DefaultTupleStructNamedProj, + project_ref = DefaultTupleStructNamedProjRef, +)] +#[derive(Debug)] +pub struct DefaultTupleStructNamed(#[pin] pub T, pub U); + #[::pin_project::pin_project( project = DefaultEnumProj, project_ref = DefaultEnumProjRef, @@ -78,10 +96,30 @@ pub struct ReplaceStruct { pub unpinned: U, } +#[::pin_project::pin_project( + project = ReplaceStructNamedProj, + project_ref = ReplaceStructNamedProjRef, + project_replace = ReplaceStructNamedProjOwn, +)] +#[derive(Debug)] +pub struct ReplaceStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, +} + #[::pin_project::pin_project(project_replace)] #[derive(Debug)] pub struct ReplaceTupleStruct(#[pin] pub T, pub U); +#[::pin_project::pin_project( + project = ReplaceTupleStructNamedProj, + project_ref = ReplaceTupleStructNamedProjRef, + project_replace = ReplaceTupleStructNamedProjOwn, +)] +#[derive(Debug)] +pub struct ReplaceTupleStructNamed(#[pin] pub T, pub U); + #[::pin_project::pin_project( project = ReplaceEnumProj, project_ref = ReplaceEnumProjRef, diff --git a/tests/lint.rs b/tests/lint.rs index 86cb121..c7f1380 100644 --- a/tests/lint.rs +++ b/tests/lint.rs @@ -54,10 +54,28 @@ pub mod basic { pub unpinned: U, } + #[::pin_project::pin_project( + project = DefaultStructNamedProj, + project_ref = DefaultStructNamedProjRef, + )] + #[derive(Debug)] + pub struct DefaultStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, + } + #[::pin_project::pin_project] #[derive(Debug)] pub struct DefaultTupleStruct(#[pin] pub T, pub U); + #[::pin_project::pin_project( + project = DefaultTupleStructNamedProj, + project_ref = DefaultTupleStructNamedProjRef, + )] + #[derive(Debug)] + pub struct DefaultTupleStructNamed(#[pin] pub T, pub U); + #[::pin_project::pin_project( project = DefaultEnumProj, project_ref = DefaultEnumProjRef, @@ -124,10 +142,30 @@ pub mod basic { pub unpinned: U, } + #[::pin_project::pin_project( + project = ReplaceStructNamedProj, + project_ref = ReplaceStructNamedProjRef, + project_replace = ReplaceStructNamedProjOwn, + )] + #[derive(Debug)] + pub struct ReplaceStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, + } + #[::pin_project::pin_project(project_replace)] #[derive(Debug)] pub struct ReplaceTupleStruct(#[pin] pub T, pub U); + #[::pin_project::pin_project( + project = ReplaceTupleStructNamedProj, + project_ref = ReplaceTupleStructNamedProjRef, + project_replace = ReplaceTupleStructNamedProjOwn, + )] + #[derive(Debug)] + pub struct ReplaceTupleStructNamed(#[pin] pub T, pub U); + #[::pin_project::pin_project( project = ReplaceEnumProj, project_ref = ReplaceEnumProjRef, @@ -223,6 +261,207 @@ pub mod forbid_unsafe { #![forbid(unsafe_code)] include!("include/basic-safe-part.rs"); + + pub mod inside_macro { + #[rustfmt::skip] + macro_rules! mac { + () => { + #[::pin_project::pin_project] + #[derive(Debug)] + pub struct DefaultStruct { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pin_project( + project = DefaultStructNamedProj, + project_ref = DefaultStructNamedProjRef, + )] + #[derive(Debug)] + pub struct DefaultStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pin_project] + #[derive(Debug)] + pub struct DefaultTupleStruct(#[pin] pub T, pub U); + + #[::pin_project::pin_project( + project = DefaultTupleStructNamedProj, + project_ref = DefaultTupleStructNamedProjRef, + )] + #[derive(Debug)] + pub struct DefaultTupleStructNamed(#[pin] pub T, pub U); + + #[::pin_project::pin_project( + project = DefaultEnumProj, + project_ref = DefaultEnumProjRef, + )] + #[derive(Debug)] + pub enum DefaultEnum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Tuple(#[pin] T, U), + Unit, + } + + #[::pin_project::pin_project(PinnedDrop)] + #[derive(Debug)] + pub struct PinnedDropStruct { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pinned_drop] + impl PinnedDrop for PinnedDropStruct { + fn drop(self: ::pin_project::__private::Pin<&mut Self>) {} + } + + #[::pin_project::pin_project(PinnedDrop)] + #[derive(Debug)] + pub struct PinnedDropTupleStruct(#[pin] pub T, pub U); + + #[::pin_project::pinned_drop] + impl PinnedDrop for PinnedDropTupleStruct { + fn drop(self: ::pin_project::__private::Pin<&mut Self>) {} + } + + #[::pin_project::pin_project( + PinnedDrop, + project = PinnedDropEnumProj, + project_ref = PinnedDropEnumProjRef, + )] + #[derive(Debug)] + pub enum PinnedDropEnum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Tuple(#[pin] T, U), + Unit, + } + + #[::pin_project::pinned_drop] + impl PinnedDrop for PinnedDropEnum { + fn drop(self: ::pin_project::__private::Pin<&mut Self>) {} + } + + #[::pin_project::pin_project(project_replace)] + #[derive(Debug)] + pub struct ReplaceStruct { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pin_project( + project = ReplaceStructNamedProj, + project_ref = ReplaceStructNamedProjRef, + project_replace = ReplaceStructNamedProjOwn, + )] + #[derive(Debug)] + pub struct ReplaceStructNamed { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pin_project(project_replace)] + #[derive(Debug)] + pub struct ReplaceTupleStruct(#[pin] pub T, pub U); + + #[::pin_project::pin_project( + project = ReplaceTupleStructNamedProj, + project_ref = ReplaceTupleStructNamedProjRef, + project_replace = ReplaceTupleStructNamedProjOwn, + )] + #[derive(Debug)] + pub struct ReplaceTupleStructNamed(#[pin] pub T, pub U); + + #[::pin_project::pin_project( + project = ReplaceEnumProj, + project_ref = ReplaceEnumProjRef, + project_replace = ReplaceEnumProjOwn, + )] + #[derive(Debug)] + pub enum ReplaceEnum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Tuple(#[pin] T, U), + Unit, + } + + #[::pin_project::pin_project(UnsafeUnpin)] + #[derive(Debug)] + pub struct UnsafeUnpinStruct { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pin_project(UnsafeUnpin)] + #[derive(Debug)] + pub struct UnsafeUnpinTupleStruct(#[pin] pub T, pub U); + + #[::pin_project::pin_project( + UnsafeUnpin, + project = UnsafeUnpinEnumProj, + project_ref = UnsafeUnpinEnumProjRef, + )] + #[derive(Debug)] + pub enum UnsafeUnpinEnum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Tuple(#[pin] T, U), + Unit, + } + + #[::pin_project::pin_project(!Unpin)] + #[derive(Debug)] + pub struct NotUnpinStruct { + #[pin] + pub pinned: T, + pub unpinned: U, + } + + #[::pin_project::pin_project(!Unpin)] + #[derive(Debug)] + pub struct NotUnpinTupleStruct(#[pin] pub T, pub U); + + #[::pin_project::pin_project( + !Unpin, + project = NotUnpinEnumProj, + project_ref = NotUnpinEnumProjRef, + )] + #[derive(Debug)] + pub enum NotUnpinEnum { + Struct { + #[pin] + pinned: T, + unpinned: U, + }, + Tuple(#[pin] T, U), + Unit, + } + }; + } + + mac!(); + } } pub mod box_pointers { @@ -782,32 +1021,34 @@ pub mod clippy_used_underscore_binding { } } +// Run `./dev.sh +$toolchain test --test lint` to update this. #[cfg(not(miri))] #[allow(box_pointers)] #[allow(clippy::restriction)] -#[rustversion::attr(not(nightly), ignore)] +#[rustversion::attr(before(2020-11-08), ignore)] // Note: This date is commit-date and the day before the toolchain date. #[test] fn check_lint_list() { - use std::{env, fs, path::PathBuf, process::Command, str}; + use std::{env, fs, path::Path, process::Command, str}; type Result> = std::result::Result; fn assert_eq(expected_path: &str, actual: &str) -> Result<()> { - let manifest_dir = env::var_os("CARGO_MANIFEST_DIR") - .map(PathBuf::from) - .expect("CARGO_MANIFEST_DIR not set"); - let expected_path = manifest_dir.join(expected_path); - let expected = fs::read_to_string(&expected_path)?; + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let expected_path = &manifest_dir.join(expected_path); + let expected = fs::read_to_string(expected_path)?; if expected != actual { - if env::var_os("CI").map_or(false, |v| v == "true") { - panic!( - "assertion failed:\n\nEXPECTED:\n{0}\n{1}\n{0}\n\nACTUAL:\n{0}\n{2}\n{0}\n", - "-".repeat(60), - expected, - actual, - ); + if env::var_os("CI").is_some() { + let actual_path = + &manifest_dir.join("target").join(expected_path.file_name().unwrap()); + fs::write(actual_path, actual)?; + let status = Command::new("git") + .args(&["--no-pager", "diff", "--no-index", "--"]) + .args(&[expected_path, actual_path]) + .status()?; + assert!(!status.success()); + panic!("assertion failed"); } else { - fs::write(&expected_path, actual)?; + fs::write(expected_path, actual)?; } } Ok(()) diff --git a/tests/lint.txt b/tests/lint.txt index e4c9f98..a258fb8 100644 --- a/tests/lint.txt +++ b/tests/lint.txt @@ -59,6 +59,7 @@ Lint checks provided by rustc: drop-bounds warn bounds of the form `T: Drop` are useless ellipsis-inclusive-range-patterns warn `...` range patterns are deprecated exported-private-dependencies warn public interface leaks type from a private dependency + function-item-references warn suggest casting to a function pointer when attempting to take references to function items illegal-floating-point-literal-pattern warn floating-point literals cannot be used in patterns improper-ctypes warn proper use of libc types in foreign modules improper-ctypes-definitions warn proper use of libc types in foreign item definitions @@ -72,6 +73,7 @@ Lint checks provided by rustc: mixed-script-confusables warn detects Unicode scripts whose mixed script confusables codepoints are solely used mutable-borrow-reservation-conflict warn reservation of a two-phased borrow conflicts with other shared borrows nontrivial-structural-match warn constant used in pattern of non-structural-match type and the constant's initializer expression contains values of non-structural-match types + non-autolinks warn detects URLs that could be written using only angle brackets non-camel-case-types warn types, variants, traits and type parameters should have camel case names non-shorthand-field-patterns warn using `Struct { x: x }` instead of `Struct { x }` in a pattern non-snake-case warn variables, methods, functions, lifetime parameters and modules should have snake case names @@ -79,17 +81,20 @@ Lint checks provided by rustc: no-mangle-generic-items warn generic items must be mangled overlapping-patterns warn detects overlapping patterns path-statements warn path statements with no effect + private-intra-doc-links warn linking from a public item to a private one private-in-public warn detect private items in public interfaces not caught by the old implementation proc-macro-derive-resolution-fallback warn detects proc macro derives using inaccessible names from parent modules redundant-semicolons warn detects unnecessary trailing semicolons renamed-and-removed-lints warn lints that have been renamed or removed safe-packed-borrows warn safe borrows of fields of packed structs were erroneously allowed stable-features warn stable features found in `#[feature]` directive + temporary-cstring-as-ptr warn detects getting the inner pointer of a temporary `CString` trivial-bounds warn these bounds don't depend on an type parameters type-alias-bounds warn bounds in type aliases are not enforced tyvar-behind-raw-pointer warn raw pointer to an inference variable uncommon-codepoints warn detects uncommon Unicode codepoints in identifiers unconditional-recursion warn functions that cannot return without calling themselves + uninhabited-static warn uninhabited static unknown-lints warn unrecognized lint attribute unnameable-test-items warn detects an item that cannot be named being marked as `#[test_case]` unreachable-code warn detects unreachable code paths @@ -130,6 +135,7 @@ Lint checks provided by rustc: soft-unstable deny a feature gate that doesn't break dependent crates unconditional-panic deny operation will cause a panic at runtime unknown-crate-types deny unknown crate type found in `#[crate_type]` directive + useless-deprecated deny detects deprecation attributes with no effect Lint groups provided by rustc: @@ -137,11 +143,11 @@ Lint groups provided by rustc: name sub-lints ---- --------- warnings all lints that are set to issue warnings - future-incompatible keyword-idents, anonymous-parameters, illegal-floating-point-literal-pattern, private-in-public, pub-use-of-private-extern-crate, invalid-type-param-default, safe-packed-borrows, patterns-in-fns-without-body, late-bound-lifetime-arguments, order-dependent-trait-objects, coherence-leak-check, tyvar-behind-raw-pointer, absolute-paths-not-starting-with-crate, unstable-name-collisions, where-clauses-object-safety, proc-macro-derive-resolution-fallback, macro-expanded-macro-exports-accessed-by-absolute-paths, ill-formed-attribute-input, conflicting-repr-hints, ambiguous-associated-items, mutable-borrow-reservation-conflict, indirect-structural-match, pointer-structural-match, nontrivial-structural-match, soft-unstable, cenum-impl-drop-cast, const-evaluatable-unchecked, array-into-iter + future-incompatible keyword-idents, anonymous-parameters, illegal-floating-point-literal-pattern, private-in-public, pub-use-of-private-extern-crate, invalid-type-param-default, safe-packed-borrows, patterns-in-fns-without-body, late-bound-lifetime-arguments, order-dependent-trait-objects, coherence-leak-check, tyvar-behind-raw-pointer, absolute-paths-not-starting-with-crate, unstable-name-collisions, where-clauses-object-safety, proc-macro-derive-resolution-fallback, macro-expanded-macro-exports-accessed-by-absolute-paths, ill-formed-attribute-input, conflicting-repr-hints, ambiguous-associated-items, mutable-borrow-reservation-conflict, indirect-structural-match, pointer-structural-match, nontrivial-structural-match, soft-unstable, cenum-impl-drop-cast, const-evaluatable-unchecked, uninhabited-static, array-into-iter nonstandard-style non-camel-case-types, non-snake-case, non-upper-case-globals rust-2018-compatibility keyword-idents, anonymous-parameters, tyvar-behind-raw-pointer, absolute-paths-not-starting-with-crate rust-2018-idioms bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements - rustdoc broken-intra-doc-links, private-intra-doc-links, invalid-codeblock-attributes, missing-doc-code-examples, private-doc-tests, invalid-html-tags + rustdoc non-autolinks, broken-intra-doc-links, private-intra-doc-links, invalid-codeblock-attributes, missing-doc-code-examples, private-doc-tests, invalid-html-tags unused unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, overlapping-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons diff --git a/tests/pin_project.rs b/tests/pin_project.rs index d9c37e5..17dbd2a 100644 --- a/tests/pin_project.rs +++ b/tests/pin_project.rs @@ -28,31 +28,34 @@ fn projection() { let mut s_orig = Pin::new(&mut s); let s = s_orig.as_mut().project(); - let x: Pin<&mut i32> = s.f1; - assert_eq!(*x, 1); - let y: &mut i32 = s.f2; - assert_eq!(*y, 2); + let _: Pin<&mut i32> = s.f1; + assert_eq!(*s.f1, 1); + let _: &mut i32 = s.f2; + assert_eq!(*s.f2, 2); assert_eq!(s_orig.as_ref().f1, 1); assert_eq!(s_orig.as_ref().f2, 2); let mut s = Struct { f1: 1, f2: 2 }; - - let StructProj { f1, f2 } = Pin::new(&mut s).project(); - let _: Pin<&mut i32> = f1; - let _: &mut i32 = f2; - - let StructProjRef { f1, f2 } = Pin::new(&s).project_ref(); - let _: Pin<&i32> = f1; - let _: &i32 = f2; - let mut s = Pin::new(&mut s); - let StructProjOwn { f1, f2 } = s.as_mut().project_replace(Struct { f1: 3, f2: 4 }); - let _: PhantomData = f1; - let _: i32 = f2; - assert_eq!(f2, 2); - assert_eq!(s.f1, 3); - assert_eq!(s.f2, 4); + { + let StructProj { f1, f2 } = s.as_mut().project(); + let _: Pin<&mut i32> = f1; + let _: &mut i32 = f2; + } + { + let StructProjRef { f1, f2 } = s.as_ref().project_ref(); + let _: Pin<&i32> = f1; + let _: &i32 = f2; + } + { + let StructProjOwn { f1, f2 } = s.as_mut().project_replace(Struct { f1: 3, f2: 4 }); + let _: PhantomData = f1; + let _: i32 = f2; + assert_eq!(f2, 2); + assert_eq!(s.f1, 3); + assert_eq!(s.f2, 4); + } #[pin_project(project_replace)] struct TupleStruct(#[pin] T, U); @@ -60,10 +63,10 @@ fn projection() { let mut s = TupleStruct(1, 2); let s = Pin::new(&mut s).project(); - let x: Pin<&mut i32> = s.0; - assert_eq!(*x, 1); - let y: &mut i32 = s.1; - assert_eq!(*y, 2); + let _: Pin<&mut i32> = s.0; + assert_eq!(*s.0, 1); + let _: &mut i32 = s.1; + assert_eq!(*s.1, 2); #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)] #[derive(Eq, PartialEq, Debug)] @@ -78,10 +81,9 @@ fn projection() { } let mut e = Enum::Tuple(1, 2); - let mut e_orig = Pin::new(&mut e); - let e = e_orig.as_mut().project(); + let mut e = Pin::new(&mut e); - match e { + match e.as_mut().project() { EnumProj::Tuple(x, y) => { let x: Pin<&mut i32> = x; assert_eq!(*x, 1); @@ -91,34 +93,36 @@ fn projection() { EnumProj::Struct { f1, f2 } => { let _: Pin<&mut i32> = f1; let _: &mut i32 = f2; + unreachable!() } - EnumProj::Unit => {} + EnumProj::Unit => unreachable!(), } - assert_eq!(Pin::into_ref(e_orig).get_ref(), &Enum::Tuple(1, 2)); + assert_eq!(&*e, &Enum::Tuple(1, 2)); let mut e = Enum::Struct { f1: 3, f2: 4 }; - let mut e = Pin::new(&mut e).project(); + let mut e = Pin::new(&mut e); - match &mut e { + match e.as_mut().project() { EnumProj::Tuple(x, y) => { - let _: &mut Pin<&mut i32> = x; - let _: &mut &mut i32 = y; + let _: Pin<&mut i32> = x; + let _: &mut i32 = y; + unreachable!() } EnumProj::Struct { f1, f2 } => { - let x: &mut Pin<&mut i32> = f1; - assert_eq!(**x, 3); - let y: &mut &mut i32 = f2; - assert_eq!(**y, 4); + let _: Pin<&mut i32> = f1; + assert_eq!(*f1, 3); + let _: &mut i32 = f2; + assert_eq!(*f2, 4); } - EnumProj::Unit => {} + EnumProj::Unit => unreachable!(), } - if let EnumProj::Struct { f1, f2 } = e { - let x: Pin<&mut i32> = f1; - assert_eq!(*x, 3); - let y: &mut i32 = f2; - assert_eq!(*y, 4); + if let EnumProj::Struct { f1, f2 } = e.as_mut().project() { + let _: Pin<&mut i32> = f1; + assert_eq!(*f1, 3); + let _: &mut i32 = f2; + assert_eq!(*f2, 4); } } @@ -140,7 +144,7 @@ fn enum_project_set() { let new_e = Enum::V2(val.as_ref().get_ref() == &25); e_orig.set(new_e); } - _ => unreachable!(), + EnumProj::V2(_) => unreachable!(), } assert_eq!(e, Enum::V2(true)); @@ -288,7 +292,7 @@ fn trait_bounds_on_type_generics() { f: &'a mut T, } - let _: Struct6<'_> = Struct6 { f: &mut [0u8; 16] }; + let _: Struct6<'_> = Struct6 { f: &mut [0_u8; 16] }; #[pin_project(project_replace)] pub struct Struct7 { @@ -433,7 +437,7 @@ fn lifetime_project() { #[pin_project(project_replace)] struct Struct2<'a, T, U> { #[pin] - pinned: &'a mut T, + pinned: &'a T, unpinned: U, } @@ -462,16 +466,16 @@ fn lifetime_project() { } impl<'b, T, U> Struct2<'b, T, U> { - fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b mut T> { + fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b T> { self.project_ref().pinned } - fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b mut T> { + fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b T> { self.project().pinned } - fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&&'b mut T> { + fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&&'b T> { self.project_ref().pinned } - fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut &'b mut T> { + fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut &'b T> { self.project().pinned } } diff --git a/tests/pinned_drop.rs b/tests/pinned_drop.rs index e369ecb..78b73dc 100644 --- a/tests/pinned_drop.rs +++ b/tests/pinned_drop.rs @@ -201,19 +201,19 @@ fn self_ty_inside_macro_call() { } impl Struct { - const ASSOC1: &'static str = "1"; + const ASSOC1: usize = 1; fn assoc1() {} } trait Trait { type Assoc2; - const ASSOC2: &'static str; + const ASSOC2: usize; fn assoc2(); } impl Trait for Struct { type Assoc2 = (); - const ASSOC2: &'static str = "2"; + const ASSOC2: usize = 2; fn assoc2() {} } diff --git a/tests/proper_unpin.rs b/tests/proper_unpin.rs index ce2a6c8..8873572 100644 --- a/tests/proper_unpin.rs +++ b/tests/proper_unpin.rs @@ -16,16 +16,30 @@ pub mod default { assert_not_unpin!(Inner); #[pin_project] - struct Foo { + struct Struct { #[pin] f1: Inner, f2: U, } - assert_unpin!(Foo<(), ()>); - assert_unpin!(Foo<(), PhantomPinned>); - assert_not_unpin!(Foo); - assert_not_unpin!(Foo); + assert_unpin!(Struct<(), ()>); + assert_unpin!(Struct<(), PhantomPinned>); + assert_not_unpin!(Struct); + assert_not_unpin!(Struct); + + #[pin_project(project = EnumProj, project_ref = EnumProjRef)] + enum Enum { + V1 { + #[pin] + f1: Inner, + f2: U, + }, + } + + assert_unpin!(Enum<(), ()>); + assert_unpin!(Enum<(), PhantomPinned>); + assert_not_unpin!(Enum); + assert_not_unpin!(Enum); #[pin_project] struct TrivialBounds { @@ -36,13 +50,13 @@ pub mod default { assert_not_unpin!(TrivialBounds); #[pin_project] - struct Bar<'a, T, U> { + struct PinRef<'a, T, U> { #[pin] f1: &'a mut Inner, f2: U, } - assert_unpin!(Bar<'_, PhantomPinned, PhantomPinned>); + assert_unpin!(PinRef<'_, PhantomPinned, PhantomPinned>); } pub mod cfg { @@ -105,16 +119,16 @@ pub mod not_unpin { } #[pin_project(!Unpin)] - struct Foo { + struct Struct { #[pin] inner: Inner, other: U, } - assert_not_unpin!(Foo<(), ()>); - assert_not_unpin!(Foo<(), PhantomPinned>); - assert_not_unpin!(Foo); - assert_not_unpin!(Foo); + assert_not_unpin!(Struct<(), ()>); + assert_not_unpin!(Struct<(), PhantomPinned>); + assert_not_unpin!(Struct); + assert_not_unpin!(Struct); #[pin_project(!Unpin)] struct TrivialBounds { @@ -125,11 +139,11 @@ pub mod not_unpin { assert_not_unpin!(TrivialBounds); #[pin_project(!Unpin)] - struct Bar<'a, T, U> { + struct PinRef<'a, T, U> { #[pin] inner: &'a mut Inner, other: U, } - assert_not_unpin!(Bar<'_, (), ()>); + assert_not_unpin!(PinRef<'_, (), ()>); } diff --git a/tests/ui/cfg/cfg_attr-resolve.rs b/tests/ui/cfg/cfg_attr-resolve.rs index c7a246a..e36cc95 100644 --- a/tests/ui/cfg/cfg_attr-resolve.rs +++ b/tests/ui/cfg/cfg_attr-resolve.rs @@ -7,5 +7,5 @@ struct Foo { fn main() { let mut x = Foo { f: 0_u8 }; - let _x = Pin::new(&mut x).project(); //~ ERROR E0599 + let _ = Pin::new(&mut x).project(); //~ ERROR E0599 } diff --git a/tests/ui/cfg/cfg_attr-resolve.stderr b/tests/ui/cfg/cfg_attr-resolve.stderr index ee1fa03..12bcc67 100644 --- a/tests/ui/cfg/cfg_attr-resolve.stderr +++ b/tests/ui/cfg/cfg_attr-resolve.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `project` found for struct `Pin<&mut Foo>` in the current scope - --> $DIR/cfg_attr-resolve.rs:10:31 + --> $DIR/cfg_attr-resolve.rs:10:30 | -10 | let _x = Pin::new(&mut x).project(); //~ ERROR E0599 - | ^^^^^^^ method not found in `Pin<&mut Foo>` +10 | let _ = Pin::new(&mut x).project(); //~ ERROR E0599 + | ^^^^^^^ method not found in `Pin<&mut Foo>` diff --git a/tests/ui/pin_project/packed-enum.stderr b/tests/ui/pin_project/packed-enum.stderr index 0a5d31b..afc8b30 100644 --- a/tests/ui/pin_project/packed-enum.stderr +++ b/tests/ui/pin_project/packed-enum.stderr @@ -1,4 +1,4 @@ -error[E0517]: attribute should be applied to struct or union +error[E0517]: attribute should be applied to a struct or union --> $DIR/packed-enum.rs:3:8 | 3 | #[repr(packed)] //~ ERROR E0517 @@ -8,7 +8,7 @@ error[E0517]: attribute should be applied to struct or union 6 | | } | |_- not a struct or union -error[E0517]: attribute should be applied to struct or union +error[E0517]: attribute should be applied to a struct or union --> $DIR/packed-enum.rs:9:8 | 9 | #[repr(packed)] //~ ERROR E0517 @@ -18,7 +18,7 @@ error[E0517]: attribute should be applied to struct or union 12 | | } | |_- not a struct or union -error[E0517]: attribute should be applied to struct or union +error[E0517]: attribute should be applied to a struct or union --> $DIR/packed-enum.rs:14:8 | 14 | #[repr(packed)] //~ ERROR E0517 diff --git a/tests/ui/pin_project/private_in_public-enum.stderr b/tests/ui/pin_project/private_in_public-enum.stderr index a14756b..6e3316c 100644 --- a/tests/ui/pin_project/private_in_public-enum.stderr +++ b/tests/ui/pin_project/private_in_public-enum.stderr @@ -5,7 +5,7 @@ error[E0446]: private type `PrivateEnum` in public interface | ^^^^^^^^^^^ can't leak private type ... 9 | enum PrivateEnum { - | - `PrivateEnum` declared as private + | ---------------- `PrivateEnum` declared as private error[E0446]: private type `foo::PrivateEnum` in public interface --> $DIR/private_in_public-enum.rs:15:11 @@ -14,4 +14,4 @@ error[E0446]: private type `foo::PrivateEnum` in public interface | ^^^^^^^^^^^ can't leak private type ... 18 | enum PrivateEnum { - | - `foo::PrivateEnum` declared as private + | ---------------- `foo::PrivateEnum` declared as private diff --git a/tests/ui/pin_project/project_replace_unsized.stderr b/tests/ui/pin_project/project_replace_unsized.stderr index b6ecb1b..e40db5f 100644 --- a/tests/ui/pin_project/project_replace_unsized.stderr +++ b/tests/ui/pin_project/project_replace_unsized.stderr @@ -7,7 +7,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim | - this type parameter needs to be `Sized` | = note: required because it appears within the type `Struct` - = help: unsized locals are gated as an unstable feature + = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | 3 | #[pin_project(&project_replace)] //~ ERROR E0277 @@ -42,7 +42,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim | - this type parameter needs to be `Sized` | = note: required because it appears within the type `TupleStruct` - = help: unsized locals are gated as an unstable feature + = help: unsized fn params are gated as an unstable feature help: function arguments must have a statically known size, borrowed types always have a known size | 8 | #[pin_project(&project_replace)] //~ ERROR E0277 @@ -67,4 +67,4 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim | doesn't have a size known at compile-time | = note: all function arguments must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized fn params are gated as an unstable feature diff --git a/tests/ui/pin_project/project_replace_unsized_fn_params.rs b/tests/ui/pin_project/project_replace_unsized_fn_params.rs new file mode 100644 index 0000000..e0fa25b --- /dev/null +++ b/tests/ui/pin_project/project_replace_unsized_fn_params.rs @@ -0,0 +1,13 @@ +#![feature(unsized_fn_params)] + +use pin_project::pin_project; + +#[pin_project(project_replace)] //~ ERROR E0277 +struct Struct { + f: T, +} + +#[pin_project(project_replace)] //~ ERROR E0277 +struct TupleStruct(T); + +fn main() {} diff --git a/tests/ui/pin_project/project_replace_unsized_fn_params.stderr b/tests/ui/pin_project/project_replace_unsized_fn_params.stderr new file mode 100644 index 0000000..622d12f --- /dev/null +++ b/tests/ui/pin_project/project_replace_unsized_fn_params.stderr @@ -0,0 +1,53 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/project_replace_unsized_fn_params.rs:6:8 + | +6 | struct Struct { + | ^^^^^^^-^^^^^^^^^ + | | | + | | this type parameter needs to be `Sized` + | doesn't have a size known at compile-time + | + = note: required because it appears within the type `__StructProjectionOwned` + = note: the return type of a function must have a statically known size + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/project_replace_unsized_fn_params.rs:7:5 + | +6 | struct Struct { + | - this type parameter needs to be `Sized` +7 | f: T, + | ^ doesn't have a size known at compile-time + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/project_replace_unsized_fn_params.rs:5:1 + | +5 | #[pin_project(project_replace)] //~ ERROR E0277 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time +6 | struct Struct { + | - this type parameter needs to be `Sized` + | + = note: required because it appears within the type `__StructProjectionOwned` + = note: structs must have a statically known size to be initialized + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/project_replace_unsized_fn_params.rs:11:8 + | +11 | struct TupleStruct(T); + | ^^^^^^^^^^^^-^^^^^^^^^ + | | | + | | this type parameter needs to be `Sized` + | doesn't have a size known at compile-time + | + = note: required because it appears within the type `__TupleStructProjectionOwned` + = note: the return type of a function must have a statically known size + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/project_replace_unsized_fn_params.rs:10:1 + | +10 | #[pin_project(project_replace)] //~ ERROR E0277 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time +11 | struct TupleStruct(T); + | - this type parameter needs to be `Sized` + | + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/pin_project/project_replace_unsized_locals.rs b/tests/ui/pin_project/project_replace_unsized_locals.rs deleted file mode 100644 index 7e28e2c..0000000 --- a/tests/ui/pin_project/project_replace_unsized_locals.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(unsized_locals)] - -use pin_project::pin_project; - -#[pin_project(project_replace)] //~ ERROR E0277 -struct Struct { - f: T, -} - -#[pin_project(project_replace)] //~ ERROR E0277 -struct TupleStruct(T); - -fn main() {} diff --git a/tests/ui/pin_project/project_replace_unsized_locals.stderr b/tests/ui/pin_project/project_replace_unsized_locals.stderr deleted file mode 100644 index ad965e5..0000000 --- a/tests/ui/pin_project/project_replace_unsized_locals.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/project_replace_unsized_locals.rs:6:8 - | -6 | struct Struct { - | ^^^^^^^-^^^^^^^^^ - | | | - | | this type parameter needs to be `Sized` - | doesn't have a size known at compile-time - | - = note: required because it appears within the type `__StructProjectionOwned` - = note: the return type of a function must have a statically known size - -error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/project_replace_unsized_locals.rs:7:5 - | -6 | struct Struct { - | - this type parameter needs to be `Sized` -7 | f: T, - | ^ doesn't have a size known at compile-time - -error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/project_replace_unsized_locals.rs:5:1 - | -5 | #[pin_project(project_replace)] //~ ERROR E0277 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time -6 | struct Struct { - | - this type parameter needs to be `Sized` - | - = note: required because it appears within the type `__StructProjectionOwned` - = note: structs must have a statically known size to be initialized - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/project_replace_unsized_locals.rs:11:8 - | -11 | struct TupleStruct(T); - | ^^^^^^^^^^^^-^^^^^^^^^ - | | | - | | this type parameter needs to be `Sized` - | doesn't have a size known at compile-time - | - = note: required because it appears within the type `__TupleStructProjectionOwned` - = note: the return type of a function must have a statically known size - -error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/project_replace_unsized_locals.rs:10:1 - | -10 | #[pin_project(project_replace)] //~ ERROR E0277 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time -11 | struct TupleStruct(T); - | - this type parameter needs to be `Sized` - | - = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/pinned_drop/call-drop-inner.stderr b/tests/ui/pinned_drop/call-drop-inner.stderr index eb55ce7..53194b0 100644 --- a/tests/ui/pinned_drop/call-drop-inner.stderr +++ b/tests/ui/pinned_drop/call-drop-inner.stderr @@ -1,10 +1,14 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/call-drop-inner.rs:12:9 | -9 | #[pinned_drop] - | -------------- defined here -... 12 | __drop_inner(__self); | ^^^^^^^^^^^^ ------ supplied 1 argument | | | expected 0 arguments + | +note: function defined here + --> $DIR/call-drop-inner.rs:9:1 + | +9 | #[pinned_drop] + | ^^^^^^^^^^^^^^ + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) -- cgit v1.2.3