iroha
iroha copied to clipboard
Static type checking of `EvaluatesTo` not working
I've noticed that our type checking of EvaluatesTo is not giving out compile errors when it is expected to do so.
The following test should not compile, yet it does:
#[test]
fn genesis_block_is_commited_with_some_offline_peers() {
// Given
let rt = Runtime::test();
let (network, mut iroha_client) = rt.block_on(<Network>::start_test_with_offline(4, 1, 1));
wait_for_genesis_committed(&network.clients(), 1);
//When
// NOTE: I have used `AssetDefinitionId` instead of `AccountId` for demonstration purpose
let alice_id: AssetDefinitionId = "alice#wonderland".parse().expect("Valid");
let alice_has_roses = 13;
//Then
let assets = iroha_client
// NOTE: This should not compile because `client::asset::by_account_id`
// should only accept expressions that evaluate to `AccountId`!
.request(client::asset::by_account_id(alice_id))
.expect("Failed to execute request.");
let asset = assets
.iter()
.find(|asset| asset.id().definition_id == "rose#wonderland".parse().expect("Valid"))
.unwrap();
assert_eq!(AssetValue::Quantity(alice_has_roses), *asset.value());
}
Notice that client::asset::by_account_id as it's argument accepts impl Into<EvaluatesTo<AccountId>>, yet when given AssetDefinitionId it still compiles as if there is an implementation AssetDefinitionId: Into<AccountId>.
@appetrosyan, @mversic if we look at:
impl<V: TryFrom<Value>, E: Into<ExpressionBox>> From<E> for EvaluatesTo<V> {
fn from(expression: E) -> Self {
Self {
expression: expression.into(),
_value_type: PhantomData::default(),
}
}
}
Nothing prevent us from having:
impl From<AssetDefinitionId> for EvaluatesTo<AccountId> {
fn from(expression: AssetDefinitionId) -> Self {
Self {
// AssetDefinitionId into ExpressionBox
expression: expression.into(),
_value_type: PhantomData::default(),
}
}
}
impl From<AccountId> for EvaluatesTo<AccountId> {
fn from(expression: AccountId) -> Self {
Self {
// AccountId into ExpressionBox
expression: expression.into(),
_value_type: PhantomData::default(),
}
}
}
EDIT: so the problem is that when we require type value: impl Into<EvaluatesTo<V>, we really only require value: impl Into<ExpressionBox>.