Skip to content

Commit b28af85

Browse files
authored
impl PartialEq, Eq, Hash, Clone for array (#7037)
## Description This PR is part of #6860. It continues the implementation of more `std` library "traits" for arrays. It also fixes a small error when formatting "const generics declarations". ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
1 parent 74282e2 commit b28af85

File tree

8 files changed

+222
-40
lines changed

8 files changed

+222
-40
lines changed

sway-core/src/language/ty/expression/expression.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,12 @@ impl MaterializeConstGenerics for TyExpression {
383383
self.return_type
384384
.materialize_const_generics(engines, handler, name, value)?;
385385
match &mut self.expression {
386+
TyExpressionVariant::CodeBlock(block) => {
387+
for node in block.contents.iter_mut() {
388+
node.materialize_const_generics(engines, handler, name, value)?;
389+
}
390+
Ok(())
391+
}
386392
TyExpressionVariant::ConstGenericExpression { decl, .. } => {
387393
decl.materialize_const_generics(engines, handler, name, value)
388394
}
@@ -393,7 +399,29 @@ impl MaterializeConstGenerics for TyExpression {
393399
for (_, expr) in arguments {
394400
expr.materialize_const_generics(engines, handler, name, value)?;
395401
}
396-
402+
Ok(())
403+
}
404+
TyExpressionVariant::IntrinsicFunction(TyIntrinsicFunctionKind {
405+
arguments, ..
406+
}) => {
407+
for expr in arguments {
408+
expr.materialize_const_generics(engines, handler, name, value)?;
409+
}
410+
Ok(())
411+
}
412+
TyExpressionVariant::Return(expr) => {
413+
expr.materialize_const_generics(engines, handler, name, value)
414+
}
415+
TyExpressionVariant::IfExp {
416+
condition,
417+
then,
418+
r#else,
419+
} => {
420+
condition.materialize_const_generics(engines, handler, name, value)?;
421+
then.materialize_const_generics(engines, handler, name, value)?;
422+
if let Some(e) = r#else.as_mut() {
423+
e.materialize_const_generics(engines, handler, name, value)?;
424+
}
397425
Ok(())
398426
}
399427
TyExpressionVariant::WhileLoop { condition, body } => {
@@ -407,12 +435,6 @@ impl MaterializeConstGenerics for TyExpression {
407435
prefix.materialize_const_generics(engines, handler, name, value)?;
408436
index.materialize_const_generics(engines, handler, name, value)
409437
}
410-
TyExpressionVariant::IntrinsicFunction(kind) => {
411-
for expr in kind.arguments.iter_mut() {
412-
expr.materialize_const_generics(engines, handler, name, value)?;
413-
}
414-
Ok(())
415-
}
416438
TyExpressionVariant::Literal(_) | TyExpressionVariant::VariableExpression { .. } => {
417439
Ok(())
418440
}
@@ -428,6 +450,9 @@ impl MaterializeConstGenerics for TyExpression {
428450
TyExpressionVariant::Ref(r) => {
429451
r.materialize_const_generics(engines, handler, name, value)
430452
}
453+
TyExpressionVariant::Deref(r) => {
454+
r.materialize_const_generics(engines, handler, name, value)
455+
}
431456
_ => Err(handler.emit_err(
432457
sway_error::error::CompileError::ConstGenericNotSupportedHere {
433458
span: self.span.clone(),

sway-lib-std/src/clone.sw

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,67 @@ pub trait Clone {
66
/// Clone self into a new value of the same type.
77
fn clone(self) -> Self;
88
}
9+
10+
impl Clone for u8 {
11+
fn clone(self) -> Self {
12+
self
13+
}
14+
}
15+
16+
impl Clone for u16 {
17+
fn clone(self) -> Self {
18+
self
19+
}
20+
}
21+
22+
impl Clone for u32 {
23+
fn clone(self) -> Self {
24+
self
25+
}
26+
}
27+
28+
impl Clone for u64 {
29+
fn clone(self) -> Self {
30+
self
31+
}
32+
}
33+
34+
impl Clone for u256 {
35+
fn clone(self) -> Self {
36+
self
37+
}
38+
}
39+
40+
#[cfg(experimental_const_generics = true)]
41+
impl<T, const N: u64> Clone for [T; N]
42+
where
43+
T: Clone,
44+
{
45+
fn clone(self) -> Self {
46+
let first: T = *__elem_at(&self, 0);
47+
let mut new_array = [first.clone(); N];
48+
49+
let mut i = 1;
50+
while __lt(i, N) {
51+
let item: T = *__elem_at(&self, i);
52+
let new_item: &mut T = __elem_at(&mut new_array, i);
53+
*new_item = item.clone();
54+
i = __add(i, 1);
55+
}
56+
57+
new_array
58+
}
59+
}
60+
61+
#[cfg(experimental_const_generics = true)]
62+
#[test]
63+
fn ok_array_clone() {
64+
use ::ops::*;
65+
66+
let a = [1, 2, 3];
67+
let b = a.clone();
68+
69+
if !a.eq(b) {
70+
__revert(5);
71+
}
72+
}

sway-lib-std/src/codec.sw

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ impl AbiEncode for raw_slice {
698698
}
699699

700700
#[cfg(experimental_const_generics = true)]
701-
impl<T, const N:u64> AbiEncode for [T; N]
701+
impl<T, const N: u64> AbiEncode for [T; N]
702702
where
703703
T: AbiEncode,
704704
{
@@ -3219,7 +3219,7 @@ impl AbiDecode for str[64] {
32193219
// END STRARRAY_DECODE
32203220

32213221
#[cfg(experimental_const_generics = true)]
3222-
impl<T, const N:u64> AbiDecode for [T; N]
3222+
impl<T, const N: u64> AbiDecode for [T; N]
32233223
where
32243224
T: AbiDecode,
32253225
{

sway-lib-std/src/hash.sw

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ where
241241
}
242242
}
243243

244+
#[cfg(experimental_const_generics = false)]
244245
impl<T> Hash for [T; 1]
245246
where
246247
T: Hash,
@@ -250,6 +251,7 @@ where
250251
}
251252
}
252253

254+
#[cfg(experimental_const_generics = false)]
253255
impl<T> Hash for [T; 2]
254256
where
255257
T: Hash,
@@ -260,6 +262,7 @@ where
260262
}
261263
}
262264

265+
#[cfg(experimental_const_generics = false)]
263266
impl<T> Hash for [T; 3]
264267
where
265268
T: Hash,
@@ -271,6 +274,7 @@ where
271274
}
272275
}
273276

277+
#[cfg(experimental_const_generics = false)]
274278
impl<T> Hash for [T; 4]
275279
where
276280
T: Hash,
@@ -283,6 +287,7 @@ where
283287
}
284288
}
285289

290+
#[cfg(experimental_const_generics = false)]
286291
impl<T> Hash for [T; 5]
287292
where
288293
T: Hash,
@@ -296,6 +301,7 @@ where
296301
}
297302
}
298303

304+
#[cfg(experimental_const_generics = false)]
299305
impl<T> Hash for [T; 6]
300306
where
301307
T: Hash,
@@ -310,6 +316,7 @@ where
310316
}
311317
}
312318

319+
#[cfg(experimental_const_generics = false)]
313320
impl<T> Hash for [T; 7]
314321
where
315322
T: Hash,
@@ -325,6 +332,7 @@ where
325332
}
326333
}
327334

335+
#[cfg(experimental_const_generics = false)]
328336
impl<T> Hash for [T; 8]
329337
where
330338
T: Hash,
@@ -341,6 +349,7 @@ where
341349
}
342350
}
343351

352+
#[cfg(experimental_const_generics = false)]
344353
impl<T> Hash for [T; 9]
345354
where
346355
T: Hash,
@@ -358,6 +367,7 @@ where
358367
}
359368
}
360369

370+
#[cfg(experimental_const_generics = false)]
361371
impl<T> Hash for [T; 10]
362372
where
363373
T: Hash,
@@ -376,6 +386,21 @@ where
376386
}
377387
}
378388

389+
#[cfg(experimental_const_generics = true)]
390+
impl<T, const N: u64> Hash for [T; N]
391+
where
392+
T: Hash,
393+
{
394+
fn hash(self, ref mut state: Hasher) {
395+
let mut i = 0;
396+
while __lt(i, N) {
397+
let item: T = *__elem_at(&self, i);
398+
item.hash(state);
399+
i = __add(i, 1);
400+
}
401+
}
402+
}
403+
379404
/// Returns the `SHA-2-256` hash of `param`.
380405
///
381406
/// # Arguments
@@ -462,3 +487,16 @@ where
462487
s.hash(hasher);
463488
hasher.keccak256()
464489
}
490+
491+
#[cfg(experimental_const_generics = true)]
492+
#[test]
493+
fn ok_array_hash() {
494+
use ::ops::*;
495+
496+
let a = sha256([1, 2, 3]);
497+
let b = sha256((1, 2, 3));
498+
499+
if a != b {
500+
__revert(0);
501+
}
502+
}

sway-lib-std/src/ops.sw

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,34 @@ impl PartialEq for raw_ptr {
729729

730730
impl Eq for raw_ptr {}
731731

732+
#[cfg(experimental_const_generics = true)]
733+
impl<T, const N: u64> PartialEq for [T; N]
734+
where
735+
T: PartialEq,
736+
{
737+
fn eq(self, other: Self) -> bool {
738+
let mut i = 0;
739+
while __lt(i, N) {
740+
let a: T = *__elem_at(&self, i);
741+
let b: T = *__elem_at(&other, i);
742+
743+
if !a.eq(b) {
744+
return false;
745+
}
746+
747+
i = __add(i, 1);
748+
};
749+
750+
true
751+
}
752+
}
753+
754+
#[cfg(experimental_const_generics = true)]
755+
impl<T, const N: u64> Eq for [T; N]
756+
where
757+
T: Eq,
758+
{}
759+
732760
/// Trait to evaluate if one value is greater or less than another of the same type.
733761
pub trait Ord {
734762
/// Evaluates if one value of the same type is greater than another.
@@ -1611,3 +1639,29 @@ fn u64_as_u8(val: u64) -> u8 {
16111639
input: u8
16121640
}
16131641
}
1642+
1643+
#[cfg(experimental_const_generics = true)]
1644+
#[test]
1645+
fn ok_array_eq() {
1646+
let a = [1, 2, 3];
1647+
let b = [1, 2, 3];
1648+
let c = [1, 1, 1];
1649+
1650+
if !a.eq(a) {
1651+
__revert(0);
1652+
}
1653+
1654+
if !a.eq(b) {
1655+
__revert(0);
1656+
}
1657+
if !b.eq(a) {
1658+
__revert(0);
1659+
}
1660+
1661+
if a.eq(c) {
1662+
__revert(0);
1663+
}
1664+
if c.eq(a) {
1665+
__revert(0);
1666+
}
1667+
}

swayfmt/src/utils/language/generics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ impl Format for GenericParam {
2121
write!(formatted_code, "{} ", ConstToken::AS_STR)?;
2222
let _ = ident.format(formatted_code, formatter);
2323
let _ = colon(formatted_code);
24+
write!(formatted_code, " ")?;
2425
ty.format(formatted_code, formatter)
2526
}
2627
}

swayfmt/tests/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ fn impl_spacing() {
12671267
fn is_baz_true(self) -> bool;
12681268
}
12691269
1270-
impl<A , B> Qux<A, B> for
1270+
impl<A , B , const N : u64> Qux<A, B> for
12711271
Foo
12721272
where
12731273
A : Qux,
@@ -1287,7 +1287,7 @@ fn impl_spacing() {
12871287
fn is_baz_true(self) -> bool;
12881288
}
12891289
1290-
impl<A, B> Qux<A, B> for Foo
1290+
impl<A, B, const N: u64> Qux<A, B> for Foo
12911291
where
12921292
A: Qux,
12931293
B: Qux,

0 commit comments

Comments
 (0)