inherent/
lib.rs

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&logo=docs.rs
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]
24//!     impl Trait for Struct {
25//!         pub 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#![doc(html_root_url = "https://docs.rs/inherent/1.0.13")]
76#![allow(
77    clippy::default_trait_access,
78    clippy::module_name_repetitions,
79    clippy::needless_doctest_main,
80    clippy::needless_pass_by_value,
81    clippy::uninlined_format_args
82)]
83
84extern crate proc_macro;
85
86mod expand;
87mod parse;
88mod verbatim;
89
90use proc_macro::TokenStream;
91use syn::parse::Nothing;
92use syn::parse_macro_input;
93
94use crate::parse::TraitImpl;
95
96#[proc_macro_attribute]
97pub fn inherent(args: TokenStream, input: TokenStream) -> TokenStream {
98    parse_macro_input!(args as Nothing);
99    let input = parse_macro_input!(input as TraitImpl);
100    expand::inherent(input).into()
101}