diff options
-rw-r--r-- | src/lib.rs | 8 | ||||
-rw-r--r-- | src/parse_trait_sig.rs | 1 | ||||
-rw-r--r-- | src/transform.rs | 22 | ||||
-rw-r--r-- | tests/doctests.md | 38 |
4 files changed, 63 insertions, 6 deletions
@@ -110,9 +110,11 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream { MethodParseError::AssocTypeInUnsupportedReturnType | MethodParseError::UnconvertibleAssocTypeInFnInput, )) => return abort!(span, "dynamize does not know how to convert this type"), - Err((span, MethodParseError::UnconvertibleAssocTypeInTraitBound)) => { - return abort!(span, "dynamize does not support associated types here") - } + Err(( + span, + MethodParseError::UnconvertibleAssocTypeInTraitBound + | MethodParseError::UnconvertibleAssocTypeInWhereClause, + )) => return abort!(span, "dynamize does not support associated types here"), Err((span, MethodParseError::ImplTraitInInputs)) => { return abort!( span, diff --git a/src/parse_trait_sig.rs b/src/parse_trait_sig.rs index 508e131..82b8ee9 100644 --- a/src/parse_trait_sig.rs +++ b/src/parse_trait_sig.rs @@ -28,6 +28,7 @@ pub enum MethodParseError { AssocTypeInUnsupportedReturnType, UnconvertibleAssocTypeInFnInput, UnconvertibleAssocTypeInTraitBound, + UnconvertibleAssocTypeInWhereClause, UnconvertibleAssocType, } diff --git a/src/transform.rs b/src/transform.rs index 676cfd8..b13b7cf 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -141,11 +141,27 @@ pub fn dynamize_function_bounds( } } - // TODO: return error if predicate_type.bounded_ty contains associated type + // just to provide better error messages + if let Some(assoc_type) = + iter_type(&predicate_type.bounded_ty).find_map(filter_map_assoc_paths) + { + return Err(( + assoc_type.span(), + MethodParseError::UnconvertibleAssocTypeInWhereClause, + )); + } + // just to provide better error messages for bound in &mut predicate_type.bounds { - if let TypeParamBound::Trait(_bound) = bound { - // TODO: return error if bound.path contains associated type + if let TypeParamBound::Trait(bound) = bound { + if let Some(assoc_type) = + iter_path(&bound.path).find_map(filter_map_assoc_paths) + { + return Err(( + assoc_type.span(), + MethodParseError::UnconvertibleAssocTypeInWhereClause, + )); + } } } } diff --git a/tests/doctests.md b/tests/doctests.md index 3318dba..8fa8306 100644 --- a/tests/doctests.md +++ b/tests/doctests.md @@ -54,3 +54,41 @@ trait Trait { fn b<A: std::fmt::Display>(&self, a: A) -> Self::A; } ``` + +## Where clause must not contain associated types in complex predicates + +Works: + +```rust +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into<String>; + + fn a<G>(&self, a: G) where G: Fn(Self::A); +} +``` + +Fails: + +```rust compile_fail +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into<String>; + + fn a<G>(&self, a: G) where G: Into<Self::A>; +} +``` + +Fails: + +```rust compile_fail +struct MyType<A>(A); +trait SomeTrait {} + +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into<String>; + + fn a<G>(&self, a: G) where MyType<Self::A>: SomeTrait; +} +``` |