What version are you using?
main with feature expiremental_spec_shaking_v2
What did you do?
Used a Rust type alias in a contract function signature. This applies if the aliased type is a primitive like i128 or a custom type like in the example below.
Minimal example:
#![no_std]
use soroban_sdk::{contract, contractimpl, contracttype};
#[contracttype]
#[derive(Clone)]
pub struct Item {
pub amount: i128,
}
pub type ItemAlias = Item;
#[contract]
pub struct Contract;
#[contractimpl]
impl Contract {
pub fn echo(item: ItemAlias) -> ItemAlias {
item
}
}
Under spec shaking v2, generated boundary code roots reachable types by calling the marker method for the function parameter and return types, conceptually:
<ItemAlias as SpecShakingMarker>::spec_shaking_marker();
But ItemAlias is only a Rust type alias. Rust trait lookup normalizes it to the aliased type, so this call resolves as if it were:
<Item as SpecShakingMarker>::spec_shaking_marker();
That means the surviving marker is the marker for the Item spec entry.
At the same time, the contract spec macro builds the public function spec from the source syntax. It sees the token ItemAlias in the function signature and emits a function spec that references UDT name ItemAlias.
This creates two different views of the same signature:
contractspecv0 function entry says the function uses UDT ItemAlias.
T::spec_shaking_marker() roots the spec entry for UDT Item.
What did you expect to see?
Either of these would be acceptable:
- The SDK rejects source-level type aliases in contract-facing signatures with a clear compile-time error.
- The SDK resolves the alias consistently, so both the public function spec and the spec-shaking marker refer to the same UDT,
Item.
In either case, spec shaking should not produce a final spec where a function references a UDT name that has no corresponding UDT spec entry.
What did you see instead?
For the example above, the marker machinery keeps Item, but the public function spec can still reference ItemAlias. After shaking, this can produce an invalid or unusable contract spec: generated import/client code expects a type named ItemAlias, but the actual UDT spec entry is named Item.
What version are you using?
main with feature
expiremental_spec_shaking_v2What did you do?
Used a Rust type alias in a contract function signature. This applies if the aliased type is a primitive like
i128or a custom type like in the example below.Minimal example:
Under spec shaking v2, generated boundary code roots reachable types by calling the marker method for the function parameter and return types, conceptually:
But
ItemAliasis only a Rust type alias. Rust trait lookup normalizes it to the aliased type, so this call resolves as if it were:That means the surviving marker is the marker for the
Itemspec entry.At the same time, the contract spec macro builds the public function spec from the source syntax. It sees the token
ItemAliasin the function signature and emits a function spec that references UDT nameItemAlias.This creates two different views of the same signature:
contractspecv0function entry says the function uses UDTItemAlias.T::spec_shaking_marker()roots the spec entry for UDTItem.What did you expect to see?
Either of these would be acceptable:
Item.In either case, spec shaking should not produce a final spec where a function references a UDT name that has no corresponding UDT spec entry.
What did you see instead?
For the example above, the marker machinery keeps
Item, but the public function spec can still referenceItemAlias. After shaking, this can produce an invalid or unusable contract spec: generated import/client code expects a type namedItemAlias, but the actual UDT spec entry is namedItem.