diff --git a/src/parse/control_flow.rs b/src/parse/control_flow.rs index 559f985..646896d 100644 --- a/src/parse/control_flow.rs +++ b/src/parse/control_flow.rs @@ -294,7 +294,7 @@ impl<'a> Parser<'a> { self.scopes.enter_new_scope(); for i in iter { - self.scopes.insert_var( + self.scopes.insert_var_last( var.node, Spanned { node: Value::Dimension(Number::from(i), Unit::None), @@ -464,9 +464,11 @@ impl<'a> Parser<'a> { let mut stmts = Vec::new(); + self.scopes.enter_new_scope(); + for row in iter { if vars.len() == 1 { - self.scopes.insert_var( + self.scopes.insert_var_last( vars[0].node, Spanned { node: row, @@ -479,7 +481,7 @@ impl<'a> Parser<'a> { .into_iter() .chain(std::iter::once(Value::Null).cycle()), ) { - self.scopes.insert_var( + self.scopes.insert_var_last( var.node, Spanned { node: val, @@ -531,6 +533,8 @@ impl<'a> Parser<'a> { } } + self.scopes.exit_scope(); + Ok(stmts) } } diff --git a/src/scope.rs b/src/scope.rs index 7ce48de..484b1aa 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -128,6 +128,20 @@ impl Scopes { } } + /// Always insert this variable into the innermost scope + /// + /// Used, for example, for variables from `@each` and `@for` + pub fn insert_var_last(&mut self, s: Identifier, v: Spanned) -> Option> { + if let Some(scope) = self.0.last_mut() { + scope.insert_var(s, v) + } else { + let mut scope = Scope::new(); + scope.insert_var(s, v); + self.0.push(scope); + None + } + } + pub fn insert_default_var( &mut self, s: Identifier, diff --git a/tests/each.rs b/tests/each.rs index aede71d..a47e4b5 100644 --- a/tests/each.rs +++ b/tests/each.rs @@ -61,6 +61,22 @@ test!( }", "a {\n color: (a: b, c: d);\n}\n" ); +test!( + indexing_variable_does_not_affect_outer_scopes, + "a { + $a: 1; + $b: 1; + + @each $a in a b { + color: $a; + $b: $a; + } + + color: $a; + color: $b; + }", + "a {\n color: a;\n color: b;\n color: 1;\n color: b;\n}\n" +); error!( list_of_single_map, "a { diff --git a/tests/for.rs b/tests/for.rs index ee73806..7b6fa39 100644 --- a/tests/for.rs +++ b/tests/for.rs @@ -97,3 +97,19 @@ test!( }", "a {\n color: \\}}}{{{#;\n}\n" ); +test!( + indexing_variable_does_not_affect_outer_scopes, + "a { + $a: 1; + $b: 1; + + @for $a from 1 through 2 { + color: $a; + $b: $a; + } + + color: $a; + color: $b; + }", + "a {\n color: 1;\n color: 2;\n color: 1;\n color: 2;\n}\n" +);