Repository: CosmWasm/sylvia
Pull request #323 (2024-03-11 08:44:44)

feat: Handle missing explicite custom types

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/CosmWasm/sylvia/pull/323?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm) Report
Attention: Patch coverage is `55.55556%` with `8 lines` in your changes are missing coverage. Please review.
> Project coverage is 85.27%. Comparing base [(`a9f7128`)](https://app.codecov.io/gh/CosmWasm/sylvia/commit/a9f71281865efe1e41b74f95f9eb0469a199c468?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm) to head [(`1a8dfd7`)](https://app.codecov.io/gh/CosmWasm/sylvia/pull/323?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm).

| [Files](https://app.codecov.io/gh/CosmWasm/sylvia/pull/323?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm) | Patch % | Lines |
|---|---|---|
| [sylvia-derive/src/input.rs](https://app.codecov.io/gh/CosmWasm/sylvia/pull/323?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm#diff-c3lsdmlhLWRlcml2ZS9zcmMvaW5wdXQucnM=) | 50.00% | [8 Missing :warning: ](https://app.codecov.io/gh/CosmWasm/sylvia/pull/323?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm) |

<details><summary>Additional details and impacted files</summary>


```diff
@@                      Coverage Diff                       @@
##           feat/bound_querier_improve     #323      +/-   ##
==============================================================
- Coverage                       85.45%   85.27%   -0.19%     
==============================================================
  Files                              37       37              
  Lines                            2695     2709      +14     
==============================================================
+ Hits                             2303     2310       +7     
- Misses                            392      399       +7     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/CosmWasm/sylvia/pull/323?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm).

kulikthebird: There's a problem with coverage, since we do not have a proper errors/warnings testing setup at the moment. To be fixed by https://github.com/CosmWasm/sylvia/issues/98

Patch:
diff --git a/examples/interfaces/cw1/src/lib.rs b/examples/interfaces/cw1/src/lib.rs
index a32c94f..0aedc60 100644
--- a/examples/interfaces/cw1/src/lib.rs
+++ b/examples/interfaces/cw1/src/lib.rs
@@ -11,6 +11,7 @@ pub struct CanExecuteResp {
 }
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Cw1 {
     type Error: From<StdError>;
 
diff --git a/examples/interfaces/cw20-allowances/src/lib.rs b/examples/interfaces/cw20-allowances/src/lib.rs
index 287c327..35ed061 100644
--- a/examples/interfaces/cw20-allowances/src/lib.rs
+++ b/examples/interfaces/cw20-allowances/src/lib.rs
@@ -9,6 +9,7 @@ use sylvia::types::{ExecCtx, QueryCtx};
 use sylvia::{interface, schemars};
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Cw20Allowances {
     type Error: From<StdError>;
 
diff --git a/examples/interfaces/cw20-marketing/src/lib.rs b/examples/interfaces/cw20-marketing/src/lib.rs
index 3d4675f..31b6383 100644
--- a/examples/interfaces/cw20-marketing/src/lib.rs
+++ b/examples/interfaces/cw20-marketing/src/lib.rs
@@ -29,6 +29,7 @@ pub enum EmbeddedLogo {
 }
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Cw20Marketing {
     type Error: From<StdError>;
 
diff --git a/examples/interfaces/cw20-minting/src/lib.rs b/examples/interfaces/cw20-minting/src/lib.rs
index 4f4bb6f..f2627fb 100644
--- a/examples/interfaces/cw20-minting/src/lib.rs
+++ b/examples/interfaces/cw20-minting/src/lib.rs
@@ -6,6 +6,7 @@ use sylvia::types::{ExecCtx, QueryCtx};
 use sylvia::{interface, schemars};
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Cw20Minting {
     type Error: From<StdError>;
 
diff --git a/examples/interfaces/cw4/src/lib.rs b/examples/interfaces/cw4/src/lib.rs
index ab188c4..1c75eca 100644
--- a/examples/interfaces/cw4/src/lib.rs
+++ b/examples/interfaces/cw4/src/lib.rs
@@ -4,6 +4,7 @@ use sylvia::types::{ExecCtx, QueryCtx};
 use sylvia::{interface, schemars};
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Cw4 {
     type Error: From<StdError>;
 
diff --git a/examples/interfaces/generic/src/lib.rs b/examples/interfaces/generic/src/lib.rs
index 9624672..b3d59c6 100644
--- a/examples/interfaces/generic/src/lib.rs
+++ b/examples/interfaces/generic/src/lib.rs
@@ -4,6 +4,7 @@ use sylvia::types::{CustomMsg, ExecCtx, QueryCtx, SudoCtx};
 use sylvia::{interface, schemars};
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Generic {
     type Error: From<StdError>;
     type Exec1T: CustomMsg;
diff --git a/examples/interfaces/whitelist/src/lib.rs b/examples/interfaces/whitelist/src/lib.rs
index 7fe9b62..a14fc3f 100644
--- a/examples/interfaces/whitelist/src/lib.rs
+++ b/examples/interfaces/whitelist/src/lib.rs
@@ -6,6 +6,7 @@ use sylvia::{interface, schemars};
 pub mod responses;
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Whitelist {
     type Error: From<cosmwasm_std::StdError>;
 
diff --git a/sylvia-derive/src/input.rs b/sylvia-derive/src/input.rs
index 8f66eb7..4e100e8 100644
--- a/sylvia-derive/src/input.rs
+++ b/sylvia-derive/src/input.rs
@@ -1,9 +1,9 @@
 use proc_macro2::TokenStream;
-use proc_macro_error::emit_error;
+use proc_macro_error::{emit_error, emit_warning};
 use quote::quote;
 use syn::{GenericParam, Ident, ItemImpl, ItemTrait, TraitItem};
 
-use crate::associated_types::{AssociatedTypes, ItemType};
+use crate::associated_types::{AssociatedTypes, ItemType, EXEC_TYPE, QUERY_TYPE};
 use crate::interfaces::Interfaces;
 use crate::message::{
     ContractApi, ContractEnumMessage, EnumMessage, GlueMessage, InterfaceApi, MsgVariants,
@@ -48,6 +48,30 @@ impl<'a> TraitInput<'a> {
             .unwrap_or_default();
         let associated_types = AssociatedTypes::new(item);
 
+        if custom.msg.is_none()
+            && !associated_types
+                .all_names()
+                .any(|assoc_type| assoc_type == EXEC_TYPE)
+        {
+            emit_warning!(
+                item.ident.span(), "Missing both `{}` type and `#[sv::custom(msg=...)]` defined for the trait.", EXEC_TYPE;
+                note = "Implicitly it means that the trait could not be implemented for contracts that use CustomMsg different than `cosmwasm_std::Empty`";
+                note = "If this behaviour is intended, please add `#[sv::custom(msg=sylvia::cw_std::Empty]` attribute.";
+            );
+        }
+
+        if custom.query.is_none()
+            && !associated_types
+                .all_names()
+                .any(|assoc_type| assoc_type == QUERY_TYPE)
+        {
+            emit_warning!(
+                item.ident.span(), "Missing both `{}` type and `#[sv::custom(query=...)]` defined for the trait.", QUERY_TYPE;
+                note = "Implicitly it means that the trait could not be implemented for contracts that use CustomQuery different than `cosmwasm_std::Empty`";
+                note = "If this behaviour is intended, please add `#[sv::custom(query=sylvia::cw_std::Empty]` attribute.";
+            );
+        }
+
         Self {
             item,
             custom,
diff --git a/sylvia-derive/src/message.rs b/sylvia-derive/src/message.rs
index e06a4f9..b8703df 100644
--- a/sylvia-derive/src/message.rs
+++ b/sylvia-derive/src/message.rs
@@ -198,12 +198,14 @@ impl<'a> EnumMessage<'a> {
         let associated_query = parse_associated_custom_type(source, QUERY_TYPE);
 
         let resp_type = custom
-            .msg()
+            .msg
+            .clone()
             .or(associated_exec)
             .unwrap_or_else(Custom::default_type);
 
         let query_type = custom
-            .query()
+            .query
+            .clone()
             .or(associated_query)
             .unwrap_or_else(Custom::default_type);
 
diff --git a/sylvia-derive/src/parser/attributes/custom.rs b/sylvia-derive/src/parser/attributes/custom.rs
index 647d228..dd93f9f 100644
--- a/sylvia-derive/src/parser/attributes/custom.rs
+++ b/sylvia-derive/src/parser/attributes/custom.rs
@@ -7,8 +7,8 @@ use crate::crate_module;
 
 #[derive(Debug, Default)]
 pub struct Custom {
-    msg: Option<Type>,
-    query: Option<Type>,
+    pub msg: Option<Type>,
+    pub query: Option<Type>,
 }
 
 impl Custom {
@@ -30,14 +30,6 @@ impl Custom {
         self.query.clone().unwrap_or_else(Self::default_type)
     }
 
-    pub fn msg(&self) -> Option<Type> {
-        self.msg.clone()
-    }
-
-    pub fn query(&self) -> Option<Type> {
-        self.query.clone()
-    }
-
     pub fn default_type() -> Type {
         let sylvia = crate_module();
         parse_quote! { #sylvia ::cw_std::Empty }
diff --git a/sylvia/examples/basic.rs b/sylvia/examples/basic.rs
index 6014fe9..4b7aee1 100644
--- a/sylvia/examples/basic.rs
+++ b/sylvia/examples/basic.rs
@@ -39,6 +39,7 @@ mod group {
     use crate::{Member, MemberResp};
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait Group {
         type Error: From<StdError>;
 


Test patch:
diff --git a/examples/contracts/cw20-base/src/multitest/receiver.rs b/examples/contracts/cw20-base/src/multitest/receiver.rs
index 2729a22..2d67d44 100644
--- a/examples/contracts/cw20-base/src/multitest/receiver.rs
+++ b/examples/contracts/cw20-base/src/multitest/receiver.rs
@@ -3,6 +3,7 @@ use sylvia::types::ExecCtx;
 use sylvia::{interface, schemars};
 
 #[interface]
+#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
 pub trait Receiver {
     type Error: From<StdError>;
 
diff --git a/sylvia/tests/custom_msg.rs b/sylvia/tests/custom_msg.rs
index 7acc2d0..d3a454a 100644
--- a/sylvia/tests/custom_msg.rs
+++ b/sylvia/tests/custom_msg.rs
@@ -27,7 +27,7 @@ mod some_interface {
     use crate::{MyMsg, SomeResponse};
 
     #[interface]
-    #[sv::custom(msg=MyMsg)]
+    #[sv::custom(msg=MyMsg, query=cosmwasm_std::Empty)]
     pub trait SomeInterface {
         type Error: From<StdError>;
 
@@ -74,7 +74,7 @@ mod interface {
     use sylvia::types::{ExecCtx, QueryCtx, SudoCtx};
 
     #[interface]
-    #[sv::custom(msg=MyMsg)]
+    #[sv::custom(msg=MyMsg, query=cosmwasm_std::Empty)]
     pub trait Interface {
         type Error: From<StdError>;
         type ExecC: CustomMsg;
@@ -119,6 +119,7 @@ mod other_interface {
     use sylvia::types::{ExecCtx, QueryCtx, SudoCtx};
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait OtherInterface {
         type Error: From<StdError>;
 
@@ -161,6 +162,7 @@ mod associated_interface {
     use sylvia::types::{ExecCtx, QueryCtx, SudoCtx};
 
     #[interface]
+    #[sv::custom(query=cosmwasm_std::Empty)]
     pub trait AssociatedInterface {
         type Error: From<StdError>;
         type ExecC: CustomMsg;
diff --git a/sylvia/tests/custom_query.rs b/sylvia/tests/custom_query.rs
index 5fa6d65..c8459a6 100644
--- a/sylvia/tests/custom_query.rs
+++ b/sylvia/tests/custom_query.rs
@@ -26,7 +26,7 @@ mod interface {
     use crate::{MyQuery, SomeResponse};
 
     #[interface]
-    #[sv::custom(query=MyQuery)]
+    #[sv::custom(query=MyQuery, msg=cosmwasm_std::Empty)]
     pub trait Interface {
         type Error: From<StdError>;
         type QueryC: CustomQuery;
@@ -74,7 +74,7 @@ mod some_interface {
     use crate::{MyQuery, SomeResponse};
 
     #[interface]
-    #[sv::custom(query=MyQuery)]
+    #[sv::custom(query=MyQuery, msg=cosmwasm_std::Empty)]
     pub trait SomeInterface {
         type Error: From<StdError>;
 
@@ -120,6 +120,7 @@ mod associated_type_interface {
     use crate::SomeResponse;
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty)]
     pub trait AssociatedTypeInterface {
         type Error: From<StdError>;
         type QueryC: CustomQuery;
@@ -167,6 +168,7 @@ mod default_query_interface {
     use crate::SomeResponse;
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait DefaultQueryInterface {
         type Error: From<StdError>;
 
diff --git a/sylvia/tests/dispatching.rs b/sylvia/tests/dispatching.rs
index 594ca89..3254e32 100644
--- a/sylvia/tests/dispatching.rs
+++ b/sylvia/tests/dispatching.rs
@@ -24,6 +24,7 @@ mod interface {
     use crate::{EmptyQueryResponse, QueryResponse};
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait Interface {
         type Error: From<StdError>;
 
diff --git a/sylvia/tests/messages_generation.rs b/sylvia/tests/messages_generation.rs
index d76b485..7f29ae0 100644
--- a/sylvia/tests/messages_generation.rs
+++ b/sylvia/tests/messages_generation.rs
@@ -20,6 +20,7 @@ mod interface {
     use crate::QueryResult;
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait Interface {
         type Error: From<StdError>;
 
diff --git a/sylvia/tests/querier.rs b/sylvia/tests/querier.rs
index 3440a68..83c2688 100644
--- a/sylvia/tests/querier.rs
+++ b/sylvia/tests/querier.rs
@@ -20,6 +20,7 @@ pub mod counter {
     use crate::CountResponse;
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait Counter {
         type Error: From<StdError>;
 
diff --git a/sylvia/tests/query_returns.rs b/sylvia/tests/query_returns.rs
index 614c095..ddd1508 100644
--- a/sylvia/tests/query_returns.rs
+++ b/sylvia/tests/query_returns.rs
@@ -25,6 +25,7 @@ mod msg {
     use crate::{QueryResponse, QueryResult};
 
     #[interface(module=msg)]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait Interface {
         type Error: From<StdError>;
 
diff --git a/sylvia/tests/remote.rs b/sylvia/tests/remote.rs
index 025ecc2..054d300 100644
--- a/sylvia/tests/remote.rs
+++ b/sylvia/tests/remote.rs
@@ -10,6 +10,7 @@ pub mod some_interface {
     use sylvia::interface;
 
     #[interface]
+    #[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
     pub trait SomeInterface {
         type Error: From<StdError>;
     }