1 //! [![github]](https://github.com/dtolnay/inherent) [![crates-io]](https://crates.io/crates/inherent) [![docs-rs]](https://docs.rs/inherent)
2 //!
3 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
6 //!
7 //! <br>
8 //!
9 //! ##### An attribute macro to make trait methods callable without the trait in scope.
10 //!
11 //! # Example
12 //!
13 //! ```rust
14 //! mod types {
15 //!     use inherent::inherent;
16 //!
17 //!     trait Trait {
18 //!         fn f(self);
19 //!     }
20 //!
21 //!     pub struct Struct;
22 //!
23 //!     #[inherent(pub)]
24 //!     impl Trait for Struct {
25 //!         fn f(self) {}
26 //!     }
27 //! }
28 //!
29 //! fn main() {
30 //!     // types::Trait is not in scope, but method can be called.
31 //!     types::Struct.f();
32 //! }
33 //! ```
34 //!
35 //! Without the `inherent` macro on the trait impl, this would have failed with the
36 //! following error:
37 //!
38 //! ```console
39 //! error[E0599]: no method named `f` found for type `types::Struct` in the current scope
40 //!   --> src/main.rs:18:19
41 //!    |
42 //! 8  |     pub struct Struct;
43 //!    |     ------------------ method `f` not found for this
44 //! ...
45 //! 18 |     types::Struct.f();
46 //!    |                   ^
47 //!    |
48 //!    = help: items from traits can only be used if the trait is implemented and in scope
49 //!    = note: the following trait defines an item `f`, perhaps you need to implement it:
50 //!            candidate #1: `types::Trait`
51 //! ```
52 //!
53 //! The `inherent` macro expands to inherent methods on the `Self` type of the trait
54 //! impl that forward to the trait methods. In the case above, the generated code
55 //! would be:
56 //!
57 //! ```rust
58 //! # trait Trait {
59 //! #     fn f(self);
60 //! # }
61 //! #
62 //! # pub struct Struct;
63 //! #
64 //! # impl Trait for Struct {
65 //! #     fn f(self) {}
66 //! # }
67 //! #
68 //! impl Struct {
69 //!     pub fn f(self) {
70 //!         <Self as Trait>::f(self)
71 //!     }
72 //! }
73 //! ```
74 //!
75 //! # Visibility
76 //!
77 //! Ordinary trait methods have the same visibility as the trait or the `Self` type,
78 //! whichever's is smaller. Neither of these visibilities is knowable to the
79 //! `inherent` macro, so we simply emit all inherent methods as private by default.
80 //! A different visibility may be specified explicitly in the `inherent` macro
81 //! invocation.
82 //!
83 //! ```rust
84 //! # use inherent::inherent;
85 //! #
86 //! # trait Trait {}
87 //! #
88 //! # struct A;
89 //! #[inherent]  // private inherent methods are the default
90 //! # impl Trait for A {}
91 //!
92 //! # struct B;
93 //! #[inherent(pub)]  // all methods pub
94 //! # impl Trait for B {}
95 //!
96 //! # struct C;
97 //! #[inherent(crate)]  // all methods pub(crate)
98 //! # impl Trait for C {}
99 //!
100 //! # struct D;
101 //! #[inherent(in path::to)]  // all methods pub(in path::to)
102 //! # impl Trait for D {}
103 //! ```
104 
105 extern crate proc_macro;
106 
107 mod default_methods;
108 mod expand;
109 mod parse;
110 mod visibility;
111 
112 use proc_macro::TokenStream;
113 use syn::parse_macro_input;
114 
115 use crate::parse::TraitImpl;
116 use crate::visibility::Visibility;
117 
118 #[proc_macro_attribute]
inherent(args: TokenStream, input: TokenStream) -> TokenStream119 pub fn inherent(args: TokenStream, input: TokenStream) -> TokenStream {
120     let vis = parse_macro_input!(args as Visibility);
121     let input = parse_macro_input!(input as TraitImpl);
122     expand::inherent(vis, input).into()
123 }
124