Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
rust-version: ['stable', 'beta', 'nightly', '1.56']
rust-version: ['stable', 'beta', 'nightly', '1.71']
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ categories = ["development-tools", "rust-patterns"]
readme = "README.md"
autotests = true
edition = "2021"
rust-version = "1.56"
rust-version = "1.71"

[workspace]
members = [
Expand All @@ -27,7 +27,7 @@ proc-macro = true
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", features = ["full", "visit", "visit-mut"] }
syn = { version = "3.0", features = ["full", "visit", "visit-mut"] }

[dev-dependencies]
trybuild = "1"
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ some common smart pointers and closures.

# Usage

This library requires Rust 1.56.0 or newer. This library doesn't leave any public API in your code.
This library requires Rust 1.71.0 or newer. This library doesn't leave any public API in your code.

Add `auto_impl` to your `Cargo.toml` and just use it in your crate:

Expand Down Expand Up @@ -36,13 +36,13 @@ requires_foo(&0i32); // works: through the generated impl
requires_foo(Box::new(0i32)); // works: through the generated impl
```

For more explanations, please see [**the documentation**](https://docs.rs/auto_impl) and for more examples, see
For more explanations, please see [**the documentation**](https://docs.rs/auto_impl) and for more examples, see
[the examples folder](https://github.com/auto-impl-rs/auto_impl/tree/master/examples).

# Alternatives

This library implements a fraction of a very broad and complex usecase. It's mostly useful for applications that
define traits for components, and want to be able to abstract over the storage for those traits. If it doesn't offer
This library implements a fraction of a very broad and complex usecase. It's mostly useful for applications that
define traits for components, and want to be able to abstract over the storage for those traits. If it doesn't offer
some functionality you need, check out the [`impl-tools`](https://github.com/kas-gui/impl-tools/) project.

---
Expand Down
46 changes: 25 additions & 21 deletions src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use proc_macro2::{Span as Span2, TokenStream as TokenStream2, TokenTree as Token
use quote::{ToTokens, TokenStreamExt};
use syn::{
punctuated::Punctuated, spanned::Spanned, Attribute, Error, FnArg, GenericParam, Ident,
ItemTrait, Lifetime, Pat, PatIdent, PatType, ReturnType, Signature, Token, TraitBound,
TraitBoundModifier, TraitItem, TraitItemConst, TraitItemFn, TraitItemType, Type,
ItemTrait, Lifetime, Pat, PatIdent, PatType, Receiver, ReceiverKind, ReturnType, Safety,
Signature, Token, TraitBound, TraitItem, TraitItemConst, TraitItemFn, TraitItemType, Type,
TypeParamBound, WherePredicate,
};

Expand Down Expand Up @@ -114,10 +114,8 @@ fn gen_header(
// Check if the bound contains `Sized`
pred.bounds.iter().any(|b| match b {
TypeParamBound::Trait(TraitBound {
modifier: TraitBoundModifier::None,
path,
..
}) => path.is_ident("Sized"),
modifiers, path, ..
}) if modifiers.require_empty().is_ok() => path.is_ident("Sized"),
_ => false,
})
}
Expand All @@ -127,10 +125,13 @@ fn gen_header(

// Check if the first parameter is `self` by value. In that
// case, we might require `Self` to be `Sized`.
let self_value_param = match m.sig.inputs.first() {
Some(FnArg::Receiver(receiver)) => receiver.reference.is_none(),
_ => false,
};
let self_value_param = matches!(
m.sig.inputs.first(),
Some(FnArg::Receiver(Receiver {
kind: ReceiverKind::Value,
..
}))
);

// Check if return type is `Self`
let self_value_return = match &m.sig.output {
Expand Down Expand Up @@ -357,7 +358,7 @@ fn gen_fn_type_for_trait(
));
}

if let Some(unsafe_token) = &sig.unsafety {
if let Safety::Unsafe(unsafe_token) = &sig.safety {
return Err(Error::new(
unsafe_token.span(),
format_args!(
Expand Down Expand Up @@ -662,7 +663,7 @@ fn gen_method_item(
let sig = Signature {
constness: item.sig.constness,
asyncness: item.sig.asyncness,
unsafety: item.sig.unsafety,
safety: item.sig.safety.clone(),
abi: item.sig.abi.clone(),
fn_token: item.sig.fn_token,
ident: item.sig.ident.clone(),
Expand Down Expand Up @@ -763,15 +764,18 @@ enum SelfType {
impl SelfType {
fn from_sig(sig: &Signature) -> Self {
match sig.inputs.iter().next() {
Some(FnArg::Receiver(r)) => {
if r.reference.is_none() {
SelfType::Value
} else if r.mutability.is_none() {
SelfType::Ref
} else {
SelfType::Mut
}
}
Some(FnArg::Receiver(Receiver {
kind: ReceiverKind::Value,
..
})) => SelfType::Value,
Some(FnArg::Receiver(Receiver {
kind: ReceiverKind::Reference(_, _, None),
..
})) => SelfType::Ref,
Some(FnArg::Receiver(Receiver {
kind: ReceiverKind::Reference(_, _, Some(_)),
..
})) => SelfType::Mut,
_ => SelfType::None,
}
}
Expand Down
Loading