Skip to content

Commit e1f41e8

Browse files
committed
Fix dict spreading in dict literal
1 parent acbc517 commit e1f41e8

File tree

4 files changed

+124
-37
lines changed

4 files changed

+124
-37
lines changed

compiler/ast/src/ast_gen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ pub enum ExprKind<U = ()> {
195195
orelse: Box<Expr<U>>,
196196
},
197197
Dict {
198-
keys: Vec<Expr<U>>,
198+
keys: Vec<Option<Expr<U>>>,
199199
values: Vec<Expr<U>>,
200200
},
201201
Set {

compiler/parser/python.lalrpop

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,42 +1138,42 @@ Atom<Goal>: ast::Expr = {
11381138
<location:@L> "{" <e:DictLiteralValues?> "}" <end_location:@R> => {
11391139
let pairs = e.unwrap_or_default();
11401140

1141-
let (keys, values) = match pairs.iter().position(|(k,_)| k.is_none()) {
1142-
Some(unpack_idx) => {
1143-
let mut pairs = pairs;
1144-
let (keys, mut values): (_, Vec<_>) = pairs.drain(..unpack_idx).map(|(k, v)| (*k.unwrap(), v)).unzip();
1145-
1146-
fn build_map(items: &mut Vec<(ast::Expr, ast::Expr)>) -> ast::Expr {
1147-
let location = items[0].0.location;
1148-
let end_location = items[0].0.end_location;
1149-
let (keys, values) = items.drain(..).unzip();
1150-
ast::Expr {
1151-
location,
1152-
end_location,
1153-
custom: (),
1154-
node: ast::ExprKind::Dict { keys, values }
1155-
}
1156-
}
1157-
1158-
let mut items = Vec::new();
1159-
for (key, value) in pairs.into_iter() {
1160-
if let Some(key) = key {
1161-
items.push((*key, value));
1162-
continue;
1163-
}
1164-
if !items.is_empty() {
1165-
values.push(build_map(&mut items));
1166-
}
1167-
values.push(value);
1168-
}
1169-
if !items.is_empty() {
1170-
values.push(build_map(&mut items));
1171-
}
1172-
(keys, values)
1173-
},
1174-
None => pairs.into_iter().map(|(k, v)| (*k.unwrap(), v)).unzip()
1175-
};
1176-
1141+
// let (keys, values) = match pairs.iter().position(|(k,_)| k.is_none()) {
1142+
// Some(unpack_idx) => {
1143+
// let mut pairs = pairs;
1144+
// let (keys, mut values): (_, Vec<_>) = pairs.drain(..unpack_idx).map(|(k, v)| (*k.unwrap(), v)).unzip();
1145+
//
1146+
// fn build_map(items: &mut Vec<(ast::Expr, ast::Expr)>) -> ast::Expr {
1147+
// let location = items[0].0.location;
1148+
// let end_location = items[0].0.end_location;
1149+
// let (keys, values) = items.drain(..).unzip();
1150+
// ast::Expr {
1151+
// location,
1152+
// end_location,
1153+
// custom: (),
1154+
// node: ast::ExprKind::Dict { keys, values }
1155+
// }
1156+
// }
1157+
//
1158+
// let mut items = Vec::new();
1159+
// for (key, value) in pairs.into_iter() {
1160+
// if let Some(key) = key {
1161+
// items.push((*key, value));
1162+
// continue;
1163+
// }
1164+
// if !items.is_empty() {
1165+
// values.push(build_map(&mut items));
1166+
// }
1167+
// values.push(value);
1168+
// }
1169+
// if !items.is_empty() {
1170+
// values.push(build_map(&mut items));
1171+
// }
1172+
// (keys, values)
1173+
// },
1174+
// None => pairs.into_iter().map(|(k, v)| (k, v)).unzip()
1175+
// };
1176+
let (keys, values) = pairs.into_iter().map(|(k, v)| (k.map(|x| *x), v)).unzip();
11771177
ast::Expr {
11781178
location,
11791179
end_location: Some(end_location),

compiler/parser/src/parser.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,10 @@ with (0 as a, 1 as b,): pass
309309
assert!(parse_program(source, "<test>").is_err());
310310
}
311311
}
312+
313+
#[test]
314+
fn test_dict_containing_spread() {
315+
let parse_ast = parse_expression(r#"{"k": "v", **d}"#, "<test>").unwrap();
316+
insta::assert_debug_snapshot!(parse_ast);
317+
}
312318
}

compiler/parser/src/snapshots/rustpython_parser__parser__tests__dict_containing_spread.snap

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)