Skip to content

Commit ce53c6e

Browse files
authored
Merge pull request argotorg#1501 from sbillig/univ3
Replace sol-compat int trait impl boilerplate with blanket impls
2 parents 81e94b9 + 77baa7c commit ce53c6e

26 files changed

Lines changed: 1674 additions & 1546 deletions

crates/codegen/tests/fixtures/sonatina_ir/effect_ptr_domains.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ func private %bump__gb2d8(v0.objref<@layout_0>) {
9292
return;
9393
}
9494

95-
func private %impl_trait_StorPtr__from_raw__gb2d8(v0.i256) -> i256 {
95+
func private %impl_trait_MemPtr__from_raw__gb2d8(v0.i256) -> i256 {
9696
block0:
9797
jump block1;
9898

9999
block1:
100100
return v0;
101101
}
102102

103-
func private %impl_trait_MemPtr__from_raw__gb2d8(v0.i256) -> i256 {
103+
func private %impl_trait_StorPtr__from_raw__gb2d8(v0.i256) -> i256 {
104104
block0:
105105
jump block1;
106106

crates/codegen/tests/fixtures/sonatina_ir/erc20_low_level.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ func private %std__lib__evm__effects__impl_trait_Address_3ffb__eq_fb60(v0.@layou
201201
return v7;
202202
}
203203

204-
func private %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_b944(v0.i256) -> i256 {
204+
func private %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_866d(v0.i256) -> i256 {
205205
block0:
206206
jump block1;
207207

208208
block1:
209209
return v0;
210210
}
211211

212-
func private %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_b944_0(v0.i256) -> i256 {
212+
func private %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_866d_0(v0.i256) -> i256 {
213213
block0:
214214
jump block1;
215215

@@ -790,7 +790,7 @@ func private %std__lib__evm__effects__trait_RawStorage__stor_ptr__g3730_6bd4(v0.
790790
jump block1;
791791

792792
block1:
793-
v2.i256 = call %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_b944 v0;
793+
v2.i256 = call %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_866d v0;
794794
return v2;
795795
}
796796

@@ -799,7 +799,7 @@ func private %std__lib__evm__effects__trait_RawStorage__stor_ptr__g3730_6bd4_0(v
799799
jump block1;
800800

801801
block1:
802-
v2.i256 = call %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_b944_0 v0;
802+
v2.i256 = call %core__lib__effect_ref__impl_trait_StorPtr_27da__from_raw__gb51e_866d_0 v0;
803803
return v2;
804804
}
805805

crates/codegen/tests/fixtures/sonatina_ir/explicit_raw_boundaries.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ func private %explicit_raw_boundaries() {
3636
return;
3737
}
3838

39-
func private %from_raw__ge513(v0.i256) -> i256 {
39+
func private %from_raw__g4a95(v0.i256) -> i256 {
4040
block0:
4141
jump block1;
4242

4343
block1:
4444
return v0;
4545
}
4646

47-
func private %from_raw__g4a95(v0.i256) -> i256 {
47+
func private %from_raw__ge513(v0.i256) -> i256 {
4848
block0:
4949
jump block1;
5050

@@ -97,15 +97,15 @@ func private %std__lib__evm__effects__impl_trait_Evm_d0d8__mstore_c9f4_0(v0.i256
9797
return;
9898
}
9999

100-
func private %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_0a9d(v0.i256) -> i256 {
100+
func private %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_c621(v0.i256) -> i256 {
101101
block0:
102102
jump block1;
103103

104104
block1:
105105
return v0;
106106
}
107107

108-
func private %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_0a9d_0(v0.i256) -> i256 {
108+
func private %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_c621_0(v0.i256) -> i256 {
109109
block0:
110110
jump block1;
111111

@@ -118,7 +118,7 @@ func private %raw_store__gc18b(v0.i256) {
118118
jump block1;
119119

120120
block1:
121-
v2.i256 = call %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_0a9d_0 v0;
121+
v2.i256 = call %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_c621_0 v0;
122122
call %std__lib__evm__effects__impl_trait_Evm_d0d8__mstore_c9f4_0 v2 8.i256;
123123
return;
124124
}
@@ -128,7 +128,7 @@ func private %raw_store__g64c6(v0.i256) {
128128
jump block1;
129129

130130
block1:
131-
v2.i256 = call %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_0a9d v0;
131+
v2.i256 = call %core__lib__effect_ref__impl_trait_MemPtr_ec03__raw__g4a95_c621 v0;
132132
call %std__lib__evm__effects__impl_trait_Evm_d0d8__mstore_c9f4 v2 8.i256;
133133
return;
134134
}

crates/codegen/tests/fixtures/sonatina_ir/storage.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,15 @@ func private %credit_bob(v0.i256, v1.i256, v2.i256) -> i256 {
118118
return v25;
119119
}
120120

121-
func private %from_raw__g9438(v0.i256) -> i256 {
121+
func private %from_raw__gf198(v0.i256) -> i256 {
122122
block0:
123123
jump block1;
124124

125125
block1:
126126
return v0;
127127
}
128128

129-
func private %from_raw__gf198(v0.i256) -> i256 {
129+
func private %from_raw__g9438(v0.i256) -> i256 {
130130
block0:
131131
jump block1;
132132

crates/codegen/tests/fixtures/sonatina_ir/wrapping_saturating.snap

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,21 @@ func private %impl_trait_u64__saturating_add(v0.i64, v1.i64) -> i64 {
5252
return v4;
5353
}
5454

55-
func private %impl_trait_u256__saturating_mul(v0.i256, v1.i256) -> i256 {
55+
func private %impl_trait_u64__saturating_mul(v0.i64, v1.i64) -> i64 {
5656
block0:
5757
jump block1;
5858

5959
block1:
60-
v4.i256 = umulsat v0 v1;
60+
v4.i64 = umulsat v0 v1;
6161
return v4;
6262
}
6363

64-
func private %impl_trait_u64__saturating_mul(v0.i64, v1.i64) -> i64 {
64+
func private %impl_trait_u256__saturating_mul(v0.i256, v1.i256) -> i256 {
6565
block0:
6666
jump block1;
6767

6868
block1:
69-
v4.i64 = umulsat v0 v1;
69+
v4.i256 = umulsat v0 v1;
7070
return v4;
7171
}
7272

@@ -116,39 +116,39 @@ func private %impl_trait_u256__saturating_sub(v0.i256, v1.i256) -> i256 {
116116
return v4;
117117
}
118118

119-
func private %impl_trait_u256__wrapping_add(v0.i256, v1.i256) -> i256 {
119+
func private %impl_trait_u64__wrapping_add(v0.i64, v1.i64) -> i64 {
120120
block0:
121121
jump block1;
122122

123123
block1:
124-
v4.i256 = add v0 v1;
124+
v4.i64 = add v0 v1;
125125
return v4;
126126
}
127127

128-
func private %impl_trait_u64__wrapping_add(v0.i64, v1.i64) -> i64 {
128+
func private %impl_trait_u256__wrapping_add(v0.i256, v1.i256) -> i256 {
129129
block0:
130130
jump block1;
131131

132132
block1:
133-
v4.i64 = add v0 v1;
133+
v4.i256 = add v0 v1;
134134
return v4;
135135
}
136136

137-
func private %impl_trait_u64__wrapping_mul(v0.i64, v1.i64) -> i64 {
137+
func private %impl_trait_u256__wrapping_mul(v0.i256, v1.i256) -> i256 {
138138
block0:
139139
jump block1;
140140

141141
block1:
142-
v4.i64 = mul v0 v1;
142+
v4.i256 = mul v0 v1;
143143
return v4;
144144
}
145145

146-
func private %impl_trait_u256__wrapping_mul(v0.i256, v1.i256) -> i256 {
146+
func private %impl_trait_u64__wrapping_mul(v0.i64, v1.i64) -> i64 {
147147
block0:
148148
jump block1;
149149

150150
block1:
151-
v4.i256 = mul v0 v1;
151+
v4.i64 = mul v0 v1;
152152
return v4;
153153
}
154154

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use core::ops::{WrappingAdd, WrappingMul, WrappingSub}
2+
3+
trait LeftWide {}
4+
trait LeftNarrow {}
5+
trait RightWide {}
6+
7+
struct X {
8+
value: u256,
9+
}
10+
11+
struct Y {
12+
value: u256,
13+
}
14+
15+
struct Z {
16+
value: u256,
17+
}
18+
19+
impl LeftWide for X {}
20+
impl LeftWide for Y {}
21+
22+
impl LeftNarrow for X {}
23+
impl LeftNarrow for Z {}
24+
25+
impl RightWide for Y {}
26+
impl RightWide for Z {}
27+
28+
impl<T: LeftWide + LeftNarrow> WrappingAdd for T {
29+
fn wrapping_add(self, _ other: T) -> Self {
30+
self
31+
}
32+
}
33+
34+
impl<T: RightWide> WrappingAdd for T {
35+
fn wrapping_add(self, _ other: T) -> Self {
36+
other
37+
}
38+
}
39+
40+
trait EmptyMarker {}
41+
trait FullMarker {}
42+
43+
struct Full {
44+
value: u256,
45+
}
46+
47+
impl FullMarker for Full {}
48+
49+
impl<T: EmptyMarker> WrappingSub for T {
50+
fn wrapping_sub(self, _ other: T) -> Self {
51+
self
52+
}
53+
}
54+
55+
impl<T: FullMarker> WrappingSub for T {
56+
fn wrapping_sub(self, _ other: T) -> Self {
57+
other
58+
}
59+
}
60+
61+
trait LeftOnly {}
62+
trait RightOnly {}
63+
trait Common {}
64+
65+
struct Left {
66+
value: u256,
67+
}
68+
69+
struct Right {
70+
value: u256,
71+
}
72+
73+
impl LeftOnly for Left {}
74+
impl Common for Left {}
75+
76+
impl RightOnly for Right {}
77+
impl Common for Right {}
78+
79+
impl<T: LeftOnly + Common> WrappingMul for T {
80+
fn wrapping_mul(self, _ other: T) -> Self {
81+
self
82+
}
83+
}
84+
85+
impl<T: RightOnly + Common> WrappingMul for T {
86+
fn wrapping_mul(self, _ other: T) -> Self {
87+
other
88+
}
89+
}
90+
91+
#[test]
92+
fn sealed_marker_blanket_impl_global_intersection_disjoint() {
93+
let left = X { value: 11 }
94+
let left_other = X { value: 31 }
95+
assert!(left.wrapping_add(left_other).value == 11)
96+
97+
let right = Y { value: 5 }
98+
let right_other = Y { value: 7 }
99+
assert!(right.wrapping_add(right_other).value == 7)
100+
}
101+
102+
#[test]
103+
fn sealed_marker_blanket_impl_empty_marker_targets_are_unreachable() {
104+
let full = Full { value: 13 }
105+
let full_other = Full { value: 17 }
106+
assert!(full.wrapping_sub(full_other).value == 17)
107+
}
108+
109+
#[test]
110+
fn sealed_marker_blanket_impl_single_disjoint_pair_is_enough() {
111+
let left = Left { value: 23 }
112+
let left_other = Left { value: 29 }
113+
assert!(left.wrapping_mul(left_other).value == 23)
114+
115+
let right = Right { value: 37 }
116+
let right_other = Right { value: 41 }
117+
assert!(right.wrapping_mul(right_other).value == 41)
118+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Runtime coverage for the ABI traits on custom-width Solidity int wrappers
2+
// (`Encode` / `Decode` / `AbiSize` / `AbiSpan` / `TopicValue`), which are
3+
// provided by marker-gated blanket impls in `std::abi::sol::ints`. Round-trips
4+
// a value through a contract call (caller-side `Encode`, callee-side `Decode`,
5+
// and the re-`Encode`d return) and emits an event whose indexed field uses
6+
// `TopicValue`.
7+
use std::abi::sol
8+
use std::abi::sol::{Uint160, Int24}
9+
use std::evm::{Evm, Log}
10+
11+
msg M {
12+
#[selector = sol("rtU160(uint160)")]
13+
RtU160 { v: Uint160 } -> Uint160,
14+
#[selector = sol("rtI24(int24)")]
15+
RtI24 { v: Int24 } -> Int24,
16+
#[selector = sol("emitSwap(uint160,int24)")]
17+
EmitSwap { sender: Uint160, tick: Int24 },
18+
}
19+
20+
#[event]
21+
struct Swap {
22+
#[indexed]
23+
sender: Uint160,
24+
tick: Int24,
25+
}
26+
27+
pub contract C uses (log: mut Log) {
28+
init() {}
29+
30+
recv M {
31+
RtU160 { v } -> Uint160 {
32+
v
33+
}
34+
RtI24 { v } -> Int24 {
35+
v
36+
}
37+
EmitSwap { sender, tick } uses (mut log) {
38+
log.emit(Swap { sender: sender, tick: tick })
39+
}
40+
}
41+
}
42+
43+
#[test]
44+
fn uint160_abi_roundtrip() uses (evm: mut Evm) {
45+
let c = evm.create2<C>(value: 0, args: (), salt: 0)
46+
47+
let max_u160: u256 = ((1 as u256) << 160) - 1
48+
let r: Uint160 = evm.call(addr: c, gas: 2000000, value: 0, message: M::RtU160 { v: Uint160 { val: max_u160 } })
49+
assert(r.val == max_u160)
50+
51+
let r: Uint160 = evm.call(addr: c, gas: 2000000, value: 0, message: M::RtU160 { v: Uint160 { val: 0x1234 } })
52+
assert(r.val == 0x1234)
53+
}
54+
55+
#[test]
56+
fn int24_abi_roundtrip() uses (evm: mut Evm) {
57+
let c = evm.create2<C>(value: 0, args: (), salt: 2)
58+
59+
// Exercises signed custom-width decode/encode (sign-extension) directly,
60+
// across the full int24 range including negatives.
61+
let r: Int24 = evm.call(addr: c, gas: 2000000, value: 0, message: M::RtI24 { v: Int24 { val: 8388607 } })
62+
assert(r.val == 8388607)
63+
64+
let r: Int24 = evm.call(addr: c, gas: 2000000, value: 0, message: M::RtI24 { v: Int24 { val: -8388608 } })
65+
assert(r.val == -8388608)
66+
67+
let r: Int24 = evm.call(addr: c, gas: 2000000, value: 0, message: M::RtI24 { v: Int24 { val: -1 } })
68+
assert(r.val == -1)
69+
}
70+
71+
#[test]
72+
fn event_indexed_uint160_topic() uses (evm: mut Evm) {
73+
let c = evm.create2<C>(value: 0, args: (), salt: 1)
74+
evm.call(
75+
addr: c,
76+
gas: 2000000,
77+
value: 0,
78+
message: M::EmitSwap { sender: Uint160 { val: 0xabcdef }, tick: Int24 { val: -42 } },
79+
)
80+
}

0 commit comments

Comments
 (0)