Bug 1836420 - Upgrade extend to 1.2.0. r=emilio,supply-chain-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D179757
This commit is contained in:
Mike Hommey 2023-06-05 22:49:52 +00:00
parent 8ba840c3b8
commit 1991d34ad4
11 changed files with 183 additions and 141 deletions

7
Cargo.lock generated
View File

@ -1525,14 +1525,13 @@ dependencies = [
[[package]]
name = "extend"
version = "1.1.2"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5216e387a76eebaaf11f6d871ec8a4aae0b25f05456ee21f228e024b1b3610"
checksum = "311a6d2f1f9d60bff73d2c78a0af97ed27f79672f15c238192a5bbb64db56d00"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.107",
"syn 2.0.18",
]
[[package]]

View File

@ -1154,6 +1154,11 @@ criteria = "safe-to-deploy"
version = "1.1.2"
notes = "Inspected the crate and noted that the impl block comes directly from the proc-macro input. If no new code can be added by this crate, I don't think there can be any issues."
[[audits.extend]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.1.2 -> 1.2.0"
[[audits.fallible_collections]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"

View File

@ -1 +1 @@
{"files":{"CHANGELOG.md":"910cd2057d356b18cd4f21791bc23956734a83b0f58701ec0d0d03405f5c21df","Cargo.toml":"928b8b97607b3589b85a6d4d00fb1cf64b78bee6354c303d8f49fbfa2ca5bdae","LICENSE":"db0efd0bb80126f32214f478434536d07d86a30658fb209d8b543b7261492a2b","README.md":"0872b2b15ec22732a09b121a31cdd8f8cfc80566f671566e4a7fb6b52a742a2e","deny.toml":"60448e9313f1883a7adf30713fcca789c454e77228105926024ce3abe9293100","rustfmt.toml":"9bbb759b3914c49c8060bcdeeb7786f4aec083d30bcfe236bbd48d8388d06103","src/lib.rs":"85bd23c064c78dcd141cb2fecca6fff2ee7e1dfb4cf19b74ab97ef30d51f6f03","tests/compile_fail/double_vis.rs":"524e8bc996f5a45de3d15f0c741d4f3414004e9c636c52de0f011785cc535109","tests/compile_fail/double_vis.stderr":"3748e67e6f41bd5624946ad7cdc4e2b30a9d0b5e76bc27c19ecc9d62da733978","tests/compile_fail/supertraits_are_actually_included.rs":"c03980316c4e71ceb7e80ab7011f00b6f1f8f89906670e9823267a4118f72853","tests/compile_fail/supertraits_are_actually_included.stderr":"835e79bb1bceb48e9db5f0a410c57af51c856e17917ef72f65e3ae2af79d97ec","tests/compile_pass/associated_constants.rs":"f3e56405650ddd31c33e932846553e88fe7181585e0f09a7414d50d521b0f103","tests/compile_pass/async_trait.rs":"9138801d67dbe20ed87fdb3f48bb968f0bfa11fe2d27414d5ea5ea7a6e44bb35","tests/compile_pass/changing_extension_trait_name.rs":"046e7a66151ce05c3515b4bea36be72f83b98f3bdb06fa6f065ad6fc373e19f2","tests/compile_pass/complex_trait_name.rs":"5a8c3588c26df07973739fbb85619d0de480cc8c992611dfc2dbcb9ab3c6e2b6","tests/compile_pass/double_ext_on_same_type.rs":"0e4d16fe9059f0325e4ad1337d53738876633b0533f9a2d4e9714ddada96eb4d","tests/compile_pass/extension_on_complex_types.rs":"88bdf979e1f399d7f9824165730b33884bc9c46347d246f8cc12e0e2039642a1","tests/compile_pass/generics.rs":"367f089e8010d1c98ccc975b03acb6cf03810793e1198105f75c006eafd52bb8","tests/compile_pass/hello_world.rs":"1961cfa634143974f0d64b26f817ac3148375faa5cf5864d63f0127d3af8099e","tests/compile_pass/issue_2.rs":"a14d5e2179b74ff71c5357e8a4f1a9ac228a711196edd40c12719565c8dfaa21","tests/compile_pass/more_than_one_extension.rs":"1d7486e4e9e4095d7e7f42aac878d836f021c49fbe26c31cb13fe6a0415a8558","tests/compile_pass/multiple_config.rs":"dc3b06e4fafbb7236b5bc49f9a5e9693241c07118da8886dd0752b895ff27425","tests/compile_pass/multiple_generic_params.rs":"2ac052ea7b818b6d45ee8070cf6ec18953419473f711375cafbe7283244b5743","tests/compile_pass/pub_impl.rs":"8dfcba21fbbc45efcf85b66fca2d187022569e72d4b10b57047eddda67a1725b","tests/compile_pass/ref_and_ref_mut.rs":"d1086a23809cbd8f87487677073238c3657a8a98fafc63a688eb9d622bf2eb11","tests/compile_pass/sized.rs":"baceaaabcf368b3c72e6d27fea72aadde11d97d9d153c35df5e2d89fb3da4e3e","tests/compile_pass/super_trait.rs":"07448e1fe2b9018125ccaabf7db1e2a244788519bb42117f8e437e48358eb2f0","tests/compile_pass/visibility_config.rs":"64846014a63327661fb250cdb726cce532ed82b1cea5cb83308526bcba22b4be"},"package":"5c5216e387a76eebaaf11f6d871ec8a4aae0b25f05456ee21f228e024b1b3610"}
{"files":{"CHANGELOG.md":"7f91119554e4587936d7e431dae1b7b77c677230809615ad81e931477e7b7013","Cargo.toml":"fa01cfc6e053fa0072da1ad9e413a147a4f2cfee53a529de57a7c44ce858ad13","LICENSE":"db0efd0bb80126f32214f478434536d07d86a30658fb209d8b543b7261492a2b","README.md":"0872b2b15ec22732a09b121a31cdd8f8cfc80566f671566e4a7fb6b52a742a2e","deny.toml":"5896a0134be617fcfbde7680ae65f0d8bbb14e7250588f27d8bff347f7bd59d3","src/lib.rs":"6128d331b2ee8fb6261548387b691c633b515a3d6dec1533cac69035676c11ef","tests/compile_fail/double_vis.rs":"524e8bc996f5a45de3d15f0c741d4f3414004e9c636c52de0f011785cc535109","tests/compile_fail/double_vis.stderr":"3748e67e6f41bd5624946ad7cdc4e2b30a9d0b5e76bc27c19ecc9d62da733978","tests/compile_fail/supertraits_are_actually_included.rs":"c03980316c4e71ceb7e80ab7011f00b6f1f8f89906670e9823267a4118f72853","tests/compile_fail/supertraits_are_actually_included.stderr":"d88d744cd810a58b3f7a4495ecb020604ddc1badfb765a7b13bd38ba1ba0f243","tests/compile_pass/associated_constants.rs":"f3e56405650ddd31c33e932846553e88fe7181585e0f09a7414d50d521b0f103","tests/compile_pass/async_trait.rs":"9138801d67dbe20ed87fdb3f48bb968f0bfa11fe2d27414d5ea5ea7a6e44bb35","tests/compile_pass/changing_extension_trait_name.rs":"046e7a66151ce05c3515b4bea36be72f83b98f3bdb06fa6f065ad6fc373e19f2","tests/compile_pass/complex_trait_name.rs":"5a8c3588c26df07973739fbb85619d0de480cc8c992611dfc2dbcb9ab3c6e2b6","tests/compile_pass/destructure.rs":"274b1c97ecce02fd3412a4da3f194e48dc1339a7714ebf3748b0d9ff16ce93be","tests/compile_pass/double_ext_on_same_type.rs":"0e4d16fe9059f0325e4ad1337d53738876633b0533f9a2d4e9714ddada96eb4d","tests/compile_pass/extension_on_complex_types.rs":"8dd484df9e6a4c8a20b9f14b8d33aeecb8fce6a9e1be2e68b8dc7f312e860562","tests/compile_pass/generics.rs":"367f089e8010d1c98ccc975b03acb6cf03810793e1198105f75c006eafd52bb8","tests/compile_pass/hello_world.rs":"1961cfa634143974f0d64b26f817ac3148375faa5cf5864d63f0127d3af8099e","tests/compile_pass/issue_2.rs":"a14d5e2179b74ff71c5357e8a4f1a9ac228a711196edd40c12719565c8dfaa21","tests/compile_pass/more_than_one_extension.rs":"1d7486e4e9e4095d7e7f42aac878d836f021c49fbe26c31cb13fe6a0415a8558","tests/compile_pass/multiple_config.rs":"dc3b06e4fafbb7236b5bc49f9a5e9693241c07118da8886dd0752b895ff27425","tests/compile_pass/multiple_generic_params.rs":"2ac052ea7b818b6d45ee8070cf6ec18953419473f711375cafbe7283244b5743","tests/compile_pass/pub_impl.rs":"8dfcba21fbbc45efcf85b66fca2d187022569e72d4b10b57047eddda67a1725b","tests/compile_pass/ref_and_ref_mut.rs":"d1086a23809cbd8f87487677073238c3657a8a98fafc63a688eb9d622bf2eb11","tests/compile_pass/sized.rs":"baceaaabcf368b3c72e6d27fea72aadde11d97d9d153c35df5e2d89fb3da4e3e","tests/compile_pass/super_trait.rs":"07448e1fe2b9018125ccaabf7db1e2a244788519bb42117f8e437e48358eb2f0","tests/compile_pass/visibility_config.rs":"64846014a63327661fb250cdb726cce532ed82b1cea5cb83308526bcba22b4be"},"package":"311a6d2f1f9d60bff73d2c78a0af97ed27f79672f15c238192a5bbb64db56d00"}

View File

@ -6,11 +6,19 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
## Unreleased
None.
- None.
### Breaking changes
None.
- None.
## 1.2.0 - 2023-03-18
- Support destructuring function arguments
## 1.1.3 - 2023-03-18
- Update to syn 2.0
## 1.1.2 - 2021-09-02

View File

@ -3,32 +3,30 @@
# 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
# to registry (e.g., crates.io) dependencies.
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
# 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 = "extend"
version = "1.1.2"
version = "1.2.0"
authors = ["David Pedersen <david.pdrsn@gmail.com>"]
description = "Create extensions for types you don't own with extension traits but without the boilerplate."
homepage = "https://github.com/davidpdrsn/extend"
documentation = "https://docs.rs/extend"
readme = "README.md"
keywords = ["extension", "trait"]
keywords = [
"extension",
"trait",
]
categories = ["rust-patterns"]
license = "MIT"
repository = "https://github.com/davidpdrsn/extend.git"
repository = "https://github.com/davidpdrsn/extend"
[lib]
path = "src/lib.rs"
proc-macro = true
[dependencies.proc-macro-error]
version = "1"
[dependencies.proc-macro2]
version = "1"
@ -37,12 +35,15 @@ version = "1"
version = "1"
[dependencies.syn]
version = "1"
features = ["full", "extra-traits", "visit"]
version = "2"
features = [
"full",
"extra-traits",
"visit",
]
[dev-dependencies.async-trait]
version = "0.1.40"
[dev-dependencies.trybuild]
version = "1.0.17"
[badges.maintenance]
status = "passively-maintained"

View File

@ -1,47 +1,23 @@
targets = []
[advisories]
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
vulnerability = "deny"
unmaintained = "warn"
yanked = "warn"
notice = "warn"
ignore = []
[licenses]
unlicensed = "deny"
allow = [
"MIT",
"Apache-2.0",
]
unlicensed = "warn"
allow = []
deny = []
copyleft = "warn"
allow-osi-fsf-free = "neither"
default = "deny"
allow-osi-fsf-free = "either"
confidence-threshold = 0.8
exceptions = []
[licenses.private]
ignore = false
registries = []
[bans]
multiple-versions = "deny"
wildcards = "allow"
highlight = "all"
allow = []
deny = []
skip = []
skip-tree = []
[sources]
unknown-registry = "warn"
unknown-git = "warn"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
[sources.allow-org]
github = []
gitlab = []
bitbucket = []

View File

@ -1 +0,0 @@
merge_imports = true

View File

@ -13,12 +13,10 @@
//! }
//! }
//!
//! fn main() {
//! assert_eq!(
//! vec![1, 2, 3],
//! vec![2, 3, 1].sorted(),
//! );
//! }
//! assert_eq!(
//! vec![1, 2, 3],
//! vec![2, 3, 1].sorted(),
//! );
//! ```
//!
//! # How does it work?
@ -150,28 +148,21 @@
//!
//! [extension traits]: https://dev.to/matsimitsu/extending-existing-functionality-in-rust-with-traits-in-rust-3622
#![doc(html_root_url = "https://docs.rs/extend/1.1.2")]
#![allow(clippy::let_and_return)]
#![deny(
unused_variables,
mutable_borrow_reservation_conflict,
dead_code,
unused_must_use,
unused_imports
)]
#![deny(unused_variables, dead_code, unused_must_use, unused_imports)]
use proc_macro2::TokenStream;
use proc_macro_error::*;
use quote::{format_ident, quote, ToTokens};
use std::convert::{TryFrom, TryInto};
use syn::{
parse::{self, Parse, ParseStream},
parse_macro_input, parse_quote,
punctuated::Punctuated,
spanned::Spanned,
token::{Add, Semi},
Ident, ImplItem, ItemImpl, Token, TraitItemConst, TraitItemMethod, Type, TypeArray, TypeBareFn,
TypeGroup, TypeNever, TypeParamBound, TypeParen, TypePath, TypePtr, TypeReference, TypeSlice,
TypeTraitObject, TypeTuple, Visibility,
token::{Plus, Semi},
Ident, ImplItem, ItemImpl, Result, Token, TraitItemConst, TraitItemFn, Type, TypeArray,
TypeBareFn, TypeGroup, TypeNever, TypeParamBound, TypeParen, TypePath, TypePtr, TypeReference,
TypeSlice, TypeTraitObject, TypeTuple, Visibility,
};
#[derive(Debug)]
@ -201,7 +192,6 @@ impl Parse for Input {
/// See crate docs for more info.
#[proc_macro_attribute]
#[proc_macro_error]
#[allow(clippy::unneeded_field_pattern)]
pub fn ext(
attr: proc_macro::TokenStream,
@ -209,7 +199,10 @@ pub fn ext(
) -> proc_macro::TokenStream {
let item = parse_macro_input!(item as Input);
let config = parse_macro_input!(attr as Config);
go(item, config)
match go(item, config) {
Ok(tokens) => tokens,
Err(err) => err.into_compile_error().into(),
}
}
/// Like [`ext`](macro@crate::ext) but always add `Sized` as a supertrait.
@ -228,7 +221,6 @@ pub fn ext(
/// }
/// ```
#[proc_macro_attribute]
#[proc_macro_error]
#[allow(clippy::unneeded_field_pattern)]
pub fn ext_sized(
attr: proc_macro::TokenStream,
@ -243,16 +235,19 @@ pub fn ext_sized(
Some(parse_quote!(Sized))
};
go(item, config)
match go(item, config) {
Ok(tokens) => tokens,
Err(err) => err.into_compile_error().into(),
}
}
fn go(item: Input, mut config: Config) -> proc_macro::TokenStream {
fn go(item: Input, mut config: Config) -> Result<proc_macro::TokenStream> {
if let Some(vis) = item.vis {
if config.visibility != Visibility::Inherited {
abort!(
return Err(syn::Error::new(
config.visibility.span(),
"Cannot set visibility on `#[ext]` and `impl` block"
);
"Cannot set visibility on `#[ext]` and `impl` block",
));
}
config.visibility = vis;
@ -272,19 +267,24 @@ fn go(item: Input, mut config: Config) -> proc_macro::TokenStream {
} = item.item_impl;
if let Some((_, path, _)) = trait_ {
abort!(path.span(), "Trait impls cannot be used for #[ext]");
return Err(syn::Error::new(
path.span(),
"Trait impls cannot be used for #[ext]",
));
}
let self_ty = parse_self_ty(&self_ty);
let self_ty = parse_self_ty(&self_ty)?;
let ext_trait_name = config
.ext_trait_name
.unwrap_or_else(|| ext_trait_name(&self_ty));
let ext_trait_name = if let Some(ext_trait_name) = config.ext_trait_name {
ext_trait_name
} else {
ext_trait_name(&self_ty)?
};
let MethodsAndConsts {
trait_methods,
trait_consts,
} = extract_allowed_items(&items);
} = extract_allowed_items(&items)?;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
@ -299,7 +299,7 @@ fn go(item: Input, mut config: Config) -> proc_macro::TokenStream {
let supertraits_quoted = if all_supertraits.is_empty() {
quote! {}
} else {
let supertraits_quoted = punctuated_from_iter::<_, _, Add>(all_supertraits);
let supertraits_quoted = punctuated_from_iter::<_, _, Plus>(all_supertraits);
quote! { : #supertraits_quoted }
};
@ -330,7 +330,7 @@ fn go(item: Input, mut config: Config) -> proc_macro::TokenStream {
})
.into();
code
Ok(code)
}
#[derive(Debug, Clone)]
@ -349,8 +349,8 @@ enum ExtType<'a> {
}
#[allow(clippy::wildcard_in_or_patterns)]
fn parse_self_ty(self_ty: &Type) -> ExtType {
match self_ty {
fn parse_self_ty(self_ty: &Type) -> Result<ExtType> {
let ty = match self_ty {
Type::Array(inner) => ExtType::Array(inner),
Type::Group(inner) => ExtType::Group(inner),
Type::Never(inner) => ExtType::Never(inner),
@ -363,15 +363,20 @@ fn parse_self_ty(self_ty: &Type) -> ExtType {
Type::BareFn(inner) => ExtType::BareFn(inner),
Type::TraitObject(inner) => ExtType::TraitObject(inner),
Type::ImplTrait(_) | Type::Infer(_) | Type::Macro(_) | Type::Verbatim(_) | _ => abort!(
self_ty.span(),
"#[ext] is not supported for this kind of type"
),
}
Type::ImplTrait(_) | Type::Infer(_) | Type::Macro(_) | Type::Verbatim(_) | _ => {
return Err(syn::Error::new(
self_ty.span(),
"#[ext] is not supported for this kind of type",
))
}
};
Ok(ty)
}
impl<'a> From<&'a Type> for ExtType<'a> {
fn from(inner: &'a Type) -> ExtType<'a> {
impl<'a> TryFrom<&'a Type> for ExtType<'a> {
type Error = syn::Error;
fn try_from(inner: &'a Type) -> Result<ExtType<'a>> {
parse_self_ty(inner)
}
}
@ -394,60 +399,60 @@ impl<'a> ToTokens for ExtType<'a> {
}
}
fn ext_trait_name(self_ty: &ExtType) -> Ident {
fn inner_self_ty(self_ty: &ExtType) -> Ident {
fn ext_trait_name(self_ty: &ExtType) -> Result<Ident> {
fn inner_self_ty(self_ty: &ExtType) -> Result<Ident> {
match self_ty {
ExtType::Path(inner) => find_and_combine_idents(inner),
ExtType::Reference(inner) => {
let name = inner_self_ty(&(&*inner.elem).into());
let name = inner_self_ty(&(&*inner.elem).try_into()?)?;
if inner.mutability.is_some() {
format_ident!("RefMut{}", name)
Ok(format_ident!("RefMut{}", name))
} else {
format_ident!("Ref{}", name)
Ok(format_ident!("Ref{}", name))
}
}
ExtType::Array(inner) => {
let name = inner_self_ty(&(&*inner.elem).into());
format_ident!("ListOf{}", name)
let name = inner_self_ty(&(&*inner.elem).try_into()?)?;
Ok(format_ident!("ListOf{}", name))
}
ExtType::Group(inner) => {
let name = inner_self_ty(&(&*inner.elem).into());
format_ident!("Group{}", name)
let name = inner_self_ty(&(&*inner.elem).try_into()?)?;
Ok(format_ident!("Group{}", name))
}
ExtType::Paren(inner) => {
let name = inner_self_ty(&(&*inner.elem).into());
format_ident!("Paren{}", name)
let name = inner_self_ty(&(&*inner.elem).try_into()?)?;
Ok(format_ident!("Paren{}", name))
}
ExtType::Ptr(inner) => {
let name = inner_self_ty(&(&*inner.elem).into());
format_ident!("PointerTo{}", name)
let name = inner_self_ty(&(&*inner.elem).try_into()?)?;
Ok(format_ident!("PointerTo{}", name))
}
ExtType::Slice(inner) => {
let name = inner_self_ty(&(&*inner.elem).into());
format_ident!("SliceOf{}", name)
let name = inner_self_ty(&(&*inner.elem).try_into()?)?;
Ok(format_ident!("SliceOf{}", name))
}
ExtType::Tuple(inner) => {
let mut name = format_ident!("TupleOf");
for elem in &inner.elems {
name = format_ident!("{}{}", name, inner_self_ty(&elem.into()));
name = format_ident!("{}{}", name, inner_self_ty(&elem.try_into()?)?);
}
name
Ok(name)
}
ExtType::Never(_) => format_ident!("Never"),
ExtType::Never(_) => Ok(format_ident!("Never")),
ExtType::BareFn(inner) => {
let mut name = format_ident!("BareFn");
for input in inner.inputs.iter() {
name = format_ident!("{}{}", name, inner_self_ty(&(&input.ty).into()));
name = format_ident!("{}{}", name, inner_self_ty(&(&input.ty).try_into()?)?);
}
match &inner.output {
syn::ReturnType::Default => {
name = format_ident!("{}Unit", name);
}
syn::ReturnType::Type(_, ty) => {
name = format_ident!("{}{}", name, inner_self_ty(&(&**ty).into()));
name = format_ident!("{}{}", name, inner_self_ty(&(&**ty).try_into()?)?);
}
}
name
Ok(name)
}
ExtType::TraitObject(inner) => {
let mut name = format_ident!("TraitObject");
@ -461,17 +466,20 @@ fn ext_trait_name(self_ty: &ExtType) -> Ident {
TypeParamBound::Lifetime(lifetime) => {
name = format_ident!("{}{}", name, lifetime.ident);
}
other => {
return Err(syn::Error::new(other.span(), "unsupported bound"));
}
}
}
name
Ok(name)
}
}
}
format_ident!("{}Ext", inner_self_ty(self_ty))
Ok(format_ident!("{}Ext", inner_self_ty(self_ty)?))
}
fn find_and_combine_idents(type_path: &TypePath) -> Ident {
fn find_and_combine_idents(type_path: &TypePath) -> Result<Ident> {
use syn::visit::{self, Visit};
struct IdentVisitor<'a>(Vec<&'a Ident>);
@ -487,7 +495,7 @@ fn find_and_combine_idents(type_path: &TypePath) -> Ident {
let idents = visitor.0;
if idents.is_empty() {
abort!(type_path.span(), "Empty type path")
Err(syn::Error::new(type_path.span(), "Empty type path"))
} else {
let start = &idents[0].span();
let combined_span = idents
@ -497,29 +505,49 @@ fn find_and_combine_idents(type_path: &TypePath) -> Ident {
let combined_name = idents.iter().map(|i| i.to_string()).collect::<String>();
Ident::new(&combined_name, combined_span)
Ok(Ident::new(&combined_name, combined_span))
}
}
#[derive(Debug, Default)]
struct MethodsAndConsts {
trait_methods: Vec<TraitItemMethod>,
trait_methods: Vec<TraitItemFn>,
trait_consts: Vec<TraitItemConst>,
}
#[allow(clippy::wildcard_in_or_patterns)]
fn extract_allowed_items(items: &[ImplItem]) -> MethodsAndConsts {
fn extract_allowed_items(items: &[ImplItem]) -> Result<MethodsAndConsts> {
let mut acc = MethodsAndConsts::default();
for item in items {
match item {
ImplItem::Method(method) => acc.trait_methods.push(TraitItemMethod {
ImplItem::Fn(method) => acc.trait_methods.push(TraitItemFn {
attrs: method.attrs.clone(),
sig: method.sig.clone(),
sig: {
let mut sig = method.sig.clone();
sig.inputs = sig
.inputs
.into_iter()
.map(|fn_arg| match fn_arg {
syn::FnArg::Receiver(recv) => syn::FnArg::Receiver(recv),
syn::FnArg::Typed(mut pat_type) => {
pat_type.pat = Box::new(match *pat_type.pat {
syn::Pat::Ident(pat_ident) => syn::Pat::Ident(pat_ident),
_ => {
parse_quote!(_)
}
});
syn::FnArg::Typed(pat_type)
}
})
.collect();
sig
},
default: None,
semi_token: Some(Semi::default()),
}),
ImplItem::Const(const_) => acc.trait_consts.push(TraitItemConst {
attrs: const_.attrs.clone(),
generics: const_.generics.clone(),
const_token: Default::default(),
ident: const_.ident.clone(),
colon_token: Default::default(),
@ -527,22 +555,31 @@ fn extract_allowed_items(items: &[ImplItem]) -> MethodsAndConsts {
default: None,
semi_token: Default::default(),
}),
ImplItem::Type(_) => abort!(
item.span(),
"Associated types are not allowed in #[ext] impls"
),
ImplItem::Macro(_) => abort!(item.span(), "Macros are not allowed in #[ext] impls"),
ImplItem::Verbatim(_) | _ => abort!(item.span(), "Not allowed in #[ext] impls"),
ImplItem::Type(_) => {
return Err(syn::Error::new(
item.span(),
"Associated types are not allowed in #[ext] impls",
))
}
ImplItem::Macro(_) => {
return Err(syn::Error::new(
item.span(),
"Macros are not allowed in #[ext] impls",
))
}
ImplItem::Verbatim(_) | _ => {
return Err(syn::Error::new(item.span(), "Not allowed in #[ext] impls"))
}
}
}
acc
Ok(acc)
}
#[derive(Debug)]
struct Config {
ext_trait_name: Option<Ident>,
visibility: Visibility,
supertraits: Option<Punctuated<TypeParamBound, Add>>,
supertraits: Option<Punctuated<TypeParamBound, Plus>>,
}
impl Parse for Config {
@ -565,9 +602,9 @@ impl Parse for Config {
}
"supertraits" => {
config.supertraits =
Some(Punctuated::<TypeParamBound, Add>::parse_terminated(input)?);
Some(Punctuated::<TypeParamBound, Plus>::parse_terminated(input)?);
}
_ => abort!(ident.span(), "Unknown configuration name"),
_ => return Err(syn::Error::new(ident.span(), "Unknown configuration name")),
}
input.parse::<Token![,]>().ok();

View File

@ -1,10 +1,13 @@
error[E0277]: the trait bound `String: MyTrait` is not satisfied
--> $DIR/supertraits_are_actually_included.rs:6:6
--> tests/compile_fail/supertraits_are_actually_included.rs:6:6
|
6 | impl String {
| ^^^^^^ the trait `MyTrait` is not implemented for `String`
|
note: required by a bound in `StringExt`
--> tests/compile_fail/supertraits_are_actually_included.rs:5:21
|
5 | #[ext(supertraits = MyTrait)]
| ------- required by this bound in `StringExt`
| ^^^^^^^ required by this bound in `StringExt`
6 | impl String {
| ^^^^^^
| |
| the trait `MyTrait` is not implemented for `String`
| required by a bound in this
| ------ required by a bound in this

View File

@ -0,0 +1,12 @@
#![allow(warnings)]
use extend::ext;
#[ext]
impl i32 {
fn foo(self, (a, b): (i32, i32)) {}
fn bar(self, [a, b]: [i32; 2]) {}
}
fn main() {}

View File

@ -1,3 +1,5 @@
#![allow(warnings)]
use extend::ext;
#[ext]