├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .idea ├── $CACHE_FILE$ ├── .gitignore ├── misc.xml ├── modules.xml ├── nonzero_ext.iml ├── runConfigurations │ ├── doc.xml │ ├── test__nightly__no_std_.xml │ ├── test__nightly__std_.xml │ ├── test__stable__no_std_.xml │ └── test__stable__std_.xml └── vcs.xml ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.toml ├── CoC.md ├── LICENSE.txt ├── README.md ├── bors.toml ├── deny.toml ├── release.toml ├── src ├── lib.rs └── literals.rs └── tests ├── compile-fail_1.45 ├── immoral_math.rs ├── immoral_math.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compile-fail_1.46 ├── immoral_math.rs ├── immoral_math.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compile-fail_1.48 ├── immoral_math.rs ├── immoral_math.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compile-fail_1.54 ├── immoral_math.rs ├── immoral_math.stderr ├── issue-17--adverse-conditions.rs ├── issue-17--adverse-conditions.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compile-fail_1.56 ├── immoral_math.rs ├── immoral_math.stderr ├── issue-17--adverse-conditions.rs ├── issue-17--adverse-conditions.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compile-fail_1.62 ├── immoral_math.rs ├── immoral_math.stderr ├── issue-17--adverse-conditions.rs ├── issue-17--adverse-conditions.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compile-fail_nightly ├── immoral_math.rs ├── immoral_math.stderr ├── zero_u8.rs ├── zero_u8.stderr ├── zero_usize.rs └── zero_usize.stderr ├── compiletest.rs ├── macro.rs └── run-pass ├── const_expression.rs ├── negative_i32.rs ├── nonzero_isize.rs ├── nonzero_usize.rs └── virtuous_math.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: "CI" 2 | # This workflow is triggered on all pushes to the repository, or on Friday night. 3 | on: 4 | pull_request: {} 5 | push: 6 | branches: 7 | - master 8 | - staging 9 | - trying 10 | schedule: 11 | - cron: '0 23 * * FRI' 12 | 13 | jobs: 14 | test: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | # We don't care about nightly with its regular/unstable 19 | # changes to diagnostics, but beta could potentially break 20 | # compatibility in the next release. 21 | rust_toolchain: [beta, stable] 22 | cargo_args: 23 | - "" 24 | steps: 25 | - uses: actions/checkout@v2.3.4 26 | - uses: actions-rs/toolchain@v1 27 | with: 28 | toolchain: ${{ matrix.rust_toolchain }} 29 | override: true 30 | profile: minimal 31 | - name: "cargo test" 32 | uses: actions-rs/cargo@v1 33 | with: 34 | command: test 35 | args: ${{ matrix.cargo_args }} 36 | toolchain: ${{ matrix.rust_toolchain }} 37 | 38 | all_tests: 39 | needs: test 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Mark the job as a success 43 | run: exit 0 44 | 45 | rustfmt: 46 | runs-on: ubuntu-latest 47 | steps: 48 | - uses: actions/checkout@v2.3.4 49 | - name: "cargo fmt" 50 | uses: actions-rs/cargo@v1 51 | with: 52 | command: fmt 53 | args: "-v -- --check" 54 | 55 | cargo_deny: 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: actions/checkout@v2.3.4 59 | - name: "cargo deny" 60 | uses: EmbarkStudios/cargo-deny-action@v1 61 | with: 62 | command: "check all" 63 | 64 | cargo_clippy: 65 | runs-on: ubuntu-latest 66 | steps: 67 | - uses: actions/checkout@v2.3.4 68 | - name: "cargo clippy" 69 | uses: actions-rs/clippy-check@v1 70 | with: 71 | token: ${{ secrets.GITHUB_TOKEN }} 72 | args: -- -D warnings 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock -------------------------------------------------------------------------------- /.idea/$CACHE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Naming conventionsRust 10 | 11 | 12 | Rust 13 | 14 | 15 | 16 | 17 | Buildout 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/nonzero_ext.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/runConfigurations/doc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/runConfigurations/test__nightly__no_std_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/runConfigurations/test__nightly__std_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/runConfigurations/test__stable__no_std_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/runConfigurations/test__stable__std_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # TemplateCIConfig { bench: BenchEntry { run: false, version: "nightly", allow_failure: false, install_commandline: None, commandline: "cargo bench" }, clippy: ClippyEntry { run: true, version: "nightly", allow_failure: false, install_commandline: None, commandline: "cargo clippy -- -D warnings" }, rustfmt: RustfmtEntry { run: true, version: "stable", allow_failure: false, install_commandline: None, commandline: "cargo fmt" }, additional_matrix_entries: {}, cache: "false", os: "linux", dist: "xenial", versions: ["stable", "beta", "nightly"], test_commandline: "cargo test --all --features \"compiletest_rs $TRAVIS_RUST_VERSION\"" } 2 | os: 3 | - "linux" 4 | dist: "xenial" 5 | 6 | language: rust 7 | sudo: required 8 | cache: false 9 | 10 | rust: 11 | - stable 12 | - beta 13 | - nightly 14 | 15 | env: 16 | global: 17 | - RUN_TEST=true 18 | - RUN_CLIPPY=false 19 | - RUN_BENCH=false 20 | 21 | matrix: 22 | fast_finish: true 23 | include: 24 | - &rustfmt_build 25 | rust: "stable" 26 | env: 27 | - RUN_RUSTFMT=true 28 | - RUN_TEST=false 29 | - &clippy_build 30 | rust: "nightly" 31 | env: 32 | - RUN_CLIPPY=true 33 | - RUN_TEST=false 34 | allow_failures: [] 35 | 36 | before_script: 37 | - bash -c 'if [[ "$RUN_RUSTFMT" == "true" ]]; then 38 | rustup component add rustfmt-preview 39 | ; 40 | fi' 41 | - bash -c 'if [[ "$RUN_CLIPPY" == "true" ]]; then 42 | rm -f ~/.cargo/bin/clippy; 43 | rustup component add clippy-preview 44 | ; 45 | fi' 46 | 47 | script: 48 | - bash -c 'if [[ "$RUN_TEST" == "true" ]]; then 49 | cargo test --all --features "compiletest_rs $TRAVIS_RUST_VERSION" 50 | ; 51 | fi' 52 | - bash -c 'if [[ "$RUN_RUSTFMT" == "true" ]]; then 53 | cargo fmt -v -- --check 54 | ; 55 | fi' 56 | - bash -c 'if [[ "$RUN_CLIPPY" == "true" ]]; then 57 | cargo clippy -- -D warnings 58 | ; 59 | fi' 60 | 61 | branches: 62 | only: 63 | # release tags 64 | - /^v\d+\.\d+\.\d+.*$/ 65 | - master 66 | 67 | notifications: 68 | email: 69 | on_success: never 70 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changes for `nonzero_ext` 2 | 3 | 4 | 5 | ## [Unreleased] - ReleaseDate 6 | 7 | ## [0.3.0] - 2021-08-21 8 | 9 | ### Changed 10 | * The `nonzero!` macro now enforces that its arguments are integer 11 | literals. Any other non-zeroable types (even if they implement 12 | `nonzero_ext::NonZeroAble`) can not be accepted. This fixes 13 | [#17](https://github.com/antifuchs/nonzero_ext/issues/17). 14 | 15 | ### Contributors 16 | * [`@joshlf`](https://github.com/joshlf) 17 | * [`@ComputerDruid`](https://github.com/ComputerDruid) 18 | 19 | ## [0.2.0] - 2019-12-23 20 | 21 | ### Added 22 | * Support for `NonZeroI*` types - now `nonzero_ext` should include support for all non-zero integer types that the 23 | standard library exports. 24 | * Support for using `nonzero!` in a [const context](https://doc.rust-lang.org/reference/const_eval.html). 25 | * This [CHANGELOG](./CHANGELOG.md) file. I have tried to backfill the major changes since initial release, but there 26 | are bound to be gaps. 27 | 28 | ### Changed 29 | * The `as_nonzero` and `as_nonzero_unchecked` methods on the `NonZeroAble` trait are now named `into_nonzero` and 30 | `into_nonzero_unchecked`, respectively. The old methods still exist, but are deprecated. 31 | 32 | ## [v0.1.3] - 2019-03-10 33 | 34 | ### Added 35 | * Ability to use the `nonzero_ext` crate in `no_std` mode; to use it without the `std` library, disable default 36 | features when pulling this crate into your project. 37 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Thanks for contributing to this project! 2 | 3 | I'm completely thrilled that you find this project useful enough to 4 | spend your time on! 5 | 6 | ## Code of Conduct 7 | 8 | Contributors are expected to adhere to the 9 | [Contributor Covenant Code of Conduct](http://contributor-covenant.org/version/1/4/), 10 | version 1.4. See [CoC.md](CoC.md) for the full text. 11 | 12 | ## Things you might do 13 | 14 | Feel free to: 15 | 16 | * [Report issues](../../issues) 17 | * [Send me a pull request](../../pulls) or 18 | * Just get in touch with me: asf@boinkor.net! 19 | 20 | ## Found a security issue? 21 | 22 | If you find a bug in this program that might be security-relevant, feel free to reach out to [the author](mailto:asf@boinkor.net) with an encrypted message. You can find the most current OpenPGP keys (and other encrypted contact methods) on [keybase](https://keybase.io/asf)! 23 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nonzero_ext" 3 | version = "0.3.1-dev" 4 | authors = ["Andreas Fuchs "] 5 | license = "Apache-2.0" 6 | repository = "https://github.com/antifuchs/nonzero_ext" 7 | readme = "README.md" 8 | description = "Extensions and additional traits for non-zero integer types" 9 | documentation = "https://docs.rs/nonzero_ext" 10 | 11 | [badges] 12 | maintenance = { status = "passively-maintained" } 13 | 14 | [features] 15 | default = ["std"] 16 | std = [] 17 | 18 | [dependencies] 19 | 20 | [dev-dependencies] 21 | trybuild = "1.0.42" 22 | rustversion = "1.0.2" 23 | -------------------------------------------------------------------------------- /CoC.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at asf@boinkor.net. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2018 Andreas Fuchs 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nonzero_ext 2 | 3 | ## Traits to represent generic nonzero integer types 4 | ![Build status](https://github.com/antifuchs/nonzero_ext/actions/workflows/ci.yml/badge.svg?branch=master) [![Docs](https://docs.rs/nonzero_ext/badge.svg)](https://docs.rs/nonzero_ext) 5 | 6 | Rust ships with non-zero integer types now, which let programmers 7 | promise (memory-savingly!) that a number can never be zero. That's 8 | great, but sadly the standard library has not got a whole lot of 9 | tools to help you use them ergonomically. 10 | 11 | ### A macro for non-zero constant literals 12 | 13 | Creating and handling constant literals is neat, but the standard 14 | library (and the rust parser at the moment) have no affordances to 15 | easily create values of `num::NonZeroU*` types from constant 16 | literals. This crate ships a `nonzero!` macro that lets you write 17 | `nonzero!(20u32)`, which checks at compile time that the constant 18 | being converted is non-zero, instead of the cumbersome (and 19 | runtime-checked!) `NonZeroU32::new(20).unwrap()`. 20 | 21 | ### Traits for generic non-zeroness 22 | 23 | The stdlib `num::NonZeroU*` types do not implement any common 24 | traits (and neither do their zeroable equivalents). Where this 25 | lack of traits in the standard library becomes problematic is if 26 | you want to write a function that takes a vector of integers, and 27 | that returns a vector of the corresponding non-zero integer types, 28 | minus any elements that were zero in the original. You can write 29 | that with the standard library quite easily for concrete types: 30 | 31 | ```rust 32 | fn only_nonzeros(v: Vec) -> Vec 33 | { 34 | v.into_iter() 35 | .filter_map(|n| NonZeroU8::new(n)) 36 | .collect::>() 37 | } 38 | let expected: Vec = vec![nonzero!(20u8), nonzero!(5u8)]; 39 | assert_eq!(expected, only_nonzeros(vec![0, 20, 5])); 40 | ``` 41 | 42 | But what if you want to allow this function to work with any 43 | integer type that has a corresponding non-zero type? This crate 44 | can help: 45 | 46 | ```rust 47 | fn only_nonzeros(v: Vec) -> Vec 48 | where 49 | I: Sized + NonZeroAble, 50 | { 51 | v.into_iter() 52 | .filter_map(|n| n.as_nonzero()) 53 | .collect::>() 54 | } 55 | 56 | // It works for `u8`: 57 | let input_u8: Vec = vec![0, 20, 5]; 58 | let expected_u8: Vec = vec![nonzero!(20u8), nonzero!(5u8)]; 59 | assert_eq!(expected_u8, only_nonzeros(input_u8)); 60 | 61 | // And it works for `u32`: 62 | let input_u32: Vec = vec![0, 20, 5]; 63 | let expected_u32: Vec = vec![nonzero!(20u32), nonzero!(5u32)]; 64 | assert_eq!(expected_u32, only_nonzeros(input_u32)); 65 | ``` 66 | 67 | 68 | License: Apache-2.0 69 | -------------------------------------------------------------------------------- /bors.toml: -------------------------------------------------------------------------------- 1 | # Don't forget to update permissions and add this repo in 2 | # https://app.bors.tech/repositories so bors can see the new repo! 3 | 4 | status = [ 5 | "cargo_deny", 6 | "cargo_clippy", 7 | "all_tests", 8 | "rustfmt", 9 | ] 10 | timeout_sec = 300 11 | delete_merged_branches = true -------------------------------------------------------------------------------- /deny.toml: -------------------------------------------------------------------------------- 1 | [advisories] 2 | vulnerability = "deny" 3 | unmaintained = "warn" 4 | notice = "warn" 5 | ignore = [] 6 | 7 | [licenses] 8 | unlicensed = "deny" 9 | allow = [ 10 | "Apache-2.0", 11 | "MIT", 12 | ] 13 | deny = [] 14 | copyleft = "warn" 15 | # Blanket approval or denial for OSI-approved or FSF Free/Libre licenses 16 | # * both - The license will only be approved if it is both OSI-approved *AND* FSF/Free 17 | # * either - The license will be approved if it is either OSI-approved *OR* FSF/Free 18 | # * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF/Free 19 | # * fsf-only - The license will be approved if is FSF/Free *AND NOT* OSI-approved 20 | # * neither - The license will be denied if is FSF/Free *OR* OSI-approved 21 | allow-osi-fsf-free = "neither" 22 | confidence-threshold = 0.8 23 | 24 | [bans] 25 | # Lint level for when multiple versions of the same crate are detected 26 | multiple-versions = "warn" 27 | highlight = "lowest-version" 28 | allow = [ 29 | #{ name = "ansi_term", version = "=0.11.0" }, 30 | ] 31 | deny = [ 32 | ] 33 | # Certain crates/versions that will be skipped when doing duplicate detection. 34 | skip = [ 35 | #{ name = "ansi_term", version = "=0.11.0" }, 36 | ] 37 | skip-tree = [ 38 | ] 39 | -------------------------------------------------------------------------------- /release.toml: -------------------------------------------------------------------------------- 1 | sign-commit = false 2 | pre-release-commit-message = "Release {{version}} 🎉🎉" 3 | post-release-commit-message = "Start next development iteration {{version}}" 4 | tag-message = "Release {{prefix}}{{version}}" 5 | dev-version-ext = "dev" 6 | tag-prefix = "" 7 | pre-release-replacements = [ 8 | {file="CHANGELOG.md", search="Unreleased", replace="{{version}}"}, 9 | {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}"}, 10 | {file="CHANGELOG.md", search="", replace="\n\n## [Unreleased] - ReleaseDate"}, 11 | ] 12 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Traits to represent generic nonzero integer types 2 | //! [![Build Status](https://travis-ci.com/antifuchs/nonzero_ext.svg?branch=master)](https://travis-ci.com/antifuchs/nonzero_ext) [![Docs](https://docs.rs/nonzero_ext/badge.svg)](https://docs.rs/nonzero_ext) 3 | //! 4 | //! Rust ships with non-zero integer types now, which let programmers 5 | //! promise (memory-savingly!) that a number can never be zero. That's 6 | //! great, but sadly the standard library has not got a whole lot of 7 | //! tools to help you use them ergonomically. 8 | //! 9 | //! ## A macro for non-zero constant literals 10 | //! 11 | //! Creating and handling constant literals is neat, but the standard 12 | //! library (and the rust parser at the moment) have no affordances to 13 | //! easily create values of `num::NonZeroU*` types from constant 14 | //! literals. This crate ships a `nonzero!` macro that lets you write 15 | //! `nonzero!(20u32)`, which checks at compile time that the constant 16 | //! being converted is non-zero, instead of the cumbersome (and 17 | //! runtime-checked!) `NonZeroU32::new(20).unwrap()`. 18 | //! 19 | //! ## Traits for generic non-zeroness 20 | //! 21 | //! The stdlib `num::NonZeroU*` types do not implement any common 22 | //! traits (and neither do their zeroable equivalents). Where this 23 | //! lack of traits in the standard library becomes problematic is if 24 | //! you want to write a function that takes a vector of integers, and 25 | //! that returns a vector of the corresponding non-zero integer types, 26 | //! minus any elements that were zero in the original. You can write 27 | //! that with the standard library quite easily for concrete types: 28 | //! 29 | //! ```rust 30 | //! # use std::num::NonZeroU8; 31 | //! fn only_nonzeros(v: Vec) -> Vec 32 | //! { 33 | //! v.into_iter() 34 | //! .filter_map(|n| NonZeroU8::new(n)) 35 | //! .collect::>() 36 | //! } 37 | //! # #[macro_use] extern crate nonzero_ext; 38 | //! # fn main() { 39 | //! let expected: Vec = vec![nonzero!(20u8), nonzero!(5u8)]; 40 | //! assert_eq!(expected, only_nonzeros(vec![0, 20, 5])); 41 | //! # } 42 | //! ``` 43 | //! 44 | //! But what if you want to allow this function to work with any 45 | //! integer type that has a corresponding non-zero type? This crate 46 | //! can help: 47 | //! 48 | //! ```rust 49 | //! # use std::num::{NonZeroU8, NonZeroU32}; 50 | //! # use nonzero_ext::{NonZeroAble}; 51 | //! fn only_nonzeros(v: Vec) -> Vec 52 | //! where 53 | //! I: Sized + NonZeroAble, 54 | //! { 55 | //! v.into_iter() 56 | //! .filter_map(|n| n.as_nonzero()) 57 | //! .collect::>() 58 | //! } 59 | //! 60 | //! # #[macro_use] extern crate nonzero_ext; 61 | //! # fn main() { 62 | //! // It works for `u8`: 63 | //! let input_u8: Vec = vec![0, 20, 5]; 64 | //! let expected_u8: Vec = vec![nonzero!(20u8), nonzero!(5u8)]; 65 | //! assert_eq!(expected_u8, only_nonzeros(input_u8)); 66 | //! 67 | //! // And it works for `u32`: 68 | //! let input_u32: Vec = vec![0, 20, 5]; 69 | //! let expected_u32: Vec = vec![nonzero!(20u32), nonzero!(5u32)]; 70 | //! assert_eq!(expected_u32, only_nonzeros(input_u32)); 71 | //! # } 72 | //! ``` 73 | //! 74 | 75 | #![cfg_attr(not(feature = "std"), no_std)] 76 | #![allow(unknown_lints)] 77 | // Unfortunately necessary, otherwise features aren't supported in doctests: 78 | #![allow(clippy::needless_doctest_main)] 79 | 80 | mod lib { 81 | mod core { 82 | #[cfg(feature = "std")] 83 | pub use std::*; 84 | 85 | #[cfg(not(feature = "std"))] 86 | pub use core::*; 87 | } 88 | pub use self::core::num::{ 89 | NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, 90 | }; 91 | pub use self::core::num::{ 92 | NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, 93 | }; 94 | } 95 | 96 | use self::lib::*; 97 | 98 | pub mod literals; 99 | 100 | macro_rules! impl_nonzeroness { 101 | ($trait_name:ident, $nonzero_type:ty, $wrapped:ty) => { 102 | impl $trait_name for $nonzero_type { 103 | type Primitive = $wrapped; 104 | 105 | #[inline] 106 | #[cfg_attr(feature = "cargo-clippy", allow(clippy::new_ret_no_self))] 107 | fn new(n: $wrapped) -> Option { 108 | Self::new(n) 109 | } 110 | 111 | #[inline] 112 | fn get(self) -> Self::Primitive { 113 | <$nonzero_type>::get(self) 114 | } 115 | } 116 | }; 117 | } 118 | 119 | /// A trait identifying a non-zero integral type. It is useful mostly 120 | /// in order to give to genericized helper functions as `impl NonZero` 121 | /// arguments. 122 | pub trait NonZero { 123 | /// The primitive type (e.g. `u8`) underlying this integral type. 124 | type Primitive; 125 | 126 | /// Creates a new non-zero object from an integer that might be 127 | /// zero. 128 | fn new(n: Self::Primitive) -> Option 129 | where 130 | Self: Sized; 131 | 132 | /// Returns the value as a primitive type. 133 | fn get(self) -> Self::Primitive; 134 | } 135 | 136 | impl_nonzeroness!(NonZero, NonZeroU8, u8); 137 | impl_nonzeroness!(NonZero, NonZeroU16, u16); 138 | impl_nonzeroness!(NonZero, NonZeroU32, u32); 139 | impl_nonzeroness!(NonZero, NonZeroU64, u64); 140 | impl_nonzeroness!(NonZero, NonZeroU128, u128); 141 | impl_nonzeroness!(NonZero, NonZeroUsize, usize); 142 | 143 | impl_nonzeroness!(NonZero, NonZeroI8, i8); 144 | impl_nonzeroness!(NonZero, NonZeroI16, i16); 145 | impl_nonzeroness!(NonZero, NonZeroI32, i32); 146 | impl_nonzeroness!(NonZero, NonZeroI64, i64); 147 | impl_nonzeroness!(NonZero, NonZeroI128, i128); 148 | impl_nonzeroness!(NonZero, NonZeroIsize, isize); 149 | 150 | /// A trait identifying integral types that have a non-zeroable 151 | /// equivalent. 152 | pub trait NonZeroAble { 153 | /// The concrete non-zero type represented by an implementation of 154 | /// this trait. For example, for `u8`'s implementation, it is 155 | /// `NonZeroU8`. 156 | type NonZero: NonZero; 157 | 158 | //noinspection RsSelfConvention 159 | /// Converts the integer to its non-zero equivalent. 160 | /// 161 | /// # Examples 162 | /// 163 | /// ### Trying to convert zero 164 | /// ``` rust 165 | /// # use nonzero_ext::NonZeroAble; 166 | /// let n: u16 = 0; 167 | /// assert_eq!(n.as_nonzero(), None); 168 | /// ``` 169 | /// 170 | /// ### Converting a non-zero value 171 | /// ``` rust 172 | /// # use nonzero_ext::NonZeroAble; 173 | /// # use std::num::NonZeroUsize; 174 | /// let n: usize = 20; 175 | /// let non0n: NonZeroUsize = n.as_nonzero().expect("should result in a converted value"); 176 | /// assert_eq!(non0n.get(), 20); 177 | /// ``` 178 | #[deprecated(since = "0.2.0", note = "Renamed to `into_nonzero`")] 179 | #[allow(clippy::wrong_self_convention)] 180 | fn as_nonzero(self) -> Option 181 | where 182 | Self: Sized, 183 | { 184 | self.into_nonzero() 185 | } 186 | 187 | /// Converts the integer to its non-zero equivalent. 188 | /// 189 | /// # Examples 190 | /// 191 | /// ### Trying to convert zero 192 | /// ``` rust 193 | /// # use nonzero_ext::NonZeroAble; 194 | /// let n: u16 = 0; 195 | /// assert_eq!(n.into_nonzero(), None); 196 | /// ``` 197 | /// 198 | /// ### Converting a non-zero value 199 | /// ``` rust 200 | /// # use nonzero_ext::NonZeroAble; 201 | /// # use std::num::NonZeroUsize; 202 | /// let n: usize = 20; 203 | /// let non0n: NonZeroUsize = n.into_nonzero().expect("should result in a converted value"); 204 | /// assert_eq!(non0n.get(), 20); 205 | /// ``` 206 | fn into_nonzero(self) -> Option; 207 | 208 | //noinspection RsSelfConvention 209 | /// Converts the integer to its non-zero equivalent without 210 | /// checking for zeroness. 211 | /// 212 | /// This corresponds to the `new_unchecked` function on the 213 | /// corresponding NonZero type. 214 | /// 215 | /// # Safety 216 | /// The value must not be zero. 217 | #[deprecated(since = "0.2.0", note = "Renamed to `into_nonzero_unchecked`")] 218 | #[allow(clippy::wrong_self_convention)] 219 | unsafe fn as_nonzero_unchecked(self) -> Self::NonZero 220 | where 221 | Self: Sized, 222 | { 223 | self.into_nonzero_unchecked() 224 | } 225 | 226 | /// Converts the integer to its non-zero equivalent without 227 | /// checking for zeroness. 228 | /// 229 | /// This corresponds to the `new_unchecked` function on the 230 | /// corresponding NonZero type. 231 | /// 232 | /// # Safety 233 | /// The value must not be zero. 234 | unsafe fn into_nonzero_unchecked(self) -> Self::NonZero; 235 | } 236 | 237 | macro_rules! impl_nonzeroable { 238 | ($trait_name:ident, $nonzero_type: ty, $nonzeroable_type:ty) => { 239 | impl $trait_name for $nonzeroable_type { 240 | type NonZero = $nonzero_type; 241 | 242 | fn into_nonzero(self) -> Option<$nonzero_type> { 243 | Self::NonZero::new(self) 244 | } 245 | 246 | unsafe fn into_nonzero_unchecked(self) -> $nonzero_type { 247 | Self::NonZero::new_unchecked(self) 248 | } 249 | } 250 | impl literals::NonZeroLiteral<$nonzeroable_type> { 251 | /// Converts the wrapped value to its non-zero equivalent. 252 | /// # Safety 253 | /// The wrapped value must be non-zero. 254 | pub const unsafe fn into_nonzero(self) -> $nonzero_type { 255 | <$nonzero_type>::new_unchecked(self.0) 256 | } 257 | } 258 | impl literals::sealed::IntegerLiteral for $nonzeroable_type {} 259 | }; 260 | } 261 | 262 | impl_nonzeroable!(NonZeroAble, NonZeroU8, u8); 263 | impl_nonzeroable!(NonZeroAble, NonZeroU16, u16); 264 | impl_nonzeroable!(NonZeroAble, NonZeroU32, u32); 265 | impl_nonzeroable!(NonZeroAble, NonZeroU64, u64); 266 | impl_nonzeroable!(NonZeroAble, NonZeroU128, u128); 267 | impl_nonzeroable!(NonZeroAble, NonZeroUsize, usize); 268 | 269 | impl_nonzeroable!(NonZeroAble, NonZeroI8, i8); 270 | impl_nonzeroable!(NonZeroAble, NonZeroI16, i16); 271 | impl_nonzeroable!(NonZeroAble, NonZeroI32, i32); 272 | impl_nonzeroable!(NonZeroAble, NonZeroI64, i64); 273 | impl_nonzeroable!(NonZeroAble, NonZeroI128, i128); 274 | impl_nonzeroable!(NonZeroAble, NonZeroIsize, isize); 275 | 276 | /// Create non-zero values from constant literals easily. 277 | /// 278 | /// This macro issues a compile-time check and, if it passes, creates 279 | /// the corresponding non-zero numeric value from the given 280 | /// constant. Since the type of constant literals needs to be exactly 281 | /// known, `nonzero!` requires that you annotate the constant with the 282 | /// type, so instead of `nonzero!(20)` you must write `nonzero!(20 as 283 | /// u16)`. 284 | /// 285 | /// Note that this macro only works with [integer 286 | /// literals](https://doc.rust-lang.org/reference/tokens.html#integer-literals), 287 | /// it isn't possible to use the `nonzero!` macro with types other 288 | /// than the built-in ones. 289 | /// 290 | /// # Determining the output type 291 | /// 292 | /// Use a suffix on the input value to determine the output type: 293 | /// `nonzero!(1_usize)` will return a [`NonZeroUsize`], and 294 | /// `nonzero!(-1_i32)` will return a [`NonZeroI32`]. 295 | /// 296 | /// # Const expressions 297 | /// 298 | /// This macro can be used in const expressions. 299 | /// 300 | /// # Examples 301 | /// ``` 302 | /// # #[macro_use] 303 | /// # extern crate nonzero_ext; 304 | /// # fn main() { 305 | /// nonzero!(20usize); // => NonZeroUsize 306 | /// nonzero!(20u32); // => NonZeroU32 307 | /// nonzero!(20 as u8); // => NonZeroU8 308 | /// # } 309 | /// ``` 310 | /// 311 | /// and passing a zero of any type will fail: 312 | /// 313 | /// ``` # compile_fail 314 | /// # #[macro_use] 315 | /// # extern crate nonzero_ext; 316 | /// # fn main() { 317 | /// nonzero!(0u8); 318 | /// # } 319 | /// ``` 320 | /// 321 | #[macro_export] 322 | macro_rules! nonzero { 323 | ($n:expr) => {{ 324 | #[allow(unknown_lints, eq_op)] 325 | let _ = [(); ($n.count_ones() as usize) - 1]; 326 | let lit = $crate::literals::NonZeroLiteral($n); 327 | unsafe { lit.into_nonzero() } 328 | }}; 329 | } 330 | -------------------------------------------------------------------------------- /src/literals.rs: -------------------------------------------------------------------------------- 1 | //! Handling non-zero literal values. 2 | 3 | pub(crate) mod sealed { 4 | use crate::NonZeroAble; 5 | 6 | /// A trait implemented by all known integer literals that can 7 | /// appear in source code. 8 | pub trait IntegerLiteral: NonZeroAble {} 9 | } 10 | 11 | /// A representation of a non-zero literal. Used by the [`nonzero!`] macro. 12 | /// 13 | /// This struct has no use outside of this macro (even though it can be constructed by anyone). 14 | /// It needs to exist to support the use of the [`nonzero!`] macro in const expressions. 15 | pub struct NonZeroLiteral(pub T); 16 | -------------------------------------------------------------------------------- /tests/compile-fail_1.45/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_1.45/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.45/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.45/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to subtract with overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.45/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.45/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to subtract with overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.46/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_1.46/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize` which would overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.46/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.46/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize` which would overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.46/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.46/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize` which would overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.48/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_1.48/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.48/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.48/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.48/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.48/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/issue-17--adverse-conditions.rs: -------------------------------------------------------------------------------- 1 | use nonzero_ext::nonzero; 2 | use nonzero_ext::{literals::NonZeroLiteral, NonZeroAble}; 3 | use std::num::NonZeroUsize; 4 | 5 | struct BadInt(usize); 6 | impl BadInt { 7 | const fn count_ones(&self) -> usize { 8 | 1 // oops, even zero counts! 9 | } 10 | } 11 | impl NonZeroAble for BadInt { 12 | type NonZero = NonZeroUsize; 13 | 14 | fn into_nonzero(self) -> Option { 15 | NonZeroUsize::new(self.0) 16 | } 17 | 18 | unsafe fn into_nonzero_unchecked(self) -> Self::NonZero { 19 | NonZeroUsize::new_unchecked(self.0) 20 | } 21 | } 22 | 23 | // And we can't impl: 24 | // impl NonZeroLiteral {} // <- also errors. 25 | trait OtherTrait { 26 | /// # Safety 27 | /// self must not be NonZeroLiteral(BadInt(0)) 28 | unsafe fn into_nonzero(self) -> NonZeroUsize; 29 | } 30 | 31 | impl OtherTrait for NonZeroLiteral { 32 | unsafe fn into_nonzero(self) -> NonZeroUsize { 33 | unsafe { self.0.into_nonzero_unchecked() } 34 | } 35 | } 36 | 37 | fn main() { 38 | nonzero!(BadInt(0)); 39 | } 40 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/issue-17--adverse-conditions.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `BadInt: literals::sealed::IntegerLiteral` is not satisfied 2 | --> $DIR/issue-17--adverse-conditions.rs:31:21 3 | | 4 | 31 | impl OtherTrait for NonZeroLiteral { 5 | | ^^^^^^^^^^^^^^^^^^^^^^ the trait `literals::sealed::IntegerLiteral` is not implemented for `BadInt` 6 | | 7 | ::: $WORKSPACE/src/literals.rs 8 | | 9 | | pub struct NonZeroLiteral(pub T); 10 | | ---------------------- required by this bound in `NonZeroLiteral` 11 | 12 | error[E0277]: the trait bound `BadInt: literals::sealed::IntegerLiteral` is not satisfied 13 | --> $DIR/issue-17--adverse-conditions.rs:32:28 14 | | 15 | 32 | unsafe fn into_nonzero(self) -> NonZeroUsize { 16 | | ^^^^ the trait `literals::sealed::IntegerLiteral` is not implemented for `BadInt` 17 | | 18 | ::: $WORKSPACE/src/literals.rs 19 | | 20 | | pub struct NonZeroLiteral(pub T); 21 | | ---------------------- required by this bound in `NonZeroLiteral` 22 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.54/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/issue-17--adverse-conditions.rs: -------------------------------------------------------------------------------- 1 | use nonzero_ext::nonzero; 2 | use nonzero_ext::{literals::NonZeroLiteral, NonZeroAble}; 3 | use std::num::NonZeroUsize; 4 | 5 | struct BadInt(usize); 6 | impl BadInt { 7 | const fn count_ones(&self) -> usize { 8 | 1 // oops, even zero counts! 9 | } 10 | } 11 | impl NonZeroAble for BadInt { 12 | type NonZero = NonZeroUsize; 13 | 14 | fn into_nonzero(self) -> Option { 15 | NonZeroUsize::new(self.0) 16 | } 17 | 18 | unsafe fn into_nonzero_unchecked(self) -> Self::NonZero { 19 | NonZeroUsize::new_unchecked(self.0) 20 | } 21 | } 22 | 23 | // And we can't impl: 24 | // impl NonZeroLiteral {} // <- also errors. 25 | trait OtherTrait { 26 | /// # Safety 27 | /// self must not be NonZeroLiteral(BadInt(0)) 28 | unsafe fn into_nonzero(self) -> NonZeroUsize; 29 | } 30 | 31 | impl OtherTrait for NonZeroLiteral { 32 | unsafe fn into_nonzero(self) -> NonZeroUsize { 33 | unsafe { self.0.into_nonzero_unchecked() } 34 | } 35 | } 36 | 37 | fn main() { 38 | nonzero!(BadInt(0)); 39 | } 40 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/issue-17--adverse-conditions.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `BadInt: literals::sealed::IntegerLiteral` is not satisfied 2 | --> $DIR/issue-17--adverse-conditions.rs:31:21 3 | | 4 | 31 | impl OtherTrait for NonZeroLiteral { 5 | | ^^^^^^^^^^^^^^^^^^^^^^ the trait `literals::sealed::IntegerLiteral` is not implemented for `BadInt` 6 | | 7 | note: required by a bound in `NonZeroLiteral` 8 | --> $DIR/literals.rs:15:30 9 | | 10 | 15 | pub struct NonZeroLiteral(pub T); 11 | | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `NonZeroLiteral` 12 | 13 | error[E0277]: the trait bound `BadInt: literals::sealed::IntegerLiteral` is not satisfied 14 | --> $DIR/issue-17--adverse-conditions.rs:32:28 15 | | 16 | 32 | unsafe fn into_nonzero(self) -> NonZeroUsize { 17 | | ^^^^ the trait `literals::sealed::IntegerLiteral` is not implemented for `BadInt` 18 | | 19 | note: required by a bound in `NonZeroLiteral` 20 | --> $DIR/literals.rs:15:30 21 | | 22 | 15 | pub struct NonZeroLiteral(pub T); 23 | | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `NonZeroLiteral` 24 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.56/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/issue-17--adverse-conditions.rs: -------------------------------------------------------------------------------- 1 | use nonzero_ext::nonzero; 2 | use nonzero_ext::{literals::NonZeroLiteral, NonZeroAble}; 3 | use std::num::NonZeroUsize; 4 | 5 | struct BadInt(usize); 6 | impl BadInt { 7 | const fn count_ones(&self) -> usize { 8 | 1 // oops, even zero counts! 9 | } 10 | } 11 | impl NonZeroAble for BadInt { 12 | type NonZero = NonZeroUsize; 13 | 14 | fn into_nonzero(self) -> Option { 15 | NonZeroUsize::new(self.0) 16 | } 17 | 18 | unsafe fn into_nonzero_unchecked(self) -> Self::NonZero { 19 | NonZeroUsize::new_unchecked(self.0) 20 | } 21 | } 22 | 23 | // And we can't impl: 24 | // impl NonZeroLiteral {} // <- also errors. 25 | trait OtherTrait { 26 | /// # Safety 27 | /// self must not be NonZeroLiteral(BadInt(0)) 28 | unsafe fn into_nonzero(self) -> NonZeroUsize; 29 | } 30 | 31 | impl OtherTrait for NonZeroLiteral { 32 | unsafe fn into_nonzero(self) -> NonZeroUsize { 33 | unsafe { self.0.into_nonzero_unchecked() } 34 | } 35 | } 36 | 37 | fn main() { 38 | nonzero!(BadInt(0)); 39 | } 40 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/issue-17--adverse-conditions.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `BadInt: literals::sealed::IntegerLiteral` is not satisfied 2 | --> $DIR/issue-17--adverse-conditions.rs:31:21 3 | | 4 | 31 | impl OtherTrait for NonZeroLiteral { 5 | | ^^^^^^^^^^^^^^^^^^^^^^ the trait `literals::sealed::IntegerLiteral` is not implemented for `BadInt` 6 | | 7 | = help: the following other types implement trait `literals::sealed::IntegerLiteral`: 8 | i128 9 | i16 10 | i32 11 | i64 12 | i8 13 | isize 14 | u128 15 | u16 16 | and 4 others 17 | note: required by a bound in `NonZeroLiteral` 18 | --> $DIR/literals.rs:15:30 19 | | 20 | 15 | pub struct NonZeroLiteral(pub T); 21 | | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `NonZeroLiteral` 22 | 23 | error[E0277]: the trait bound `BadInt: literals::sealed::IntegerLiteral` is not satisfied 24 | --> $DIR/issue-17--adverse-conditions.rs:32:28 25 | | 26 | 32 | unsafe fn into_nonzero(self) -> NonZeroUsize { 27 | | ^^^^ the trait `literals::sealed::IntegerLiteral` is not implemented for `BadInt` 28 | | 29 | = help: the following other types implement trait `literals::sealed::IntegerLiteral`: 30 | i128 31 | i16 32 | i32 33 | i64 34 | i8 35 | isize 36 | u128 37 | u16 38 | and 4 others 39 | note: required by a bound in `NonZeroLiteral` 40 | --> $DIR/literals.rs:15:30 41 | | 42 | 15 | pub struct NonZeroLiteral(pub T); 43 | | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `NonZeroLiteral` 44 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_1.62/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_nightly/immoral_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile-fail_nightly/immoral_math.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/immoral_math.rs:7:42 3 | | 4 | 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 / 2 - 21) as u32); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_nightly/zero_u8.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU8; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroU8 = nonzero!(0u8); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_nightly/zero_u8.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_u8.rs:8:25 3 | | 4 | 8 | let _a: NonZeroU8 = nonzero!(0u8); 5 | | ^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compile-fail_nightly/zero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroUsize; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroUsize = nonzero!(0usize); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile-fail_nightly/zero_usize.stderr: -------------------------------------------------------------------------------- 1 | error[E0080]: evaluation of constant value failed 2 | --> $DIR/zero_usize.rs:8:28 3 | | 4 | 8 | let _a: NonZeroUsize = nonzero!(0usize); 5 | | ^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow 6 | | 7 | = note: this error originates in the macro `nonzero` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | -------------------------------------------------------------------------------- /tests/compiletest.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn compile_test_success() { 3 | let t = trybuild::TestCases::new(); 4 | t.pass("tests/run-pass/*.rs"); 5 | } 6 | 7 | #[rustversion::any(nightly)] 8 | #[test] 9 | fn compile_fail_test_prerelease() { 10 | let t = trybuild::TestCases::new(); 11 | t.compile_fail("tests/compile-fail_nightly/*.rs"); 12 | } 13 | 14 | #[rustversion::before(1.46)] 15 | #[test] 16 | fn compile_fail_test_until_1_45() { 17 | let t = trybuild::TestCases::new(); 18 | t.compile_fail("tests/compile-fail_1.45/*.rs"); 19 | } 20 | 21 | #[rustversion::all(since(1.46), before(1.48))] 22 | #[test] 23 | fn compile_fail_test_since_1_46() { 24 | let t = trybuild::TestCases::new(); 25 | t.compile_fail("tests/compile-fail_1.46/*.rs"); 26 | } 27 | 28 | #[rustversion::all(since(1.48), before(1.54.0))] 29 | #[test] 30 | fn compile_fail_test_stable_since_1_48() { 31 | let t = trybuild::TestCases::new(); 32 | t.compile_fail("tests/compile-fail_1.48/*.rs"); 33 | } 34 | 35 | #[rustversion::all(since(1.54.0), before(1.56.0))] 36 | #[test] 37 | fn compile_fail_test_since_1_54() { 38 | let t = trybuild::TestCases::new(); 39 | t.compile_fail("tests/compile-fail_1.54/*.rs"); 40 | } 41 | 42 | #[rustversion::all(since(1.56.0), before(1.62.0))] 43 | #[test] 44 | fn compile_fail_test_since_1_54() { 45 | let t = trybuild::TestCases::new(); 46 | t.compile_fail("tests/compile-fail_1.56/*.rs"); 47 | } 48 | 49 | #[rustversion::all(since(1.62.0), not(nightly))] 50 | #[test] 51 | fn compile_fail_test_since_1_62() { 52 | let t = trybuild::TestCases::new(); 53 | t.compile_fail("tests/compile-fail_1.62/*.rs"); 54 | } 55 | -------------------------------------------------------------------------------- /tests/macro.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | #[test] 5 | fn works_in_exprs() { 6 | let one = nonzero!(1u32); 7 | println!("{}", one); 8 | println!("{}", nonzero!(1u8)); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run-pass/const_expression.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!(42u32); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run-pass/negative_i32.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroI32; 5 | 6 | #[cfg_attr(rustfmt, rustfmt_skip)] 7 | fn main() { 8 | let _a: NonZeroI32 = nonzero!(-2i32); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run-pass/nonzero_isize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroIsize; 5 | 6 | fn main() { 7 | let _a: NonZeroIsize = nonzero!(20isize); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run-pass/nonzero_usize.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate nonzero_ext; 2 | 3 | use std::num::NonZeroUsize; 4 | 5 | fn main() { 6 | let _a: NonZeroUsize = nonzero!(20usize); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /tests/run-pass/virtuous_math.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nonzero_ext; 3 | 4 | use std::num::NonZeroU32; 5 | 6 | fn main() { 7 | const _MY_NON_ZERO_U32: NonZeroU32 = nonzero!((42 * 2 - 21) as u32); 8 | } 9 | --------------------------------------------------------------------------------