blanket-0.3.0/.cargo_vcs_info.json0000644000000001360000000000100124540ustar { "git": { "sha1": "9ba34015cb509a774f6b8486ad3bf5c00c481b52" }, "path_in_vcs": "" }blanket-0.3.0/.codecov.yml000064400000000000000000000000431046102023000134640ustar 00000000000000ignore: - "tests" - "examples" blanket-0.3.0/.github/workflows/publish.yml000064400000000000000000000010631046102023000170320ustar 00000000000000name: Publish to Crates.io on: push: tags: - v*.*.* jobs: publish: runs-on: ubuntu-latest environment: Crates.io name: Publish Rust crate steps: - name: Checkout code uses: actions/checkout@v1 - name: Setup Rust ${{ matrix.rust-toolchain }} uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - name: Package and publish uses: actions-rs/cargo@v1 with: command: publish args: --token ${{ secrets.CRATES_IO_TOKEN }} blanket-0.3.0/.github/workflows/test.yml000064400000000000000000000026071046102023000163500ustar 00000000000000name: Test on: - push - pull_request jobs: test: runs-on: ubuntu-latest strategy: matrix: rust-toolchain: - stable - beta - nightly steps: - name: Checkout code uses: actions/checkout@v1 - name: Setup Rust ${{ matrix.rust-toolchain }} uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.rust-toolchain }} override: true - name: Setup cache for cargo uses: actions/cache@v2 with: path: target key: ${{ runner.os }}-cargo-${{ matrix.rust-toolchain }} - name: Check code uses: actions-rs/cargo@v1 with: command: check - name: Measure code coverage uses: actions-rs/tarpaulin@v0.1 with: version: '0.16.0' args: '--lib -v --out Xml --ciserver github-actions' - name: Upload coverage statistics run: curl -SsL "https://codecov.io/bash" | bash -s lint: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v1 - name: Setup Rust stable uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true components: rustfmt - name: Check code format uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check blanket-0.3.0/.github/workflows/update-releases.yml000064400000000000000000000011031046102023000204420ustar 00000000000000name: Update releases on: push: tags: - v*.*.* jobs: chandler: environment: GitHub Releases runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v1 - name: Set up Ruby 2.7 uses: actions/setup-ruby@v1 with: ruby-version: 2.7 - name: Install chandler gem run: gem install chandler - name: Update releases messages run: chandler push --github="$GITHUB_REPOSITORY" --changelog="CHANGELOG.md" env: CHANDLER_GITHUB_API_TOKEN: ${{ secrets.CHANDLER_GITHUB_API_TOKEN }} blanket-0.3.0/.gitignore000064400000000000000000000000411046102023000132270ustar 00000000000000/target Cargo.lock cobertura.xml blanket-0.3.0/CHANGELOG.md000064400000000000000000000054261046102023000130640ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] [Unreleased]: https://github.com/althonos/blanket/compare/v0.3.0...HEAD ## [v0.3.0] - 2023-06-19 [v0.3.0]: https://github.com/althonos/blanket/compare/v0.2.0...v0.3.0 ### Fixed - `blanket` macro failing to process types with generic arguments and associated types ([#8](https://github.com/althonos/blanket/issues/8), by [@JustinLovinger](https://github.com/JustinLovinger)). ### Changed - Updated `syn` dependency to `v2.0`. - `#[blanket(default = ...)]` now also accepts a path instead of a string literal. ## [v0.2.0] - 2021-05-06 [v0.2.0]: https://github.com/althonos/blanket/compare/v0.1.5...v0.2.0 ### Added - Implementation for `#[blanket(derive(Arc))]` ([#4](https://github.com/althonos/blanket/pull/4), by [@najamelan](https://github.com/najamelan)) - Support for associated type in derived traits ([#6](https://github.com/althonos/blanket/pull/6), by [@najamelan](https://github.com/najamelan)). ### Fixed - Missing features for the `syn` crate preventing the crate to compile without leaking dev-dependencies ([#5](https://github.com/althonos/blanket/pull/5)). ## [v0.1.5] - 2021-05-31 [v0.1.5]: https://github.com/althonos/blanket/compare/v0.1.4...v0.1.5 ### Fixed - Regression in `v0.1.4` causing trait-associated lifetimes to be erased. ## [v0.1.4] - 2021-05-31 - YANKED [v0.1.4]: https://github.com/althonos/blanket/compare/v0.1.3...v0.1.4 ### Fixed - Generics being erroneously repeated when deriving a trait with bounded generic arguments ([#2](https://github.com/althonos/blanket/issues/2)). ## [v0.1.3] - 2020-10-13 [v0.1.3]: https://github.com/althonos/blanket/compare/v0.1.2...v0.1.3 ### Fixed - Handling of where clauses for traits with generic parameters, by @alexanderlinne ([#1](https://github.com/althonos/blanket/pull/1)). ## [v0.1.2] - 2020-07-22 [v0.1.2]: https://github.com/althonos/blanket/compare/v0.1.1...v0.1.2 ### Changed - `syn` now only compiles with [`full`](https://docs.rs/syn/latest/syn/#optional-features) feature in release mode. ### Removed - Unused `darling` dependency. ## [v0.1.1] - 2020-07-22 [v0.1.1]: https://github.com/althonos/blanket/compare/v0.1.0...v0.1.1 ### Added - Support for generic arguments in trait definition. - Implementation of `#[blanket(derive(Rc))]`. ### Fixed - Error messages of `#[blanket(derive(Mut))]` referring `Ref` erroneously. - Implementation of `fn(self)` methods when deriving for `Box`. ### Removed - Unused `strum` dependency. ## [v0.1.0] - 2020-07-21 [v0.1.0]: https://github.com/althonos/blanket/compare/3e6065c9...v0.1.0 Initial release. blanket-0.3.0/COPYING000064400000000000000000000020601046102023000122750ustar 00000000000000MIT License Copyright (c) 2020 Martin Larralde Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. blanket-0.3.0/Cargo.toml0000644000000042140000000000100104530ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "blanket" version = "0.3.0" authors = ["Martin Larralde "] description = "A simple macro to derive blanket implementations for your traits." homepage = "https://github.com/althonos/blanket" readme = "README.md" keywords = [ "proc-macro", "attribute", "blanket", "trait", "impl", ] categories = [ "development-tools", "rust-patterns", ] license = "MIT" repository = "https://github.com/althonos/blanket" resolver = "2" [package.metadata.docs.rs] features = ["_doc"] [lib] proc-macro = true [[test]] name = "derive_box" path = "tests/derive_box/mod.rs" harness = false [[test]] name = "derive_mut" path = "tests/derive_mut/mod.rs" harness = false [[test]] name = "derive_arc" path = "tests/derive_arc/mod.rs" harness = false [[test]] name = "derive_rc" path = "tests/derive_rc/mod.rs" harness = false [[test]] name = "derive_ref" path = "tests/derive_ref/mod.rs" harness = false [dependencies.proc-macro2] version = "1.0" [dependencies.quote] version = "1.0" [dependencies.syn] version = "2.0" features = [ "clone-impls", "full", "parsing", "printing", "proc-macro", ] default-features = false [dev-dependencies.impls] version = "1.0" [dev-dependencies.static_assertions] version = "1.1" [dev-dependencies.syn] version = "2.0" features = [ "full", "extra-traits", ] [dev-dependencies.trybuild] version = "1.0" [features] _doc = [] default = [] [badges.codecov] repository = "althonos/blanket" service = "github" [badges.is-it-maintained-issue-resolution] repository = "althonos/blanket" [badges.maintenance] status = "actively-developed" [badges.travis-ci] repository = "althonos/blanket" blanket-0.3.0/Cargo.toml.orig000064400000000000000000000030251046102023000141330ustar 00000000000000[package] name = "blanket" version = "0.3.0" authors = ["Martin Larralde "] edition = "2018" resolver = "2" license = "MIT" description = "A simple macro to derive blanket implementations for your traits." repository = "https://github.com/althonos/blanket" homepage = "https://github.com/althonos/blanket" readme = "README.md" keywords = ["proc-macro", "attribute", "blanket", "trait", "impl"] categories = ["development-tools", "rust-patterns"] [package.metadata.docs.rs] features = [ "_doc" ] [badges.travis-ci] repository = "althonos/blanket" [badges.codecov] repository = "althonos/blanket" service = "github" [badges.is-it-maintained-issue-resolution] repository = "althonos/blanket" [badges.maintenance] status = "actively-developed" [lib] proc-macro = true [dependencies] quote = "1.0" proc-macro2 = "1.0" [dependencies.syn] version = "2.0" default-features = false features = ["clone-impls", "full", "parsing", "printing", "proc-macro"] [dev-dependencies] trybuild = "1.0" impls = "1.0" static_assertions = "1.1" [dev-dependencies.syn] version = "2.0" features = ["full", "extra-traits"] [features] default = [] _doc = [] [[test]] name = "derive_box" path = "tests/derive_box/mod.rs" harness = false [[test]] name = "derive_mut" path = "tests/derive_mut/mod.rs" harness = false [[test]] name = "derive_arc" path = "tests/derive_arc/mod.rs" harness = false [[test]] name = "derive_rc" path = "tests/derive_rc/mod.rs" harness = false [[test]] name = "derive_ref" path = "tests/derive_ref/mod.rs" harness = false blanket-0.3.0/README.md000064400000000000000000000153151046102023000125300ustar 00000000000000# 🧣 `blanket` [![Star me](https://img.shields.io/github/stars/althonos/blanket.svg?style=social&label=Star&maxAge=3600)](https://github.com/althonos/blanket/stargazers) *A simple macro to derive blanket implementations for your traits.* [![Actions](https://img.shields.io/github/actions/workflow/status/althonos/blanket/test.yml?branch=master&style=flat-square&maxAge=600)](https://github.com/althonos/blanket/actions) [![Codecov](https://img.shields.io/codecov/c/gh/althonos/blanket/master.svg?style=flat-square&maxAge=600)](https://codecov.io/gh/althonos/blanket) [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square&maxAge=2678400)](https://choosealicense.com/licenses/mit/) [![Source](https://img.shields.io/badge/source-GitHub-303030.svg?maxAge=2678400&style=flat-square)](https://github.com/althonos/blanket) [![Crate](https://img.shields.io/crates/v/blanket.svg?maxAge=600&style=flat-square)](https://crates.io/crates/blanket) [![Documentation](https://img.shields.io/badge/docs.rs-latest-4d76ae.svg?maxAge=2678400&style=flat-square)](https://docs.rs/blanket) [![Changelog](https://img.shields.io/badge/keep%20a-changelog-8A0707.svg?maxAge=2678400&style=flat-square)](https://github.com/althonos/blanket.rs/blob/master/CHANGELOG.md) [![GitHub issues](https://img.shields.io/github/issues/althonos/blanket.svg?style=flat-square&maxAge=600)](https://github.com/althonos/blanket/issues) ## 🔍 Overview The Rust standard library has plenty of traits, but they shine in how well they integrate with new types. Declare an implementation of [`std::io::Write`] for a type `W`, and you also get it for [`&mut W`] and [`Box`]! This however translates into a [lot of boilerplate code] that can be hard to maintain, which is why many crates don't bother providing the same convenience implementations. [`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html [lot of boilerplate code]: https://doc.rust-lang.org/src/std/io/impls.rs.html#49-79 [`&mut W`]: https://doc.rust-lang.org/std/io/trait.Write.html#impl-Write-17 [`Box`]: https://doc.rust-lang.org/std/io/trait.Write.html#impl-Write-19 This is where `blanket` comes in! This crate helps you build the same kind of blanket implementations for your own traits with as least additional code as possible: in fact, this is as close as what a `derive` macro would look like for a `trait` item. ## 🔌 Usage `blanket` exports a single eponymous attribute macro, which can be imported simply after the crate has been added to the `Cargo.toml` dependencies: ```rust extern crate blanket; use blanket::blanket; ``` ### `#[blanket(derive(...))]` Use this macro attribute to derive a blanket implementation for a trait, provided the trait methods fit the constraints for that derive, such as only declaring methods with `&self` of `&mut self` as their receiver. The following derives are available: | Derive | Impl block | `fn (&self)` | `fn (&mut self)` | `fn (self)` | |--------|--------------------------------------------|--------------|------------------|-------------| | Ref | `impl Trait for &T` | ✔️ | | | | Rc | `impl Trait for Rc` | ✔️ | | | | Arc | `impl Trait for Arc` | ✔️ | | | | Mut | `impl Trait for &mut T` | ✔️ | ✔️ | | | Box | `impl Trait for Box` | ✔️ | ✔️ | ✔️ | For instance, with our own version of `std::fmt::Write`, we can provide an implementation for `Box` and `&mut impl Write`: ```rust extern crate blanket; use blanket::blanket; #[blanket(derive(Mut, Box))] pub trait Write { fn write_str(&mut self, s: &str) -> std::fmt::Result; fn write_char(&mut self, c: char) -> std::fmt::Result { self.write_str(c.encode_utf8(&mut [0; 4])) } } ``` Note that we can't derive `Ref` because the `Write` trait we declared expects mutable references, which we can't provide from an immutable reference. If we were to try, the compiler would warn us: ```rustc ---- src/lib.rs - (line 55) stdout ---- error: cannot derive `Ref` for a trait declaring `&mut self` methods --> src/lib.rs:61:18 | 8 | fn write_str(&mut self, s: &str) -> std::fmt::Result; | ^^^^^^^^^ ``` ### `#[blanket(default = "...")]` `blanket` can delegate default implementations of trait methods to functions of another module. This can be useful for some traits such as [visitors](https://github.com/rust-unofficial/patterns/blob/master/patterns/visitor.md) to provide a default behaviour as an external function, such as what [`syn::visit`](https://docs.rs/syn/latest/syn/visit/index.html) is doing. The following example implements a very simple visitor trait for types able to process a `&str` char-by-char. ```rust extern crate blanket; use blanket::blanket; #[blanket(default = "visitor")] trait Visitor { fn visit_string(&self, s: &str); fn visit_char(&self, c: char); } mod visitor { use super::Visitor; pub fn visit_string(v: &V, s: &str) { for c in s.chars() { v.visit_char(c); } } pub fn visit_char(v: &V, c: char) {} } ``` `blanket` will check that all methods are declared without a default block, and then create a default implementation for all of the declared methods, generating the following code: ```rust trait Visitor { fn visit_string(&self, s: &str) { visitor::visit_string(self, s) } fn visit_char(&self, c: char) { visitor::visit_char(self, c) } } ``` ## 📝 To-Do - ✓ Delegation of default method to external functions. - ✓ Support for traits with generic arguments. - ✓ `#[derive(Ref)]` - ✓ `#[derive(Mut)]` - ✓ `#[derive(Box)]` - ✓ `#[derive(Rc)]` - ✓ `#[derive(Arc)]` - ✗ Update `Box` derive to allow unsized types if possible. - ✗ `#[derive(Cow)]` ## 🤝 Credits `blanket` is developed and maintained by: - [Martin Larralde](https://github.com/althonos) The following people contributed to the project: - [Alexander Linne](https://github.com/alexanderlinne) - [Naja Melan](https://github.com/najamelan) - [Justin Lovinger](https://github.com/JustinLovinger) ## 📋 Changelog This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html) and provides a [changelog](https://github.com/althonos/blanket/blob/master/CHANGELOG.md) in the [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) format. ## 📜 License This library is provided under the open-source [MIT license](https://choosealicense.com/licenses/mit/). blanket-0.3.0/src/default.rs000064400000000000000000000023751046102023000140340ustar 00000000000000use syn::spanned::Spanned; use super::utils::{prepend_function_path, signature_to_function_call}; /// Update the method declarations of `trait_` to use default implementation from `default` module. pub fn defer_trait_methods( mut trait_: syn::ItemTrait, default: syn::Path, ) -> syn::Result { for item in trait_.items.iter_mut() { if let syn::TraitItem::Fn(ref mut m) = item { // check no default implementation was provided for the current // trait method if m.default.is_some() { let msg = "method should not have default implementation if using #[blanket(default = \"...\")]"; return Err(syn::Error::new(item.span(), msg)); } // update the declaration to include a default implementation // deferring the method call to a function call in the `default_mod` // module let mut call = signature_to_function_call(&m.sig)?; prepend_function_path(&mut call, default.clone())?; m.default = Some(syn::Block { brace_token: syn::token::Brace::default(), stmts: vec![syn::Stmt::Expr(syn::Expr::Call(call), None)], }); } } Ok(trait_) } blanket-0.3.0/src/derive/arc.rs000064400000000000000000000273621046102023000144360ustar 00000000000000use syn::parse_quote; use syn::spanned::Spanned; use crate::utils::deref_expr; use crate::utils::generics_declaration_to_generics; use crate::utils::signature_to_method_call; use crate::utils::trait_to_generic_ident; pub fn derive(trait_: &syn::ItemTrait) -> syn::Result { // build an identifier for the generic type used for the implementation let trait_ident = &trait_.ident; let generic_type = trait_to_generic_ident(&trait_); // build the generics for the impl block: // we use the same generics as the trait itself, plus // a generic type that implements the trait for which we provide the // blanket implementation let trait_generics = &trait_.generics; let where_clause = &trait_.generics.where_clause; let mut impl_generics = trait_generics.clone(); // we must however remove the generic type bounds, to avoid repeating them let mut trait_generic_names = trait_generics.clone(); trait_generic_names.params = generics_declaration_to_generics(&trait_generics.params)?; impl_generics.params.push(syn::GenericParam::Type( parse_quote!(#generic_type: #trait_ident #trait_generic_names + ?Sized), )); // build the methods & associated types. let mut methods: Vec = Vec::new(); let mut assoc_types: Vec = Vec::new(); for item in trait_.items.iter() { if let syn::TraitItem::Fn(ref m) = item { if let Some(r) = m.sig.receiver() { let err = if r.colon_token.is_some() { Some("cannot derive `Arc` for a trait declaring methods with arbitrary receiver types") } else if r.mutability.is_some() { Some("cannot derive `Arc` for a trait declaring `&mut self` methods") } else if r.reference.is_none() { Some("cannot derive `Arc` for a trait declaring `self` methods") } else { None }; if let Some(msg) = err { return Err(syn::Error::new(r.span(), msg)); } } let mut call = signature_to_method_call(&m.sig)?; call.receiver = Box::new(deref_expr(deref_expr(*call.receiver))); let signature = &m.sig; let item = parse_quote!(#[inline] #signature { #call }); methods.push(item) } if let syn::TraitItem::Type(t) = item { let t_ident = &t.ident; let attrs = &t.attrs; let t_generics = &t.generics; let where_clause = &t.generics.where_clause; let mut t_generic_names = t_generics.clone(); t_generic_names.params = generics_declaration_to_generics(&t_generics.params)?; let item = parse_quote!( #(#attrs)* type #t_ident #t_generics = <#generic_type as #trait_ident #trait_generic_names>::#t_ident #t_generic_names #where_clause ; ); assoc_types.push(item); } } Ok(parse_quote!( #[automatically_derived] impl #impl_generics #trait_ident #trait_generic_names for std::sync::Arc<#generic_type> #where_clause { #(#assoc_types)* #(#methods)* } )) } #[cfg(test)] mod tests { mod derive { use syn::parse_quote; #[test] fn empty() { let trait_ = parse_quote!( trait Trait {} ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl Trait for std::sync::Arc {} ) ); } #[test] fn receiver_ref() { let trait_ = parse_quote!( trait Trait { fn my_method(&self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl Trait for std::sync::Arc { #[inline] fn my_method(&self) { (*(*self)).my_method() } } ) ); } #[test] fn receiver_mut() { let trait_ = parse_quote!( trait Trait { fn my_method(&mut self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_self() { let trait_ = parse_quote!( trait Trait { fn my_method(self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_arbitrary() { let trait_ = parse_quote!( trait Trait { fn my_method(self: Box); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn generics() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for std::sync::Arc {} ) ); } #[test] fn generics_bounded() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for std::sync::Arc {} ) ); } #[test] fn generics_lifetime() { let trait_ = parse_quote!( trait MyTrait<'a, 'b: 'a, T: 'static + Send> {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl<'a, 'b: 'a, T: 'static + Send, MT: MyTrait<'a, 'b, T> + ?Sized> MyTrait<'a, 'b, T> for std::sync::Arc { } ) ); } #[test] fn associated_types() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { type Return = ::Return; } ) ); } #[test] fn associated_types_bound() { let trait_ = parse_quote!( trait MyTrait { type Return: Clone; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { type Return = ::Return; } ) ); } #[test] fn associated_types_dodgy_name() { let trait_ = parse_quote!( trait MyTrait { type r#type; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { type r#type = ::r#type; } ) ); } #[test] fn associated_types_attrs() { let trait_ = parse_quote!( trait MyTrait { #[cfg(target_arch = "wasm32")] type Return; #[cfg(not(target_arch = "wasm32"))] type Return: Send; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { #[cfg(target_arch = "wasm32")] type Return = ::Return; #[cfg(not(target_arch = "wasm32"))] type Return = ::Return; } ) ); } #[test] fn associated_types_and_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for std::sync::Arc { type Return = >::Return; } ) ); } #[test] fn associated_type_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_bounded() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_lifetimes() { let trait_ = parse_quote!( trait MyTrait { type Return<'a> where Self: 'a; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::sync::Arc { type Return<'a> = ::Return<'a> where Self: 'a; } ) ); } } } blanket-0.3.0/src/derive/box.rs000064400000000000000000000301071046102023000144500ustar 00000000000000use syn::{parse_quote, spanned::Spanned}; use crate::utils::{ deref_expr, generics_declaration_to_generics, signature_to_method_call, trait_to_generic_ident, }; pub fn derive(trait_: &syn::ItemTrait) -> syn::Result { // build an identifier for the generic type used for the implementation let trait_ident = &trait_.ident; let generic_type = trait_to_generic_ident(&trait_); // build the generics for the impl block: // we use the same generics as the trait itself, plus // a generic type that implements the trait for which we provide the // blanket implementation let trait_generics = &trait_.generics; let where_clause = &trait_.generics.where_clause; let mut impl_generics = trait_generics.clone(); // we must however remove the generic type bounds, to avoid repeating them let mut trait_generic_names = trait_generics.clone(); trait_generic_names.params = generics_declaration_to_generics(&trait_generics.params)?; impl_generics.params.push(syn::GenericParam::Type( parse_quote!(#generic_type: #trait_ident #trait_generic_names), )); // build the methods let mut methods: Vec = Vec::new(); let mut assoc_types: Vec = Vec::new(); for item in trait_.items.iter() { if let syn::TraitItem::Fn(ref m) = item { let signature = &m.sig; let mut call = signature_to_method_call(signature)?; if let Some(r) = m.sig.receiver() { let err = if r.colon_token.is_some() { Some("cannot derive `Box` for a trait declaring methods with arbitrary receiver types") } else if r.reference.is_some() { call.receiver = Box::new(deref_expr(deref_expr(*call.receiver))); None } else { call.receiver = Box::new(deref_expr(*call.receiver)); None }; if let Some(msg) = err { return Err(syn::Error::new(r.span(), msg)); } } else { unimplemented!() } let item = parse_quote!(#[inline] #signature { #call }); methods.push(item) } if let syn::TraitItem::Type(t) = item { let t_ident = &t.ident; let attrs = &t.attrs; let t_generics = &t.generics; let where_clause = &t.generics.where_clause; let mut t_generic_names = t_generics.clone(); t_generic_names.params = generics_declaration_to_generics(&t_generics.params)?; let item = parse_quote!( #(#attrs)* type #t_ident #t_generics = <#generic_type as #trait_ident #trait_generic_names>::#t_ident #t_generic_names #where_clause ; ); assoc_types.push(item); } } // generate the impl block Ok(parse_quote!( #[automatically_derived] impl #impl_generics #trait_ident #trait_generic_names for Box<#generic_type> #where_clause { #(#assoc_types)* #(#methods)* } )) } #[cfg(test)] mod tests { mod derive { use syn::parse_quote; #[test] fn empty() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box {} ) ); } #[test] fn receiver_ref() { let trait_ = parse_quote!( trait MyTrait { fn my_method(&self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl MyTrait for Box { #[inline] fn my_method(&self) { (*(*self)).my_method() } } ) ); } #[test] fn receiver_mut() { let trait_ = parse_quote!( trait MyTrait { fn my_method(&mut self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl MyTrait for Box { #[inline] fn my_method(&mut self) { (*(*self)).my_method() } } ) ); } #[test] fn receiver_self() { let trait_ = parse_quote!( trait MyTrait { fn my_method(self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl MyTrait for Box { #[inline] fn my_method(self) { (*self).my_method() } } ) ); } #[test] fn receiver_arbitrary() { let trait_ = parse_quote!( trait MyTrait { fn my_method(self: Box); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn generics() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl> MyTrait for Box {} ) ); } #[test] fn generics_bounded() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl> MyTrait for Box {} ) ); } #[test] fn generics_lifetime() { let trait_ = parse_quote!( trait MyTrait<'a, 'b: 'a, T: 'static + Send> {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl<'a, 'b: 'a, T: 'static + Send, MT: MyTrait<'a, 'b, T>> MyTrait<'a, 'b, T> for Box {} ) ); } #[test] fn associated_types() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { type Return = ::Return; } ) ); } #[test] fn associated_types_bound() { let trait_ = parse_quote!( trait MyTrait { type Return: Clone; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { type Return = ::Return; } ) ); } #[test] fn associated_types_dodgy_name() { let trait_ = parse_quote!( trait MyTrait { type r#type; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { type r#type = ::r#type; } ) ); } #[test] fn associated_types_attrs() { let trait_ = parse_quote!( trait MyTrait { #[cfg(target_arch = "wasm32")] type Return; #[cfg(not(target_arch = "wasm32"))] type Return: Send; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { #[cfg(target_arch = "wasm32")] type Return = ::Return; #[cfg(not(target_arch = "wasm32"))] type Return = ::Return; } ) ); } #[test] fn associated_types_and_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl> MyTrait for Box { type Return = >::Return; } ) ); } #[test] fn associated_type_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_bounded() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_lifetimes() { let trait_ = parse_quote!( trait MyTrait { type Return<'a> where Self: 'a; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for Box { type Return<'a> = ::Return<'a> where Self: 'a; } ) ); } } } blanket-0.3.0/src/derive/mod.rs000064400000000000000000000020241046102023000144340ustar 00000000000000mod arc; mod r#box; mod r#mut; mod rc; mod r#ref; #[derive(Debug, PartialEq, Eq, Hash)] pub enum Derive { Box, Ref, Mut, Rc, Arc, } impl Derive { pub fn from_str(s: &str) -> Option { match s { "Box" => Some(Derive::Box), "Ref" => Some(Derive::Ref), "Mut" => Some(Derive::Mut), "Rc" => Some(Derive::Rc), "Arc" => Some(Derive::Arc), _ => None, } } pub fn from_path(p: &syn::Path) -> Option { p.segments .first() .and_then(|s| Self::from_str(&s.ident.to_string())) } pub fn defer_trait_methods(&self, trait_: &syn::ItemTrait) -> syn::Result { match self { Derive::Box => self::r#box::derive(trait_), Derive::Ref => self::r#ref::derive(trait_), Derive::Mut => self::r#mut::derive(trait_), Derive::Rc => self::rc::derive(trait_), Derive::Arc => self::arc::derive(trait_), } } } blanket-0.3.0/src/derive/mut.rs000064400000000000000000000262511046102023000144720ustar 00000000000000use syn::{parse_quote, spanned::Spanned}; use crate::utils::{ deref_expr, generics_declaration_to_generics, signature_to_method_call, trait_to_generic_ident, }; pub fn derive(trait_: &syn::ItemTrait) -> syn::Result { // build an identifier for the generic type used for the implementation let trait_ident = &trait_.ident; let generic_type = trait_to_generic_ident(&trait_); // build the generics for the impl block: // we use the same generics as the trait itself, plus // a generic type that implements the trait for which we provide the // blanket implementation let trait_generics = &trait_.generics; let where_clause = &trait_.generics.where_clause; let mut impl_generics = trait_generics.clone(); // we must however remove the generic type bounds, to avoid repeating them let mut trait_generic_names = trait_generics.clone(); trait_generic_names.params = generics_declaration_to_generics(&trait_generics.params)?; impl_generics.params.push(syn::GenericParam::Type( parse_quote!(#generic_type: #trait_ident #trait_generic_names + ?Sized), )); // build the methods let mut methods: Vec = Vec::new(); let mut assoc_types: Vec = Vec::new(); for item in trait_.items.iter() { if let syn::TraitItem::Fn(ref m) = item { if let Some(r) = m.sig.receiver() { let err = if r.colon_token.is_some() { Some("cannot derive `Mut` for a trait declaring methods with arbitrary receiver types") } else if r.reference.is_none() { Some("cannot derive `Mut` for a trait declaring `self` methods") } else { None }; if let Some(msg) = err { return Err(syn::Error::new(r.span(), msg)); } } let mut call = signature_to_method_call(&m.sig)?; call.receiver = Box::new(deref_expr(deref_expr(*call.receiver))); let signature = &m.sig; let item = parse_quote!(#[inline] #signature { #call }); methods.push(item) } if let syn::TraitItem::Type(t) = item { let t_ident = &t.ident; let attrs = &t.attrs; let t_generics = &t.generics; let where_clause = &t.generics.where_clause; let mut t_generic_names = t_generics.clone(); t_generic_names.params = generics_declaration_to_generics(&t_generics.params)?; let item = parse_quote!( #(#attrs)* type #t_ident #t_generics = <#generic_type as #trait_ident #trait_generic_names>::#t_ident #t_generic_names #where_clause ; ); assoc_types.push(item); } } Ok(parse_quote!( #[automatically_derived] impl #impl_generics #trait_ident #trait_generic_names for &mut #generic_type #where_clause { #(#assoc_types)* #(#methods)* } )) } #[cfg(test)] mod tests { mod derive { use syn::parse_quote; #[test] fn empty() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT {} ) ); } #[test] fn receiver_mut() { let trait_ = parse_quote!( trait MyTrait { fn my_method(&mut self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { #[inline] fn my_method(&mut self) { (*(*self)).my_method() } } ) ); } #[test] fn receiver_self() { let trait_ = parse_quote!( trait MyTrait { fn my_method(self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_arbitrary() { let trait_ = parse_quote!( trait MyTrait { fn my_method(self: Box); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn generics() { let trait_ = parse_quote!( trait Trait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> Trait for &mut T_ {} ) ); } #[test] fn generics_bounded() { let trait_ = parse_quote!( trait Trait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> Trait for &mut T_ {} ) ); } #[test] fn generics_lifetime() { let trait_ = parse_quote!( trait Trait<'a, 'b: 'a, T: 'static + Send> {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl<'a, 'b: 'a, T: 'static + Send, T_: Trait<'a, 'b, T> + ?Sized> Trait<'a, 'b, T> for &mut T_ { } ) ); } #[test] fn associated_types() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { type Return = ::Return; } ) ); } #[test] fn associated_types_bound() { let trait_ = parse_quote!( trait MyTrait { type Return: Clone; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { type Return = ::Return; } ) ); } #[test] fn associated_types_dodgy_name() { let trait_ = parse_quote!( trait MyTrait { type r#type; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { type r#type = ::r#type; } ) ); } #[test] fn associated_types_attrs() { let trait_ = parse_quote!( trait MyTrait { #[cfg(target_arch = "wasm32")] type Return; #[cfg(not(target_arch = "wasm32"))] type Return: Send; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { #[cfg(target_arch = "wasm32")] type Return = ::Return; #[cfg(not(target_arch = "wasm32"))] type Return = ::Return; } ) ); } #[test] fn associated_types_and_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for &mut MT { type Return = >::Return; } ) ); } #[test] fn associated_type_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_bounded() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_lifetimes() { let trait_ = parse_quote!( trait MyTrait { type Return<'a> where Self: 'a; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &mut MT { type Return<'a> = ::Return<'a> where Self: 'a; } ) ); } } } blanket-0.3.0/src/derive/rc.rs000064400000000000000000000271751046102023000142770ustar 00000000000000use syn::{parse_quote, spanned::Spanned}; use crate::utils::{ deref_expr, generics_declaration_to_generics, signature_to_method_call, trait_to_generic_ident, }; pub fn derive(trait_: &syn::ItemTrait) -> syn::Result { // build an identifier for the generic type used for the implementation let trait_ident = &trait_.ident; let generic_type = trait_to_generic_ident(&trait_); // build the generics for the impl block: // we use the same generics as the trait itself, plus // a generic type that implements the trait for which we provide the // blanket implementation let trait_generics = &trait_.generics; let where_clause = &trait_.generics.where_clause; let mut impl_generics = trait_generics.clone(); // we must however remove the generic type bounds, to avoid repeating them let mut trait_generic_names = trait_generics.clone(); trait_generic_names.params = generics_declaration_to_generics(&trait_generics.params)?; impl_generics.params.push(syn::GenericParam::Type( parse_quote!(#generic_type: #trait_ident #trait_generic_names + ?Sized), )); // build the methods let mut methods: Vec = Vec::new(); let mut assoc_types: Vec = Vec::new(); for item in trait_.items.iter() { if let syn::TraitItem::Fn(ref m) = item { if let Some(r) = m.sig.receiver() { let err = if r.colon_token.is_some() { Some("cannot derive `Rc` for a trait declaring methods with arbitrary receiver types") } else if r.mutability.is_some() { Some("cannot derive `Rc` for a trait declaring `&mut self` methods") } else if r.reference.is_none() { Some("cannot derive `Rc` for a trait declaring `self` methods") } else { None }; if let Some(msg) = err { return Err(syn::Error::new(r.span(), msg)); } } let mut call = signature_to_method_call(&m.sig)?; call.receiver = Box::new(deref_expr(deref_expr(*call.receiver))); let signature = &m.sig; let item = parse_quote!(#[inline] #signature { #call }); methods.push(item) } if let syn::TraitItem::Type(t) = item { let t_ident = &t.ident; let attrs = &t.attrs; let t_generics = &t.generics; let where_clause = &t.generics.where_clause; let mut t_generic_names = t_generics.clone(); t_generic_names.params = generics_declaration_to_generics(&t_generics.params)?; let item = parse_quote!( #(#attrs)* type #t_ident #t_generics = <#generic_type as #trait_ident #trait_generic_names>::#t_ident #t_generic_names #where_clause ; ); assoc_types.push(item); } } Ok(parse_quote!( #[automatically_derived] impl #impl_generics #trait_ident #trait_generic_names for std::rc::Rc<#generic_type> #where_clause { #(#assoc_types)* #(#methods)* } )) } #[cfg(test)] mod tests { mod derive { use syn::parse_quote; #[test] fn empty() { let trait_ = parse_quote!( trait Trait {} ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl Trait for std::rc::Rc {} ) ); } #[test] fn receiver_ref() { let trait_ = parse_quote!( trait Trait { fn my_method(&self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl Trait for std::rc::Rc { #[inline] fn my_method(&self) { (*(*self)).my_method() } } ) ); } #[test] fn receiver_mut() { let trait_ = parse_quote!( trait Trait { fn my_method(&mut self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_self() { let trait_ = parse_quote!( trait Trait { fn my_method(self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_arbitrary() { let trait_ = parse_quote!( trait Trait { fn my_method(self: Box); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn generics() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for std::rc::Rc {} ) ); } #[test] fn generics_bounded() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for std::rc::Rc {} ) ); } #[test] fn generics_lifetime() { let trait_ = parse_quote!( trait MyTrait<'a, 'b: 'a, T: 'static + Send> {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl<'a, 'b: 'a, T: 'static + Send, MT: MyTrait<'a, 'b, T> + ?Sized> MyTrait<'a, 'b, T> for std::rc::Rc { } ) ); } #[test] fn associated_types() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { type Return = ::Return; } ) ); } #[test] fn associated_types_bound() { let trait_ = parse_quote!( trait MyTrait { type Return: Clone; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { type Return = ::Return; } ) ); } #[test] fn associated_types_dodgy_name() { let trait_ = parse_quote!( trait MyTrait { type r#type; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { type r#type = ::r#type; } ) ); } #[test] fn associated_types_attrs() { let trait_ = parse_quote!( trait MyTrait { #[cfg(target_arch = "wasm32")] type Return; #[cfg(not(target_arch = "wasm32"))] type Return: Send; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { #[cfg(target_arch = "wasm32")] type Return = ::Return; #[cfg(not(target_arch = "wasm32"))] type Return = ::Return; } ) ); } #[test] fn associated_types_and_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for std::rc::Rc { type Return = >::Return; } ) ); } #[test] fn associated_type_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_bounded() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_lifetimes() { let trait_ = parse_quote!( trait MyTrait { type Return<'a> where Self: 'a; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for std::rc::Rc { type Return<'a> = ::Return<'a> where Self: 'a; } ) ); } } } blanket-0.3.0/src/derive/ref.rs000064400000000000000000000267301046102023000144430ustar 00000000000000use syn::{parse_quote, spanned::Spanned}; use crate::utils::{ deref_expr, generics_declaration_to_generics, signature_to_method_call, trait_to_generic_ident, }; pub fn derive(trait_: &syn::ItemTrait) -> syn::Result { // build an identifier for the generic type used for the implementation let trait_ident = &trait_.ident; let generic_type = trait_to_generic_ident(&trait_); // build the generics for the impl block: // we use the same generics as the trait itself, plus // a generic type that implements the trait for which we provide the // blanket implementation let trait_generics = &trait_.generics; let where_clause = &trait_.generics.where_clause; let mut impl_generics = trait_generics.clone(); // we must however remove the generic type bounds, to avoid repeating them let mut trait_generic_names = trait_generics.clone(); trait_generic_names.params = generics_declaration_to_generics(&trait_generics.params)?; impl_generics.params.push(syn::GenericParam::Type( parse_quote!(#generic_type: #trait_ident #trait_generic_names + ?Sized), )); // build the methods let mut methods: Vec = Vec::new(); let mut assoc_types: Vec = Vec::new(); for item in trait_.items.iter() { if let syn::TraitItem::Fn(ref m) = item { if let Some(r) = m.sig.receiver() { let err = if r.colon_token.is_some() { Some("cannot derive `Ref` for a trait declaring methods with arbitrary receiver types") } else if r.mutability.is_some() { Some("cannot derive `Ref` for a trait declaring `&mut self` methods") } else if r.reference.is_none() { Some("cannot derive `Ref` for a trait declaring `self` methods") } else { None }; if let Some(msg) = err { return Err(syn::Error::new(r.span(), msg)); } } let mut call = signature_to_method_call(&m.sig)?; call.receiver = Box::new(deref_expr(deref_expr(*call.receiver))); let signature = &m.sig; let item = parse_quote!(#[inline] #signature { #call }); methods.push(item) } if let syn::TraitItem::Type(t) = item { let t_ident = &t.ident; let attrs = &t.attrs; let t_generics = &t.generics; let where_clause = &t.generics.where_clause; let mut t_generic_names = t_generics.clone(); t_generic_names.params = generics_declaration_to_generics(&t_generics.params)?; let item = parse_quote!( #(#attrs)* type #t_ident #t_generics = <#generic_type as #trait_ident #trait_generic_names>::#t_ident #t_generic_names #where_clause ; ); assoc_types.push(item); } } Ok(parse_quote!( #[automatically_derived] impl #impl_generics #trait_ident #trait_generic_names for &#generic_type #where_clause { #(#assoc_types)* #(#methods)* } )) } #[cfg(test)] mod tests { mod derive { use syn::parse_quote; #[test] fn empty() { let trait_ = parse_quote!( trait Trait {} ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl Trait for &T {} ) ); } #[test] fn receiver_ref() { let trait_ = parse_quote!( trait Trait { fn my_method(&self); } ); assert_eq!( super::super::derive(&trait_).unwrap(), parse_quote!( #[automatically_derived] impl Trait for &T { #[inline] fn my_method(&self) { (*(*self)).my_method() } } ) ); } #[test] fn receiver_mut() { let trait_ = parse_quote!( trait Trait { fn my_method(&mut self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_self() { let trait_ = parse_quote!( trait Trait { fn my_method(self); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn receiver_arbitrary() { let trait_ = parse_quote!( trait Trait { fn my_method(self: Box); } ); assert!(super::super::derive(&trait_).is_err()); } #[test] fn generics() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for &MT {} ) ); } #[test] fn generics_bounded() { let trait_ = parse_quote!( trait MyTrait {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for &MT {} ) ); } #[test] fn generics_lifetime() { let trait_ = parse_quote!( trait MyTrait<'a, 'b: 'a, T: 'static + Send> {} ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl<'a, 'b: 'a, T: 'static + Send, MT: MyTrait<'a, 'b, T> + ?Sized> MyTrait<'a, 'b, T> for &MT { } ) ); } #[test] fn associated_types() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { type Return = ::Return; } ) ); } #[test] fn associated_types_bound() { let trait_ = parse_quote!( trait MyTrait { type Return: Clone; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { type Return = ::Return; } ) ); } #[test] fn associated_types_dodgy_name() { let trait_ = parse_quote!( trait MyTrait { type r#type; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { type r#type = ::r#type; } ) ); } #[test] fn associated_types_attrs() { let trait_ = parse_quote!( trait MyTrait { #[cfg(target_arch = "wasm32")] type Return; #[cfg(not(target_arch = "wasm32"))] type Return: Send; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { #[cfg(target_arch = "wasm32")] type Return = ::Return; #[cfg(not(target_arch = "wasm32"))] type Return = ::Return; } ) ); } #[test] fn associated_types_and_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl + ?Sized> MyTrait for &MT { type Return = >::Return; } ) ); } #[test] fn associated_type_generics() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_bounded() { let trait_ = parse_quote!( trait MyTrait { type Return; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { type Return = ::Return; } ) ); } #[test] fn associated_type_generics_lifetimes() { let trait_ = parse_quote!( trait MyTrait { type Return<'a> where Self: 'a; } ); let derived = super::super::derive(&trait_).unwrap(); assert_eq!( derived, parse_quote!( #[automatically_derived] impl MyTrait for &MT { type Return<'a> = ::Return<'a> where Self: 'a; } ) ); } } } blanket-0.3.0/src/lib.rs000064400000000000000000000116021046102023000131470ustar 00000000000000#![cfg_attr(feature = "_doc", feature(doc_cfg, external_doc))] #![cfg_attr(feature = "_doc", doc(include = "../README.md"))] extern crate proc_macro; extern crate proc_macro2; extern crate quote; use std::collections::HashSet; use quote::{quote, ToTokens}; use syn::{parse_macro_input, punctuated::Punctuated, spanned::Spanned}; // --------------------------------------------------------------------------- mod default; mod derive; mod utils; // --------------------------------------------------------------------------- struct Args { default: Option, derives: HashSet, } impl Args { fn from_meta(arg: &syn::Meta) -> syn::Result { let mut default = None; let mut derives = HashSet::new(); match arg { syn::Meta::List(ref l) if l.path.to_token_stream().to_string() == "derive" => { let types = l.parse_args_with( Punctuated::::parse_separated_nonempty, )?; for pair in types.into_pairs() { if let Some(d) = derive::Derive::from_path(pair.value()) { derives.insert(d); } else { return Err(syn::Error::new( pair.span(), "unknown blanket derive option", )); } } } syn::Meta::NameValue(ref n) if n.path.to_token_stream().to_string() == "default" => { match n.value { syn::Expr::Lit(ref lit) => { if let syn::Lit::Str(ref s) = lit.lit { match syn::parse_str(&s.value()) { Ok(path) if default.is_none() => { default = Some(path); } Ok(_) => { return Err(syn::Error::new( s.span(), "duplicate default module given", )) } Err(_) => { return Err(syn::Error::new( s.span(), "expected module identifier", )) } } } else { return Err(syn::Error::new(lit.lit.span(), "expected string literal")); } } syn::Expr::Path(ref expr) => { if default.replace(expr.path.clone()).is_some() { return Err(syn::Error::new( n.span(), "duplicate default module given", )); } } _ => { return Err(syn::Error::new( n.value.span(), "expected path or string literal", )); } } } _ => return Err(syn::Error::new(arg.span(), "unexpected argument")), } Ok(Self { default, derives }) } } // --------------------------------------------------------------------------- #[proc_macro_attribute] pub fn blanket( args: proc_macro::TokenStream, input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { // parse input let trait_ = parse_macro_input!(input as syn::ItemTrait); let args = parse_macro_input!(args as syn::Meta); // parse macro arguments and immediately exit if they are invalid let args = match Args::from_meta(&args) { Ok(args) => args, Err(e) => { let err = e.to_compile_error(); return proc_macro::TokenStream::from(quote!(#err #trait_)); } }; // generate output let mut out = proc_macro2::TokenStream::new(); // update trait methods declaration if given a `default = "..."` argument, // otherwise simply keep the output match args.default { None => out.extend(quote!(#trait_)), Some(d) => match default::defer_trait_methods(trait_.clone(), d) { Ok(trait_) => out.extend(quote!(#trait_)), Err(err) => out.extend(err.to_compile_error()), }, }; // add derived implementations for d in args.derives { match d.defer_trait_methods(&trait_) { Ok(item) => out.extend(quote!(#item)), Err(e) => out.extend(e.to_compile_error()), } } // // return the new `proc-macro2` token stream as a `proc-macro` stream proc_macro::TokenStream::from(out) } blanket-0.3.0/src/utils.rs000064400000000000000000000156501046102023000135500ustar 00000000000000use quote::quote_spanned; use syn::{parse_quote, punctuated::Punctuated, spanned::Spanned, GenericParam, Token}; /// Convert a function signature to a function call with the same arguments. pub fn signature_to_function_call(sig: &syn::Signature) -> syn::Result { // Simply use the function ident as the function expression. let funcexpr = syn::ExprPath { attrs: Vec::new(), qself: None, path: sig.ident.clone().into(), }; // Extract arguments from the method signature names let mut funcargs = Punctuated::new(); for item in &sig.inputs { match item { syn::FnArg::Receiver(recv) => { let span = recv.self_token.span; funcargs.push(syn::parse2(quote_spanned!(span=> self))?); } syn::FnArg::Typed(argty) => { if let syn::Pat::Ident(ref id) = *argty.pat { let argpath = syn::ExprPath { attrs: Vec::new(), qself: None, path: id.ident.clone().into(), }; funcargs.push(syn::Expr::Path(argpath)); } else { return Err(syn::Error::new(argty.span(), "expected identifier")); } } } } // Return the function call as an expression Ok(syn::ExprCall { attrs: Vec::new(), paren_token: syn::token::Paren::default(), func: Box::new(funcexpr.into()), args: funcargs, }) } /// Convert a function signature to a method call with the same arguments. pub fn signature_to_method_call(sig: &syn::Signature) -> syn::Result { // Extract receiver let receiver = sig.receiver().unwrap(); let span = receiver.span(); // Extract arguments let mut funcargs = Punctuated::new(); for item in &sig.inputs { match item { syn::FnArg::Receiver(_) => {} syn::FnArg::Typed(argty) => { if let syn::Pat::Ident(ref id) = *argty.pat { let argpath = syn::ExprPath { attrs: Vec::new(), qself: None, path: id.ident.clone().into(), }; funcargs.push(syn::Expr::Path(argpath)); } else { return Err(syn::Error::new(argty.span(), "expected identifier")); } } } } // Write the method call Ok(syn::ExprMethodCall { attrs: Vec::new(), receiver: Box::new(syn::parse2(quote_spanned!(span=> self))?), dot_token: syn::token::Dot { spans: [sig.span()], }, method: sig.ident.clone(), turbofish: None, paren_token: syn::token::Paren::default(), args: funcargs, }) } /// Prepend a module path to a function call name. pub fn prepend_function_path(call: &mut syn::ExprCall, module: syn::Path) -> syn::Result<()> { if let syn::Expr::Path(ref mut path) = *call.func { for (i, segment) in module.segments.into_iter().enumerate() { path.path.segments.insert(i, segment); } Ok(()) } else { Err(syn::Error::new(call.func.span(), "expected path")) } } /// Deref an expression and wrap it in brackets to preserve operation priority. pub fn deref_expr(expr: syn::Expr) -> syn::Expr { syn::Expr::Paren(syn::ExprParen { attrs: Vec::new(), paren_token: syn::token::Paren::default(), expr: Box::new(syn::Expr::Unary(syn::ExprUnary { attrs: Vec::new(), op: syn::UnOp::Deref(parse_quote!(*)), expr: Box::new(expr), })), }) } /// Build a generic identifier suitable for the given trait. /// /// This function extracts the initials of the trait identifier. If this results /// in a generic type identifier already present in the generics of that trait, /// as many underscores are added to the end of the identifier. pub fn trait_to_generic_ident(trait_: &syn::ItemTrait) -> syn::Ident { let mut raw = trait_ .ident .to_string() .chars() .filter(|c| c.is_uppercase()) .collect::(); loop { if !trait_.generics.params.iter().any(|g| match g { syn::GenericParam::Type(param) if param.ident == raw => true, syn::GenericParam::Const(param) if param.ident == raw => true, _ => false, }) { break; } else { raw.push('_'); } } syn::Ident::new(&raw, trait_.ident.span()) } /// Convert a generic type declaration to a generic with the same arguments. /// /// Given a generic section ``, get simply ``. pub fn generics_declaration_to_generics( generics: &Punctuated, ) -> syn::Result> { generics .iter() .map(|gen| match gen { syn::GenericParam::Type(t) => Ok(syn::GenericParam::Type(syn::TypeParam { attrs: t.attrs.clone(), ident: t.ident.clone(), colon_token: None, bounds: Punctuated::new(), eq_token: None, default: None, })), syn::GenericParam::Lifetime(l) => Ok(syn::GenericParam::Lifetime(syn::LifetimeParam { attrs: l.attrs.clone(), lifetime: l.lifetime.clone(), colon_token: None, bounds: Punctuated::new(), })), syn::GenericParam::Const(c) => { Err(syn::Error::new(c.span(), "cannot handle const generics")) } }) .collect() } #[cfg(test)] mod tests { use syn::parse_quote; #[test] fn prepend_function_path() { let path = parse_quote!(crate::qualified::path); let mut call = parse_quote!(myfunction(arg1, arg2)); super::prepend_function_path(&mut call, path).unwrap(); assert_eq!( call, parse_quote!(crate::qualified::path::myfunction(arg1, arg2)) ); } #[test] fn deref_expr() { let expr = parse_quote!(self); let dereffed = super::deref_expr(expr); assert_eq!(dereffed, parse_quote!((*self))); } #[test] fn trait_to_generic_ident() { let trait_ = syn::parse_quote!( trait Trait {} ); let expected: syn::Ident = syn::parse_quote!(T); assert_eq!(super::trait_to_generic_ident(&trait_), expected); let trait_ = syn::parse_quote!( trait SomeTrait {} ); let expected: syn::Ident = syn::parse_quote!(ST); assert_eq!(super::trait_to_generic_ident(&trait_), expected); let trait_ = syn::parse_quote!( trait Trait {} ); let expected: syn::Ident = syn::parse_quote!(T_); assert_eq!(super::trait_to_generic_ident(&trait_), expected); } } blanket-0.3.0/tests/char_visitor.rs000064400000000000000000000030201046102023000154430ustar 00000000000000#![allow(unused)] extern crate blanket; use blanket::blanket; #[blanket(default = "visitor")] pub trait Visitor { fn visit_str(&mut self, s: &str); fn visit_char(&mut self, c: char); } pub mod visitor { use super::Visitor; pub fn visit_str(v: &mut V, s: &str) { for c in s.chars() { v.visit_char(c); } } pub fn visit_char(v: &mut V, c: char) {} } #[test] fn test_default() { #[derive(Default)] struct CharCounter { count: usize, } impl Visitor for CharCounter { fn visit_char(&mut self, c: char) { self.count += 1 } } let mut counter = CharCounter::default(); let string = String::from("Hello, world!"); counter.visit_str(&string); assert_eq!(counter.count, string.len()); } #[test] fn test_overload() { #[derive(Default)] struct CharBytesCounter { count: usize, bytes: usize, } impl Visitor for CharBytesCounter { fn visit_str(&mut self, s: &str) { self.bytes += s.as_bytes().len(); self::visitor::visit_str(self, s); } fn visit_char(&mut self, c: char) { self.count += 1 } } let mut counter = CharBytesCounter::default(); let string = String::from("Hello, 🌍!"); counter.visit_str(&string); assert_eq!( counter.count, string.chars().enumerate().last().unwrap().0 + 1 ); assert_eq!(counter.bytes, string.as_bytes().len()); } blanket-0.3.0/tests/derive_arc/fails/noderive.rs000064400000000000000000000010541046102023000177700ustar 00000000000000extern crate impls; extern crate static_assertions; use std::sync::Arc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use impls::impls; use static_assertions::const_assert; pub trait Counter { fn increment(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8 } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { const_assert!(impls!(AtomicCounter: Counter)); const_assert!(impls!(Arc: Counter)); } blanket-0.3.0/tests/derive_arc/fails/noderive.stderr000064400000000000000000000006361046102023000206540ustar 00000000000000error[E0080]: evaluation of constant value failed --> tests/derive_arc/fails/noderive.rs:28:5 | 28 | const_assert!(impls!(Arc: Counter)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow | = note: this error originates in the macro `const_assert` (in Nightly builds, run with -Z macro-backtrace for more info) blanket-0.3.0/tests/derive_arc/fails/receiver_box.rs000064400000000000000000000002151046102023000206270ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Arc))] pub trait Counter { fn increment(self: Box); } fn main() {} blanket-0.3.0/tests/derive_arc/fails/receiver_box.stderr000064400000000000000000000003301046102023000215040ustar 00000000000000error: cannot derive `Arc` for a trait declaring methods with arbitrary receiver types --> tests/derive_arc/fails/receiver_box.rs:7:18 | 7 | fn increment(self: Box); | ^^^^^^^^^^^^^^^ blanket-0.3.0/tests/derive_arc/fails/receiver_mut.rs000064400000000000000000000002071046102023000206450ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Arc))] pub trait Counter { fn increment(&mut self); } fn main() {} blanket-0.3.0/tests/derive_arc/fails/receiver_mut.stderr000064400000000000000000000002721046102023000215260ustar 00000000000000error: cannot derive `Arc` for a trait declaring `&mut self` methods --> tests/derive_arc/fails/receiver_mut.rs:7:18 | 7 | fn increment(&mut self); | ^^^^^^^^^ blanket-0.3.0/tests/derive_arc/fails/receiver_self.rs000064400000000000000000000002001046102023000207620ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Arc))] pub trait Extract { fn extract(self); } fn main() {} blanket-0.3.0/tests/derive_arc/fails/receiver_self.stderr000064400000000000000000000002261046102023000216510ustar 00000000000000error: cannot derive `Arc` for a trait declaring `self` methods --> $DIR/receiver_self.rs:7:16 | 7 | fn extract(self); | ^^^^ blanket-0.3.0/tests/derive_arc/mod.rs000064400000000000000000000003371046102023000156410ustar 00000000000000extern crate trybuild; fn main() { #[cfg(not(tarpaulin))] let t = trybuild::TestCases::new(); t.compile_fail(file!().replace("mod.rs", "fails/*.rs")); t.pass(file!().replace("mod.rs", "successes/*.rs")); } blanket-0.3.0/tests/derive_arc/successes/assoc_type.rs000064400000000000000000000012161046102023000212300ustar 00000000000000use std::sync::Arc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Arc))] pub trait Counter { type Return: Clone; // <- verify this fn increment(&self) -> Self::Return; } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { // Generate something like `type Return = ::Return;`. type Return = u8; fn increment(&self) -> u8 { self.count.fetch_add(1, Ordering::SeqCst) } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Arc: Counter)); } blanket-0.3.0/tests/derive_arc/successes/receiver_ref.rs000064400000000000000000000010361046102023000215170ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::Arc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Arc))] pub trait Counter { fn increment(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Arc: Counter)); } blanket-0.3.0/tests/derive_arc/successes/trait_generics.rs000064400000000000000000000010671046102023000220650ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::Arc; use blanket::blanket; use impls::impls; #[blanket(derive(Arc))] pub trait AsRef2 { fn as_ref2(&self) -> &T; } #[derive(Default)] struct Owner { owned: T, } impl AsRef2 for Owner { fn as_ref2(&self) -> &T { &self.owned } } fn main() { assert!(impls!(Owner: AsRef2)); assert!(impls!(Arc>: AsRef2)); assert!(impls!(Owner: AsRef2)); assert!(impls!(Arc>: AsRef2)); } blanket-0.3.0/tests/derive_arc/successes/where_clause_assoc_fn.rs000064400000000000000000000012331046102023000233770ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::Arc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Arc))] pub trait Counter where T: Clone, { fn increment(&self, t: T); fn super_helpful_helper(&self, t: T) { self.increment(t.clone()) } } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self, value: u8) { self.count.fetch_add(value, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Arc: Counter)); } blanket-0.3.0/tests/derive_box/fails/noderive.rs000064400000000000000000000006271046102023000200200ustar 00000000000000extern crate impls; extern crate static_assertions; use impls::impls; use static_assertions::const_assert; pub trait Counter { fn increment(&mut self); } struct AtomicCounter(u8); impl Counter for AtomicCounter { fn increment(&mut self) { self.0 += 1; } } fn main() { const_assert!(impls!(AtomicCounter: Counter)); const_assert!(impls!(Box: Counter)); } blanket-0.3.0/tests/derive_box/fails/noderive.stderr000064400000000000000000000006341046102023000206750ustar 00000000000000error[E0080]: evaluation of constant value failed --> tests/derive_box/fails/noderive.rs:21:5 | 21 | const_assert!(impls!(Box: Counter)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow | = note: this error originates in the macro `const_assert` (in Nightly builds, run with -Z macro-backtrace for more info) blanket-0.3.0/tests/derive_box/mod.rs000064400000000000000000000003041046102023000156560ustar 00000000000000extern crate trybuild; fn main() { let t = trybuild::TestCases::new(); t.compile_fail(file!().replace("mod.rs", "fails/*.rs")); t.pass(file!().replace("mod.rs", "successes/*.rs")); } blanket-0.3.0/tests/derive_box/successes/assoc_type.rs000064400000000000000000000011721046102023000212540ustar 00000000000000use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait Counter { type Return: Clone; // <- verify this fn increment(&self) -> Self::Return; } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { // Generate something like `type Return = ::Return;`. type Return = u8; fn increment(&self) -> u8 { self.count.fetch_add(1, Ordering::SeqCst) } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Box: Counter)); } blanket-0.3.0/tests/derive_box/successes/receiver_mix.rs000064400000000000000000000011761046102023000215700ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait Counter { fn increment(&mut self); fn decrement(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&mut self) { self.count.fetch_add(1, Ordering::SeqCst); } fn decrement(&self) { self.count.fetch_sub(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Box: Counter)); } blanket-0.3.0/tests/derive_box/successes/receiver_mut.rs000064400000000000000000000006571046102023000216030ustar 00000000000000extern crate blanket; extern crate impls; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait Counter { fn increment(&mut self); } #[derive(Default)] struct AtomicCounter { count: u8, } impl Counter for AtomicCounter { fn increment(&mut self) { self.count += 1; } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Box: Counter)); } blanket-0.3.0/tests/derive_box/successes/receiver_ref.rs000064400000000000000000000007671046102023000215540ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait Counter { fn increment(&self); } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Box: Counter)); } blanket-0.3.0/tests/derive_box/successes/receiver_self.rs000064400000000000000000000006521046102023000217220ustar 00000000000000extern crate blanket; extern crate impls; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait StringBuilder { fn build(self) -> String; } struct Concat { strings: Vec, } impl StringBuilder for Concat { fn build(self) -> String { self.strings.join("") } } fn main() { assert!(impls!(Concat: StringBuilder)); assert!(impls!(Box: StringBuilder)); } blanket-0.3.0/tests/derive_box/successes/trait_generics.rs000064400000000000000000000010421046102023000221010ustar 00000000000000extern crate blanket; extern crate impls; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait AsRef2 { fn as_ref2(&self) -> &T; } #[derive(Default)] struct Owner { owned: T, } impl AsRef2 for Owner { fn as_ref2(&self) -> &T { &self.owned } } fn main() { assert!(impls!(Owner: AsRef2)); assert!(impls!(Box>: AsRef2)); assert!(impls!(Owner: AsRef2)); assert!(impls!(Box>: AsRef2)); } blanket-0.3.0/tests/derive_box/successes/where_clause_assoc_fn.rs000064400000000000000000000012071046102023000234230ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Box))] pub trait Counter where T: Clone, { fn increment(&self, t: T); fn super_helpful_helper(&self, t: T) { self.increment(t.clone()) } } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self, value: u8) { self.count.fetch_add(value, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Box: Counter)); } blanket-0.3.0/tests/derive_mut/fails/noderive.rs000064400000000000000000000006271046102023000200350ustar 00000000000000extern crate impls; extern crate static_assertions; use impls::impls; use static_assertions::const_assert; pub trait Counter { fn increment(&mut self); } struct AtomicCounter(u8); impl Counter for AtomicCounter { fn increment(&mut self) { self.0 += 1; } } fn main() { const_assert!(impls!(AtomicCounter: Counter)); const_assert!(impls!(&mut AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_mut/fails/noderive.stderr000064400000000000000000000006341046102023000207120ustar 00000000000000error[E0080]: evaluation of constant value failed --> tests/derive_mut/fails/noderive.rs:21:5 | 21 | const_assert!(impls!(&mut AtomicCounter: Counter)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow | = note: this error originates in the macro `const_assert` (in Nightly builds, run with -Z macro-backtrace for more info) blanket-0.3.0/tests/derive_mut/fails/receiver_box.rs000064400000000000000000000002151046102023000206670ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Mut))] pub trait Counter { fn increment(self: Box); } fn main() {} blanket-0.3.0/tests/derive_mut/fails/receiver_box.stderr000064400000000000000000000003301046102023000215440ustar 00000000000000error: cannot derive `Mut` for a trait declaring methods with arbitrary receiver types --> tests/derive_mut/fails/receiver_box.rs:7:18 | 7 | fn increment(self: Box); | ^^^^^^^^^^^^^^^ blanket-0.3.0/tests/derive_mut/fails/receiver_self.rs000064400000000000000000000002001046102023000210220ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Mut))] pub trait Extract { fn extract(self); } fn main() {} blanket-0.3.0/tests/derive_mut/fails/receiver_self.stderr000064400000000000000000000002261046102023000217110ustar 00000000000000error: cannot derive `Mut` for a trait declaring `self` methods --> $DIR/receiver_self.rs:7:16 | 7 | fn extract(self); | ^^^^ blanket-0.3.0/tests/derive_mut/mod.rs000064400000000000000000000003041046102023000156730ustar 00000000000000extern crate trybuild; fn main() { let t = trybuild::TestCases::new(); t.compile_fail(file!().replace("mod.rs", "fails/*.rs")); t.pass(file!().replace("mod.rs", "successes/*.rs")); } blanket-0.3.0/tests/derive_mut/successes/assoc_type.rs000064400000000000000000000012021046102023000212630ustar 00000000000000use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Mut))] pub trait Counter { type Return: Clone; // <- verify this fn increment(&mut self) -> Self::Return; } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { // Generate something like `type Return = ::Return;`. type Return = u8; fn increment(&mut self) -> u8 { self.count.fetch_add(1, Ordering::SeqCst) } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&mut AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_mut/successes/receiver_mix.rs000064400000000000000000000011761046102023000216050ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Mut))] pub trait Counter { fn increment(&mut self); fn decrement(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&mut self) { self.count.fetch_add(1, Ordering::SeqCst); } fn decrement(&self) { self.count.fetch_sub(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&mut AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_mut/successes/receiver_mut.rs000064400000000000000000000006571046102023000216200ustar 00000000000000extern crate blanket; extern crate impls; use blanket::blanket; use impls::impls; #[blanket(derive(Mut))] pub trait Counter { fn increment(&mut self); } #[derive(Default)] struct AtomicCounter { count: u8, } impl Counter for AtomicCounter { fn increment(&mut self) { self.count += 1; } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&mut AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_mut/successes/receiver_ref.rs000064400000000000000000000007671046102023000215710ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Mut))] pub trait Counter { fn increment(&self); } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&mut AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_mut/successes/trait_generics.rs000064400000000000000000000010661046102023000221240ustar 00000000000000extern crate blanket; extern crate impls; use blanket::blanket; use impls::impls; #[blanket(derive(Mut))] pub trait AsRef2 { fn as_ref2(&mut self) -> &mut T; } #[derive(Default)] struct Owner { owned: T, } impl AsRef2 for Owner { fn as_ref2(&mut self) -> &mut T { &mut self.owned } } fn main() { assert!(impls!(Owner: AsRef2)); assert!(impls!(&mut Owner: AsRef2)); assert!(impls!(Owner: AsRef2)); assert!(impls!(&mut Owner: AsRef2)); } blanket-0.3.0/tests/derive_mut/successes/where_clause_assoc_fn.rs000064400000000000000000000012071046102023000234400ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Mut))] pub trait Counter where T: Clone, { fn increment(&self, t: T); fn super_helpful_helper(&self, t: T) { self.increment(t.clone()) } } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self, value: u8) { self.count.fetch_add(value, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&mut AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_rc/fails/noderive.rs000064400000000000000000000010471046102023000176310ustar 00000000000000extern crate impls; extern crate static_assertions; use std::rc::Rc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use impls::impls; use static_assertions::const_assert; pub trait Counter { fn increment(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8 } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { const_assert!(impls!(AtomicCounter: Counter)); const_assert!(impls!(Rc: Counter)); } blanket-0.3.0/tests/derive_rc/fails/noderive.stderr000064400000000000000000000006331046102023000205100ustar 00000000000000error[E0080]: evaluation of constant value failed --> tests/derive_rc/fails/noderive.rs:28:5 | 28 | const_assert!(impls!(Rc: Counter)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow | = note: this error originates in the macro `const_assert` (in Nightly builds, run with -Z macro-backtrace for more info) blanket-0.3.0/tests/derive_rc/fails/receiver_box.rs000064400000000000000000000002141046102023000204650ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Rc))] pub trait Counter { fn increment(self: Box); } fn main() {} blanket-0.3.0/tests/derive_rc/fails/receiver_box.stderr000064400000000000000000000003261046102023000213500ustar 00000000000000error: cannot derive `Rc` for a trait declaring methods with arbitrary receiver types --> tests/derive_rc/fails/receiver_box.rs:7:18 | 7 | fn increment(self: Box); | ^^^^^^^^^^^^^^^ blanket-0.3.0/tests/derive_rc/fails/receiver_mut.rs000064400000000000000000000002061046102023000205030ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Rc))] pub trait Counter { fn increment(&mut self); } fn main() {} blanket-0.3.0/tests/derive_rc/fails/receiver_mut.stderr000064400000000000000000000002701046102023000213630ustar 00000000000000error: cannot derive `Rc` for a trait declaring `&mut self` methods --> tests/derive_rc/fails/receiver_mut.rs:7:18 | 7 | fn increment(&mut self); | ^^^^^^^^^ blanket-0.3.0/tests/derive_rc/fails/receiver_self.rs000064400000000000000000000001771046102023000206360ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Rc))] pub trait Extract { fn extract(self); } fn main() {} blanket-0.3.0/tests/derive_rc/fails/receiver_self.stderr000064400000000000000000000002251046102023000215070ustar 00000000000000error: cannot derive `Rc` for a trait declaring `self` methods --> $DIR/receiver_self.rs:7:16 | 7 | fn extract(self); | ^^^^ blanket-0.3.0/tests/derive_rc/mod.rs000064400000000000000000000003371046102023000155000ustar 00000000000000extern crate trybuild; fn main() { #[cfg(not(tarpaulin))] let t = trybuild::TestCases::new(); t.compile_fail(file!().replace("mod.rs", "fails/*.rs")); t.pass(file!().replace("mod.rs", "successes/*.rs")); } blanket-0.3.0/tests/derive_rc/successes/assoc_type.rs000064400000000000000000000012101046102023000210610ustar 00000000000000use std::rc::Rc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Rc))] pub trait Counter { type Return: Clone; // <- verify this fn increment(&self) -> Self::Return; } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { // Generate something like `type Return = ::Return;`. type Return = u8; fn increment(&self) -> u8 { self.count.fetch_add(1, Ordering::SeqCst) } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Rc: Counter)); } blanket-0.3.0/tests/derive_rc/successes/receiver_ref.rs000064400000000000000000000010301046102023000213500ustar 00000000000000extern crate blanket; extern crate impls; use std::rc::Rc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Rc))] pub trait Counter { fn increment(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Rc: Counter)); } blanket-0.3.0/tests/derive_rc/successes/trait_generics.rs000064400000000000000000000010571046102023000217230ustar 00000000000000extern crate blanket; extern crate impls; use std::rc::Rc; use blanket::blanket; use impls::impls; #[blanket(derive(Rc))] pub trait AsRef2 { fn as_ref2(&self) -> &T; } #[derive(Default)] struct Owner { owned: T, } impl AsRef2 for Owner { fn as_ref2(&self) -> &T { &self.owned } } fn main() { assert!(impls!(Owner: AsRef2)); assert!(impls!(Rc>: AsRef2)); assert!(impls!(Owner: AsRef2)); assert!(impls!(Rc>: AsRef2)); } blanket-0.3.0/tests/derive_rc/successes/where_clause_assoc_fn.rs000064400000000000000000000012251046102023000232370ustar 00000000000000extern crate blanket; extern crate impls; use std::rc::Rc; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Rc))] pub trait Counter where T: Clone, { fn increment(&self, t: T); fn super_helpful_helper(&self, t: T) { self.increment(t.clone()) } } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self, value: u8) { self.count.fetch_add(value, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(Rc: Counter)); } blanket-0.3.0/tests/derive_ref/fails/noderive.rs000064400000000000000000000010261046102023000177760ustar 00000000000000extern crate impls; extern crate static_assertions; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use impls::impls; use static_assertions::const_assert; pub trait Counter { fn increment(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8 } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { const_assert!(impls!(AtomicCounter: Counter)); const_assert!(impls!(&AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_ref/fails/noderive.stderr000064400000000000000000000006341046102023000206610ustar 00000000000000error[E0080]: evaluation of constant value failed --> tests/derive_ref/fails/noderive.rs:27:5 | 27 | const_assert!(impls!(&AtomicCounter: Counter)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow | = note: this error originates in the macro `const_assert` (in Nightly builds, run with -Z macro-backtrace for more info) blanket-0.3.0/tests/derive_ref/fails/receiver_box.rs000064400000000000000000000002151046102023000206360ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Ref))] pub trait Counter { fn increment(self: Box); } fn main() {} blanket-0.3.0/tests/derive_ref/fails/receiver_box.stderr000064400000000000000000000003301046102023000215130ustar 00000000000000error: cannot derive `Ref` for a trait declaring methods with arbitrary receiver types --> tests/derive_ref/fails/receiver_box.rs:7:18 | 7 | fn increment(self: Box); | ^^^^^^^^^^^^^^^ blanket-0.3.0/tests/derive_ref/fails/receiver_mut.rs000064400000000000000000000002071046102023000206540ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Ref))] pub trait Counter { fn increment(&mut self); } fn main() {} blanket-0.3.0/tests/derive_ref/fails/receiver_mut.stderr000064400000000000000000000002721046102023000215350ustar 00000000000000error: cannot derive `Ref` for a trait declaring `&mut self` methods --> tests/derive_ref/fails/receiver_mut.rs:7:18 | 7 | fn increment(&mut self); | ^^^^^^^^^ blanket-0.3.0/tests/derive_ref/fails/receiver_self.rs000064400000000000000000000002001046102023000207710ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(derive(Ref))] pub trait Extract { fn extract(self); } fn main() {} blanket-0.3.0/tests/derive_ref/fails/receiver_self.stderr000064400000000000000000000002261046102023000216600ustar 00000000000000error: cannot derive `Ref` for a trait declaring `self` methods --> $DIR/receiver_self.rs:7:16 | 7 | fn extract(self); | ^^^^ blanket-0.3.0/tests/derive_ref/mod.rs000064400000000000000000000003371046102023000156500ustar 00000000000000extern crate trybuild; fn main() { #[cfg(not(tarpaulin))] let t = trybuild::TestCases::new(); t.compile_fail(file!().replace("mod.rs", "fails/*.rs")); t.pass(file!().replace("mod.rs", "successes/*.rs")); } blanket-0.3.0/tests/derive_ref/successes/assoc_type.rs000064400000000000000000000011621046102023000212370ustar 00000000000000use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Ref))] pub trait Counter { type Return: Clone; // <- verify this fn increment(&self) -> Self::Return; } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { // Generate something like `type Return = ::Return;`. type Return = u8; fn increment(&self) -> u8 { self.count.fetch_add(1, Ordering::SeqCst) } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_ref/successes/receiver_ref.rs000064400000000000000000000010021046102023000215170ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Ref))] pub trait Counter { fn increment(&self); } #[derive(Default)] struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self) { self.count.fetch_add(1, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&AtomicCounter: Counter)); } blanket-0.3.0/tests/derive_ref/successes/trait_generics.rs000064400000000000000000000010221046102023000220630ustar 00000000000000extern crate blanket; extern crate impls; use blanket::blanket; use impls::impls; #[blanket(derive(Ref))] pub trait AsRef2 { fn as_ref2(&self) -> &T; } #[derive(Default)] struct Owner { owned: T, } impl AsRef2 for Owner { fn as_ref2(&self) -> &T { &self.owned } } fn main() { assert!(impls!(Owner: AsRef2)); assert!(impls!(&Owner: AsRef2)); assert!(impls!(Owner: AsRef2)); assert!(impls!(&Owner: AsRef2)); } blanket-0.3.0/tests/derive_ref/successes/where_clause_assoc_fn.rs000064400000000000000000000011771046102023000234150ustar 00000000000000extern crate blanket; extern crate impls; use std::sync::atomic::AtomicU8; use std::sync::atomic::Ordering; use blanket::blanket; use impls::impls; #[blanket(derive(Ref))] pub trait Counter where T: Clone, { fn increment(&self, t: T); fn super_helpful_helper(&self, t: T) { self.increment(t.clone()) } } struct AtomicCounter { count: AtomicU8, } impl Counter for AtomicCounter { fn increment(&self, value: u8) { self.count.fetch_add(value, Ordering::SeqCst); } } fn main() { assert!(impls!(AtomicCounter: Counter)); assert!(impls!(&AtomicCounter: Counter)); } blanket-0.3.0/tests/fails/default-with-default.rs000064400000000000000000000002101046102023000200620ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(default = "default")] pub trait MyTrait { fn method() {} } pub fn main() {} blanket-0.3.0/tests/fails/default-with-default.stderr000064400000000000000000000002711046102023000207500ustar 00000000000000error: method should not have default implementation if using #[blanket(default = "...")] --> tests/fails/default-with-default.rs:6:5 | 6 | fn method() {} | ^^^^^^^^^^^^^^ blanket-0.3.0/tests/fails/duplicate-default.rs000064400000000000000000000002071046102023000174450ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(default = "default", default = "other")] pub trait MyTrait {} pub fn main() {} blanket-0.3.0/tests/fails/duplicate-default.stderr000064400000000000000000000002411046102023000203220ustar 00000000000000error: unexpected token --> tests/fails/duplicate-default.rs:4:30 | 4 | #[blanket(default = "default", default = "other")] | ^ blanket-0.3.0/tests/fails/invalid-default-1.rs000064400000000000000000000001541046102023000172600ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(default = 1)] pub trait MyTrait {} pub fn main() {} blanket-0.3.0/tests/fails/invalid-default-1.stderr000064400000000000000000000001751046102023000201420ustar 00000000000000error: expected string literal --> $DIR/invalid-default-1.rs:4:21 | 4 | #[blanket(default = 1)] | ^ blanket-0.3.0/tests/fails/invalid-default-2.rs000064400000000000000000000001601046102023000172560ustar 00000000000000extern crate blanket; use blanket::blanket; #[blanket(default = "a b")] pub trait MyTrait {} pub fn main() {} blanket-0.3.0/tests/fails/invalid-default-2.stderr000064400000000000000000000002101046102023000201310ustar 00000000000000error: expected module identifier --> $DIR/invalid-default-2.rs:4:21 | 4 | #[blanket(default = "a b")] | ^^^^^ blanket-0.3.0/tests/fails.rs000064400000000000000000000002261046102023000140520ustar 00000000000000extern crate trybuild; #[test] #[cfg(not(tarpaulin))] fn fails() { let t = trybuild::TestCases::new(); t.compile_fail("tests/fails/*.rs"); }