Skip to content

Commit d3c37a0

Browse files
committed
iterator trait for arrays
1 parent 0aef56a commit d3c37a0

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

sway-core/src/type_system/id.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use sway_error::{
88
use sway_types::{BaseIdent, Named, Span, Spanned};
99

1010
use crate::{
11-
decl_engine::{DeclEngineGet, DeclEngineInsert, MaterializeConstGenerics},
11+
decl_engine::{DeclEngineGet, DeclEngineGetParsedDecl, DeclEngineInsert, MaterializeConstGenerics},
1212
engine_threading::{DebugWithEngines, DisplayWithEngines, Engines, WithEngines},
13-
language::CallPath,
13+
language::{ty::TyStructDecl, CallPath},
1414
namespace::TraitMap,
1515
semantic_analysis::TypeCheckContext,
1616
type_system::priv_prelude::*,
@@ -150,10 +150,28 @@ impl MaterializeConstGenerics for TypeId {
150150
let mut decl = (*decl).clone();
151151
decl.materialize_const_generics(engines, handler, name, value)?;
152152

153-
let decl_ref = engines.de().insert(decl, None);
153+
let parsed_decl = engines.de()
154+
.get_parsed_decl(id)
155+
.unwrap()
156+
.to_enum_decl(handler, engines)
157+
.ok();
158+
let decl_ref = engines.de().insert(decl, parsed_decl.as_ref());
154159

155160
*self = engines.te().insert_enum(engines, *decl_ref.id());
156161
}
162+
TypeInfo::Struct(id) => {
163+
let mut decl = TyStructDecl::clone(&engines.de().get(id));
164+
decl.materialize_const_generics(engines, handler, name, value)?;
165+
166+
let parsed_decl = engines.de()
167+
.get_parsed_decl(id)
168+
.unwrap()
169+
.to_struct_decl(handler, engines)
170+
.ok();
171+
let decl_ref = engines.de().insert(decl, parsed_decl.as_ref());
172+
173+
*self = engines.te().insert_struct(engines, *decl_ref.id());
174+
}
157175
TypeInfo::StringArray(Length(ConstGenericExpr::AmbiguousVariableExpression {
158176
ident,
159177
})) if ident.as_str() == name => {

sway-lib-std/src/iterator.sw

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,66 @@ pub trait Iterator {
5858
/// ```
5959
fn next(ref mut self) -> Option<Self::Item>;
6060
}
61+
62+
// Array Iterator
63+
64+
#[cfg(experimental_const_generics = true)]
65+
impl<T, const N: u64> [T; N] {
66+
fn iter(self) -> ArrayIterator<T, N> {
67+
ArrayIterator { array: self, idx: 0 }
68+
}
69+
}
70+
71+
#[cfg(experimental_const_generics = true)]
72+
pub struct ArrayIterator<T, const N: u64> {
73+
array: [T; N],
74+
idx: u64,
75+
}
76+
77+
#[cfg(experimental_const_generics = true)]
78+
impl<T, const N: u64> Iterator for ArrayIterator<T, N> {
79+
type Item = T;
80+
81+
fn next(ref mut self) -> Option<Self::Item> {
82+
if self.idx >= N {
83+
None
84+
} else {
85+
let elem = __elem_at(&self.array, self.idx);
86+
self.idx += 1;
87+
Some(*elem)
88+
}
89+
}
90+
}
91+
92+
// Tests
93+
94+
#[cfg(experimental_const_generics = true)]
95+
#[test]
96+
fn ok_array_iterator_manual() {
97+
use ::assert::*;
98+
let array: [u64; 3] = [1u64, 2u64, 3u64];
99+
100+
let mut iterator = array.iter();
101+
let a = iterator.next();
102+
let b = iterator.next();
103+
let c = iterator.next();
104+
let d = iterator.next();
105+
106+
assert(a == Some(1u64));
107+
assert(b == Some(2u64));
108+
assert(c == Some(3u64));
109+
assert(d == None);
110+
}
111+
112+
#[cfg(experimental_const_generics = true)]
113+
#[test]
114+
fn ok_array_iterator_for() {
115+
use ::assert::*;
116+
let array: [u64; 3] = [1u64, 2u64, 3u64];
117+
118+
let mut value = 0;
119+
for v in array.iter() {
120+
value += v;
121+
}
122+
assert(value == 6);
123+
}

0 commit comments

Comments
 (0)