Skip to content

Commit

Permalink
feat(allocator): implement IntoIterator for &mut Vec (#8389)
Browse files Browse the repository at this point in the history
Implement `IntoIterator` for `&mut Vec` like `std::vec::Vec` does. This allows shorter and more idiomatic syntax.

Before:

```rs
for item in object.collection.iter_mut() {
  // ...
}
```

After:

```rs
for item in &mut object.collection {
  // ...
}
```
  • Loading branch information
overlookmotel committed Jan 9, 2025
1 parent eb25bc0 commit 6c7acac
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 132 deletions.
9 changes: 9 additions & 0 deletions crates/oxc_allocator/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ impl<'i, T> IntoIterator for &'i Vec<'_, T> {
}
}

impl<'i, T> IntoIterator for &'i mut Vec<'_, T> {
type IntoIter = std::slice::IterMut<'i, T>;
type Item = &'i mut T;

fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}

impl<T, I> ops::Index<I> for Vec<'_, T>
where
I: SliceIndex<[T]>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ impl<'a, 'b> PeepholeRemoveDeadCode {
return None;
}

for el in array_expr.elements.iter_mut() {
for el in &mut array_expr.elements {
match el {
ArrayExpressionElement::SpreadElement(_) => {
let spread_element = ctx.ast.move_array_expression_element(el);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
decl: &mut VariableDeclaration<'a>,
ctx: &mut TraverseCtx<'a>,
) {
for declarator in decl.declarations.iter_mut() {
for declarator in &mut decl.declarations {
self.compress_variable_declarator(declarator, Ctx(ctx));
}
}
Expand Down Expand Up @@ -1084,7 +1084,7 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
for arg in old_args {
if let Argument::SpreadElement(mut spread_el) = arg {
if let Expression::ArrayExpression(array_expr) = &mut spread_el.argument {
for el in array_expr.elements.iter_mut() {
for el in &mut array_expr.elements {
match el {
ArrayExpressionElement::SpreadElement(spread_el) => {
new_args.push(ctx.ast.argument_spread_element(
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_parser/src/js/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ impl<'a> ParserImpl<'a> {

// ExportDeclaration : export NamedExports ;
if source.is_none() {
for specifier in specifiers.iter_mut() {
for specifier in &mut specifiers {
match &specifier.local {
// It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals.
ModuleExportName::StringLiteral(literal) => {
Expand Down
10 changes: 5 additions & 5 deletions crates/oxc_transformer/src/es2018/object_rest_spread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ impl<'a> ObjectRestSpread<'a, '_> {
match target {
AssignmentTarget::ObjectAssignmentTarget(t) => {
let mut data = vec![];
for prop in t.properties.iter_mut() {
for prop in &mut t.properties {
if let AssignmentTargetProperty::AssignmentTargetPropertyProperty(p) = prop {
data.extend(match &mut p.binding {
AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(t) => {
Expand Down Expand Up @@ -419,7 +419,7 @@ impl<'a> ObjectRestSpread<'a, '_> {
}
}
AssignmentTarget::ObjectAssignmentTarget(t) => {
for p in t.properties.iter_mut() {
for p in &mut t.properties {
if let AssignmentTargetProperty::AssignmentTargetPropertyProperty(e) = p {
Self::recursive_walk_assignment_target_maybe_default(
&mut e.binding,
Expand Down Expand Up @@ -537,7 +537,7 @@ impl<'a> ObjectRestSpread<'a, '_> {
fn transform_function(func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
let scope_id = func.scope_id();
let Some(body) = func.body.as_mut() else { return };
for param in func.params.items.iter_mut() {
for param in &mut func.params.items {
if Self::has_nested_object_rest(&param.pattern) {
Self::replace_rest_element(
VariableDeclarationKind::Var,
Expand All @@ -554,7 +554,7 @@ impl<'a> ObjectRestSpread<'a, '_> {
fn transform_arrow(arrow: &mut ArrowFunctionExpression<'a>, ctx: &mut TraverseCtx<'a>) {
let scope_id = arrow.scope_id();
let mut replaced = false;
for param in arrow.params.items.iter_mut() {
for param in &mut arrow.params.items {
if Self::has_nested_object_rest(&param.pattern) {
Self::replace_rest_element(
VariableDeclarationKind::Var,
Expand Down Expand Up @@ -599,7 +599,7 @@ impl<'a> ObjectRestSpread<'a, '_> {
scope_id: ScopeId,
ctx: &mut TraverseCtx<'a>,
) {
for declarator in decl.declarations.iter_mut() {
for declarator in &mut decl.declarations {
if Self::has_nested_object_rest(&declarator.id) {
let new_scope_id = Self::try_replace_statement_with_block(body, scope_id, ctx);
let Statement::BlockStatement(block) = body else {
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_transformer/src/es2022/class_properties/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<'a> ClassProperties<'a, '_> {
// TODO: Store `FxIndexMap`s in a pool and re-use them
let mut private_props = FxIndexMap::default();
let mut constructor = None;
for element in body.body.iter_mut() {
for element in &mut body.body {
match element {
ClassElement::PropertyDefinition(prop) => {
// TODO: Throw error if property has decorators
Expand Down Expand Up @@ -296,7 +296,7 @@ impl<'a> ClassProperties<'a, '_> {
}

let mut constructor = None;
for element in body.body.iter_mut() {
for element in &mut body.body {
#[expect(clippy::match_same_arms)]
match element {
ClassElement::PropertyDefinition(prop) => {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_transformer/src/es2022/class_static_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'a> Traverse<'a> for ClassStaticBlock {
return;
}

for element in body.body.iter_mut() {
for element in &mut body.body {
if let ClassElement::StaticBlock(block) = element {
*element = Self::convert_block_to_private_field(block, &mut keys, ctx);
}
Expand Down
9 changes: 5 additions & 4 deletions crates/oxc_traverse/scripts/lib/walk.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function generateWalkFunctionsCode(types) {
ctx: &mut TraverseCtx<'a>
) {
traverser.enter_statements(&mut *stmts, ctx);
for stmt in (*stmts).iter_mut() {
for stmt in &mut *stmts {
walk_statement(traverser, stmt, ctx);
}
traverser.exit_statements(&mut *stmts, ctx);
Expand Down Expand Up @@ -209,17 +209,18 @@ function generateWalkForStruct(type, types) {
walkVecCode = `walk_statements(traverser, ${fieldCode}, ctx);`;
} else {
let walkCode = `${fieldWalkName}(traverser, item as *mut _, ctx);`,
iterModifier = '';
iteratorCode = '';
if (field.wrappers.length === 2 && field.wrappers[1] === 'Option') {
iterModifier = '.flatten()';
iteratorCode = `(*(${fieldCode})).iter_mut().flatten()`;
} else {
assert(
field.wrappers.length === 1,
`Cannot handle struct field with type ${field.type}`,
);
iteratorCode = `&mut *(${fieldCode})`;
}
walkVecCode = `
for item in (*(${fieldCode})).iter_mut()${iterModifier} {
for item in ${iteratorCode} {
${walkCode}
}
`.trim();
Expand Down
Loading

0 comments on commit 6c7acac

Please sign in to comment.