aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-26 10:27:50 +0100
committerMartin Fischer <martin@push-f.com>2021-11-26 11:45:53 +0100
commitd37cf6a72e633afb10ec78bdbeec6631d601adfe (patch)
tree1db3a4b735382c65c0feed07a3328cdd059c4bd5 /src
parent7489a3c2246e7ea2483446dd2ed3fdbfaf462c1a (diff)
return error for unused #[convert]s
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs10
-rw-r--r--src/trait_sig.rs35
-rw-r--r--src/transform.rs16
3 files changed, 39 insertions, 22 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 785827a..73ae723 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -97,6 +97,7 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream {
assoc_type_conversions: HashMap::new(),
collections: method_attrs.collections,
type_conversions: method_attrs.type_conversions,
+ used_conversions: Default::default(),
};
for item in &original_trait.items {
@@ -127,7 +128,7 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream {
if let TraitItem::Method(method) = item {
let mut signature = method.sig.clone();
- match convert_trait_signature(&mut signature, &type_converter) {
+ match convert_trait_signature(&mut signature, &mut type_converter) {
Ok(parsed_method) => objectifiable_methods.push((signature, parsed_method)),
Err((span, err)) => match err {
MethodError::NonDispatchableMethod => continue,
@@ -181,6 +182,13 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream {
}
}
+ for ty in type_converter.type_conversions.keys() {
+ if !type_converter.used_conversions.contains(ty) {
+ // FUTURE: relax to warning once proc_macro::Diagnostic is stable
+ return abort!(ty.span(), "unused conversion");
+ }
+ }
+
let mut method_impls: Vec<ImplItemMethod> = Vec::new();
let mut dyn_trait = ItemTrait {
diff --git a/src/trait_sig.rs b/src/trait_sig.rs
index a1be44f..ce6f318 100644
--- a/src/trait_sig.rs
+++ b/src/trait_sig.rs
@@ -57,7 +57,7 @@ pub struct SignatureChanges {
pub fn convert_trait_signature(
signature: &mut Signature,
- type_converter: &TypeConverter,
+ type_converter: &mut TypeConverter,
) -> Result<SignatureChanges, (Span, MethodError)> {
if is_non_dispatchable(signature) {
return Err((signature.span(), MethodError::NonDispatchableMethod));
@@ -144,7 +144,7 @@ fn bounds_self_and_has_bound_sized(predicate: &WherePredicate) -> bool {
#[cfg(test)]
mod tests {
- use std::collections::HashMap;
+ use std::collections::{HashMap, HashSet};
use quote::{format_ident, quote};
use syn::{TraitItemMethod, Type};
@@ -161,6 +161,7 @@ mod tests {
collections: HashMap::new(),
trait_ident: format_ident!("test"),
type_conversions: HashMap::new(),
+ used_conversions: HashSet::new(),
}
}
@@ -172,7 +173,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Ok(SignatureChanges {
return_type: TypeTransform::NoOp,
..
@@ -194,7 +195,7 @@ mod tests {
type_converter.assoc_type_conversions.insert(ident, dest);
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &type_converter),
+ convert_trait_signature(&mut type1.sig, &mut type_converter),
Ok(SignatureChanges {
return_type: TypeTransform::Into,
..
@@ -210,7 +211,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((
_,
MethodError::Transform(TransformError::AssocTypeWithoutDestType)
@@ -226,7 +227,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::NonDispatchableMethod))
));
}
@@ -239,7 +240,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::NonDispatchableMethod))
));
}
@@ -252,7 +253,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::NonDispatchableMethod))
));
}
@@ -265,7 +266,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::NonDispatchableMethod))
));
}
@@ -278,7 +279,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::Transform(TransformError::UnsupportedType)))
));
}
@@ -291,7 +292,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::Transform(TransformError::UnsupportedType)))
));
}
@@ -304,7 +305,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::Transform(TransformError::UnsupportedType)))
));
}
@@ -317,7 +318,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::Transform(TransformError::UnsupportedType)))
));
}
@@ -330,7 +331,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::AssocTypeInInputs))
));
}
@@ -343,7 +344,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::AssocTypeInInputs))
));
}
@@ -356,7 +357,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::ImplTraitInInputs))
));
}
@@ -369,7 +370,7 @@ mod tests {
.unwrap();
assert!(matches!(
- convert_trait_signature(&mut type1.sig, &test_converter()),
+ convert_trait_signature(&mut type1.sig, &mut test_converter()),
Err((_, MethodError::Transform(TransformError::UnsupportedType)))
));
}
diff --git a/src/transform.rs b/src/transform.rs
index ae345c8..c56bec1 100644
--- a/src/transform.rs
+++ b/src/transform.rs
@@ -1,4 +1,7 @@
-use std::{collections::HashMap, rc::Rc};
+use std::{
+ collections::{HashMap, HashSet},
+ rc::Rc,
+};
use proc_macro2::Span;
use quote::quote;
@@ -20,6 +23,7 @@ pub struct TypeConverter {
pub collections: HashMap<Ident, usize>,
pub trait_ident: Ident,
pub type_conversions: HashMap<Type, Rc<Convert>>,
+ pub used_conversions: HashSet<Type>,
}
#[derive(Debug)]
@@ -60,8 +64,12 @@ impl TypeConverter {
None
}
- pub fn convert_type(&self, type_: &mut Type) -> Result<TypeTransform, (Span, TransformError)> {
+ pub fn convert_type(
+ &mut self,
+ type_: &mut Type,
+ ) -> Result<TypeTransform, (Span, TransformError)> {
if let Some(conv) = self.type_conversions.get(type_) {
+ self.used_conversions.insert(conv.original_type.clone());
*type_ = conv.dest_type.clone();
return Ok(TypeTransform::Verbatim(conv.clone()));
}
@@ -223,7 +231,7 @@ impl TypeConverter {
pub fn dynamize_function_bounds(
generics: &mut Generics,
- type_converter: &TypeConverter,
+ type_converter: &mut TypeConverter,
) -> Result<HashMap<Ident, Vec<TypeTransform>>, (Span, MethodError)> {
let mut type_param_transforms = HashMap::new();
@@ -285,7 +293,7 @@ pub fn dynamize_function_bounds(
fn dynamize_trait_bound(
bound: &mut TraitBound,
- type_converter: &TypeConverter,
+ type_converter: &mut TypeConverter,
type_ident: &Ident,
type_param_transforms: &mut HashMap<Ident, Vec<TypeTransform>>,
) -> Result<(), (Span, MethodError)> {