From 34dc166a9bc003bad36c28aeb29b625195d20a74 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sun, 21 Nov 2021 08:33:52 +0100 Subject: better errors for assoc types in where clauses --- src/lib.rs | 8 +++++--- src/parse_trait_sig.rs | 1 + src/transform.rs | 22 +++++++++++++++++++--- tests/doctests.md | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 17cea6d..439288e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(&self, a: A) -> Self::A; } ``` + +## Where clause must not contain associated types in complex predicates + +Works: + +```rust +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into; + + fn a(&self, a: G) where G: Fn(Self::A); +} +``` + +Fails: + +```rust compile_fail +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into; + + fn a(&self, a: G) where G: Into; +} +``` + +Fails: + +```rust compile_fail +struct MyType(A); +trait SomeTrait {} + +#[dynamize::dynamize] +trait TraitWithCallback { + type A: Into; + + fn a(&self, a: G) where MyType: SomeTrait; +} +``` -- cgit v1.2.3