Merge branch 'trunk' into let-rec

This commit is contained in:
Richard Feldman 2019-12-31 20:38:05 -05:00 committed by GitHub
commit b0ce78c212
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 18 deletions

View file

@ -173,6 +173,25 @@ pub fn fmt_expr<'a>(
}
}
}
List(loc_items) => {
buf.push('[');
let mut iter = loc_items.iter().peekable();
while let Some(item) = iter.next() {
buf.push(' ');
fmt_expr(buf, &item.value, indent, false, true);
if iter.peek().is_some() {
buf.push(',');
}
}
if !loc_items.is_empty() {
buf.push(' ');
}
buf.push(']');
}
other => panic!("TODO implement Display for AST variant {:?}", other),
}
}

View file

@ -652,11 +652,21 @@ macro_rules! skip_second {
#[macro_export]
macro_rules! collection {
($opening_brace:expr, $elem:expr, $delimiter:expr, $closing_brace:expr, $min_indent:expr) => {
// TODO allow trailing commas before the closing delimiter, *but* without
// losing any comments or newlines! This will require parsing them and then,
// if they are present, merging them into the final Spaceable.
skip_first!(
$opening_brace,
skip_first!(
// We specifically allow space characters inside here, so that
// `[ ]` can be successfully parsed as an empty list, and then
// changed by the formatter back into `[]`.
//
// We don't allow newlines or comments in the middle of empty
// collections because those are normally stored in an Expr,
// and there's no Expr in which to store them in an empty collection!
//
// We could change the AST to add extra storage specifically to
// support empty literals containing newlines or comments, but this
// does not seem worth even the tiniest regression in compiler performance.
zero_or_more!(char(' ')),
skip_second!(
$crate::parse::parser::sep_by0(
$delimiter,
@ -665,6 +675,7 @@ macro_rules! collection {
$closing_brace
)
)
)
};
}

View file

@ -235,15 +235,7 @@ impl Subs {
if desc.copy.is_some() {
let content = desc.content;
self.set(
var,
Descriptor {
content: content.clone(),
rank: Rank::NONE,
mark: Mark::NONE,
copy: None,
},
);
self.set(var, content.clone().into());
restore_content(self, &content);
}

View file

@ -540,6 +540,24 @@ mod test_format {
));
}
// LIST
#[test]
fn empty_list() {
expr_formats_same("[]");
expr_formats_to("[ ]", "[]");
}
#[test]
fn one_item_list() {
expr_formats_same(indoc!("[ 4 ] "));
}
#[test]
fn two_item_list() {
expr_formats_same(indoc!("[ 7, 8 ] "));
expr_formats_to(indoc!("[ 7 , 8 ] "), indoc!("[ 7, 8 ] "));
}
// RECORD LITERALS
#[test]

View file

@ -669,6 +669,17 @@ mod test_parse {
assert_eq!(Ok(expected), actual);
}
#[test]
fn spaces_inside_empty_list() {
// This is a regression test!
let arena = Bump::new();
let elems = Vec::new_in(&arena);
let expected = List(elems);
let actual = parse_with(&arena, "[ ]");
assert_eq!(Ok(expected), actual);
}
#[test]
fn packed_singleton_list() {
let arena = Bump::new();