Skip to content

Commit 581f6e1

Browse files
committed
Fix dict spreading in dict literal
1 parent ac4d3c0 commit 581f6e1

4 files changed

Lines changed: 124 additions & 37 deletions

File tree

‎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 {

‎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),

‎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
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
source: compiler/parser/src/parser.rs
3+
expression: parse_ast
4+
---
5+
Located {
6+
location: Location {
7+
row: 1,
8+
column: 0,
9+
},
10+
end_location: Some(
11+
Location {
12+
row: 1,
13+
column: 15,
14+
},
15+
),
16+
custom: (),
17+
node: Dict {
18+
keys: [
19+
Some(
20+
Located {
21+
location: Location {
22+
row: 1,
23+
column: 1,
24+
},
25+
end_location: Some(
26+
Location {
27+
row: 1,
28+
column: 4,
29+
},
30+
),
31+
custom: (),
32+
node: Constant {
33+
value: Str(
34+
"k",
35+
),
36+
kind: None,
37+
},
38+
},
39+
),
40+
None,
41+
],
42+
values: [
43+
Located {
44+
location: Location {
45+
row: 1,
46+
column: 6,
47+
},
48+
end_location: Some(
49+
Location {
50+
row: 1,
51+
column: 9,
52+
},
53+
),
54+
custom: (),
55+
node: Constant {
56+
value: Str(
57+
"v",
58+
),
59+
kind: None,
60+
},
61+
},
62+
Located {
63+
location: Location {
64+
row: 1,
65+
column: 13,
66+
},
67+
end_location: Some(
68+
Location {
69+
row: 1,
70+
column: 14,
71+
},
72+
),
73+
custom: (),
74+
node: Name {
75+
id: "d",
76+
ctx: Load,
77+
},
78+
},
79+
],
80+
},
81+
}

0 commit comments

Comments
 (0)