//! To make attribute macros work reliably when typing, we need to take care to
//! fix up syntax errors in the code we're passing to them.

use intern::sym;
use rustc_hash::{FxHashMap, FxHashSet};
use span::{
    ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor,
    SyntaxContext,
};
use stdx::never;
use syntax::{
    SyntaxElement, SyntaxKind, SyntaxNode, TextRange, TextSize,
    ast::{self, AstNode, HasLoopBody},
    match_ast,
};
use syntax_bridge::DocCommentDesugarMode;
use triomphe::Arc;
use tt::Spacing;

use crate::{
    span_map::SpanMapRef,
    tt::{self, Ident, Leaf, Punct, TopSubtree},
};

/// The result of calculating fixes for a syntax node -- a bunch of changes
/// (appending to and replacing nodes), the information that is needed to
/// reverse those changes afterwards, and a token map.
#[derive(Debug, Default)]
pub(crate) struct SyntaxFixups {
    pub(crate) append: FxHashMap<SyntaxElement, Vec<Leaf>>,
    pub(crate) remove: FxHashSet<SyntaxElement>,
    pub(crate) undo_info: SyntaxFixupUndoInfo,
}

/// This is the information needed to reverse the fixups.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct SyntaxFixupUndoInfo {
    // FIXME: ThinArc<[Subtree]>
    original: Option<Arc<Box<[TopSubtree]>>>,
}

impl SyntaxFixupUndoInfo {
    pub(crate) const NONE: Self = SyntaxFixupUndoInfo { original: None };
}

// We mark spans with `FIXUP_DUMMY_AST_ID` to indicate that they are fake.
const FIXUP_DUMMY_AST_ID: ErasedFileAstId = FIXUP_ERASED_FILE_AST_ID_MARKER;
const FIXUP_DUMMY_RANGE: TextRange = TextRange::empty(TextSize::new(0));
// If the fake span has this range end, that means that the range start is an index into the
// `original` list in `SyntaxFixupUndoInfo`.
const FIXUP_DUMMY_RANGE_END: TextSize = TextSize::new(!0);

pub(crate) fn fixup_syntax(
    span_map: SpanMapRef<'_>,
    node: &SyntaxNode,
    call_site: Span,
    mode: DocCommentDesugarMode,
) -> SyntaxFixups {
    let mut append = FxHashMap::<SyntaxElement, _>::default();
    let mut remove = FxHashSet::<SyntaxElement>::default();
    let mut preorder = node.preorder();
    let mut original = Vec::new();
    let dummy_range = FIXUP_DUMMY_RANGE;
    let fake_span = |range| {
        let span = span_map.span_for_range(range);
        Span {
            range: dummy_range,
            anchor: SpanAnchor { ast_id: FIXUP_DUMMY_AST_ID, ..span.anchor },
            ctx: span.ctx,
        }
    };
    while let Some(event) = preorder.next() {
        let syntax::WalkEvent::Enter(node) = event else { continue };

        let node_range = node.text_range();
        if can_handle_error(&node) && has_error_to_handle(&node) {
            remove.insert(node.clone().into());
            // the node contains an error node, we have to completely replace it by something valid
            let original_tree =
                syntax_bridge::syntax_node_to_token_tree(&node, span_map, call_site, mode);
            let idx = original.len() as u32;
            original.push(original_tree);
            let span = span_map.span_for_range(node_range);
            let replacement = Leaf::Ident(Ident {
                sym: sym::__ra_fixup,
                span: Span {
                    range: TextRange::new(TextSize::new(idx), FIXUP_DUMMY_RANGE_END),
                    anchor: SpanAnchor { ast_id: FIXUP_DUMMY_AST_ID, ..span.anchor },
                    ctx: span.ctx,
                },
                is_raw: tt::IdentIsRaw::No,
            });
            append.insert(node.clone().into(), vec![replacement]);
            preorder.skip_subtree();
            continue;
        }
        // In some other situations, we can fix things by just appending some tokens.
        match_ast! {
            match node {
                ast::FieldExpr(it) => {
                    if it.name_ref().is_none() {
                        // incomplete field access: some_expr.|
                        append.insert(node.clone().into(), vec![
                            Leaf::Ident(Ident {
                                sym: sym::__ra_fixup,
                                span: fake_span(node_range),
                                is_raw: tt::IdentIsRaw::No
                            }),
                        ]);
                    }
                },
                ast::ExprStmt(it) => {
                    let needs_semi = it.semicolon_token().is_none() && it.expr().is_some_and(|e| e.syntax().kind() != SyntaxKind::BLOCK_EXPR);
                    if needs_semi {
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: ';',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range),
                            }),
                        ]);
                    }
                },
                ast::LetStmt(it) => {
                    if it.semicolon_token().is_none() {
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: ';',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                        ]);
                    }
                },
                ast::IfExpr(it) => {
                    if it.condition().is_none() {
                        // insert placeholder token after the if token
                        let if_token = match it.if_token() {
                            Some(t) => t,
                            None => continue,
                        };
                        append.insert(if_token.into(), vec![
                            Leaf::Ident(Ident {
                                sym: sym::__ra_fixup,
                                span: fake_span(node_range),
                                is_raw: tt::IdentIsRaw::No
                            }),
                        ]);
                    }
                    if it.then_branch().is_none() {
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: '{',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                            Leaf::Punct(Punct {
                                char: '}',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                        ]);
                    }
                },
                ast::WhileExpr(it) => {
                    if it.condition().is_none() {
                        // insert placeholder token after the while token
                        let while_token = match it.while_token() {
                            Some(t) => t,
                            None => continue,
                        };
                        append.insert(while_token.into(), vec![
                            Leaf::Ident(Ident {
                                sym: sym::__ra_fixup,
                                span: fake_span(node_range),
                                is_raw: tt::IdentIsRaw::No
                            }),
                        ]);
                    }
                    if it.loop_body().is_none() {
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: '{',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                            Leaf::Punct(Punct {
                                char: '}',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                        ]);
                    }
                },
                ast::LoopExpr(it) => {
                    if it.loop_body().is_none() {
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: '{',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                            Leaf::Punct(Punct {
                                char: '}',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                        ]);
                    }
                },
                // FIXME: foo::
                ast::MatchExpr(it) => {
                    if it.expr().is_none() {
                        let match_token = match it.match_token() {
                            Some(t) => t,
                            None => continue
                        };
                        append.insert(match_token.into(), vec![
                            Leaf::Ident(Ident {
                                sym: sym::__ra_fixup,
                                span: fake_span(node_range),
                                is_raw: tt::IdentIsRaw::No
                            }),
                        ]);
                    }
                    if it.match_arm_list().is_none() {
                        // No match arms
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: '{',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                            Leaf::Punct(Punct {
                                char: '}',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                        ]);
                    }
                },
                ast::ForExpr(it) => {
                    let for_token = match it.for_token() {
                        Some(token) => token,
                        None => continue
                    };

                    let [pat, in_token, iter] = [
                         sym::underscore,
                         sym::in_,
                         sym::__ra_fixup,
                    ].map(|sym|
                        Leaf::Ident(Ident {
                            sym,
                            span: fake_span(node_range),
                            is_raw: tt::IdentIsRaw::No
                        }),
                    );

                    if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
                        append.insert(for_token.into(), vec![pat, in_token, iter]);
                    // does something funky -- see test case for_no_pat
                    } else if it.pat().is_none() {
                        append.insert(for_token.into(), vec![pat]);
                    }

                    if it.loop_body().is_none() {
                        append.insert(node.clone().into(), vec![
                            Leaf::Punct(Punct {
                                char: '{',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                            Leaf::Punct(Punct {
                                char: '}',
                                spacing: Spacing::Alone,
                                span: fake_span(node_range)
                            }),
                        ]);
                    }
                },
                ast::RecordExprField(it) => {
                    if let Some(colon) = it.colon_token() {
                        if it.name_ref().is_some() && it.expr().is_none() {
                            append.insert(colon.into(), vec![
                                Leaf::Ident(Ident {
                                    sym: sym::__ra_fixup,
                                    span: fake_span(node_range),
                                    is_raw: tt::IdentIsRaw::No
                                })
                            ]);
                        }
                    }
                },
                ast::Path(it) => {
                    if let Some(colon) = it.coloncolon_token() {
                        if it.segment().is_none() {
                            append.insert(colon.into(), vec![
                                Leaf::Ident(Ident {
                                    sym: sym::__ra_fixup,
                                    span: fake_span(node_range),
                                    is_raw: tt::IdentIsRaw::No
                                })
                            ]);
                        }
                    }
                },
                ast::ClosureExpr(it) => {
                    if it.body().is_none() {
                        append.insert(node.into(), vec![
                            Leaf::Ident(Ident {
                                sym: sym::__ra_fixup,
                                span: fake_span(node_range),
                                is_raw: tt::IdentIsRaw::No
                            })
                        ]);
                    }
                },
                _ => (),
            }
        }
    }
    let needs_fixups = !append.is_empty() || !original.is_empty();
    SyntaxFixups {
        append,
        remove,
        undo_info: SyntaxFixupUndoInfo {
            original: needs_fixups.then(|| Arc::new(original.into_boxed_slice())),
        },
    }
}

fn has_error(node: &SyntaxNode) -> bool {
    node.children().any(|c| c.kind() == SyntaxKind::ERROR)
}

fn can_handle_error(node: &SyntaxNode) -> bool {
    ast::Expr::can_cast(node.kind())
}

fn has_error_to_handle(node: &SyntaxNode) -> bool {
    has_error(node) || node.children().any(|c| !can_handle_error(&c) && has_error_to_handle(&c))
}

pub(crate) fn reverse_fixups(tt: &mut TopSubtree, undo_info: &SyntaxFixupUndoInfo) {
    let Some(undo_info) = undo_info.original.as_deref() else { return };
    let undo_info = &**undo_info;
    let delimiter = tt.top_subtree_delimiter_mut();
    #[allow(deprecated)]
    if never!(
        delimiter.close.anchor.ast_id == FIXUP_DUMMY_AST_ID
            || delimiter.open.anchor.ast_id == FIXUP_DUMMY_AST_ID
    ) {
        let span = |file_id| Span {
            range: TextRange::empty(TextSize::new(0)),
            anchor: SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID },
            ctx: SyntaxContext::root(span::Edition::Edition2015),
        };
        delimiter.open = span(delimiter.open.anchor.file_id);
        delimiter.close = span(delimiter.close.anchor.file_id);
    }
    reverse_fixups_(tt, undo_info);
}

#[derive(Debug)]
enum TransformTtAction<'a> {
    Keep,
    ReplaceWith(tt::TokenTreesView<'a>),
}

impl TransformTtAction<'_> {
    fn remove() -> Self {
        Self::ReplaceWith(tt::TokenTreesView::new(&[]))
    }
}

/// This function takes a token tree, and calls `callback` with each token tree in it.
/// Then it does what the callback says: keeps the tt or replaces it with a (possibly empty)
/// tts view.
fn transform_tt<'a, 'b>(
    tt: &'a mut Vec<tt::TokenTree>,
    mut callback: impl FnMut(&mut tt::TokenTree) -> TransformTtAction<'b>,
) {
    // We need to keep a stack of the currently open subtrees, because we need to update
    // them if we change the number of items in them.
    let mut subtrees_stack = Vec::new();
    let mut i = 0;
    while i < tt.len() {
        'pop_finished_subtrees: while let Some(&subtree_idx) = subtrees_stack.last() {
            let tt::TokenTree::Subtree(subtree) = &tt[subtree_idx] else {
                unreachable!("non-subtree on subtrees stack");
            };
            if i >= subtree_idx + 1 + subtree.usize_len() {
                subtrees_stack.pop();
            } else {
                break 'pop_finished_subtrees;
            }
        }

        let action = callback(&mut tt[i]);
        match action {
            TransformTtAction::Keep => {
                // This cannot be shared with the replaced case, because then we may push the same subtree
                // twice, and will update it twice which will lead to errors.
                if let tt::TokenTree::Subtree(_) = &tt[i] {
                    subtrees_stack.push(i);
                }

                i += 1;
            }
            TransformTtAction::ReplaceWith(replacement) => {
                let old_len = 1 + match &tt[i] {
                    tt::TokenTree::Leaf(_) => 0,
                    tt::TokenTree::Subtree(subtree) => subtree.usize_len(),
                };
                let len_diff = replacement.len() as i64 - old_len as i64;
                tt.splice(i..i + old_len, replacement.flat_tokens().iter().cloned());
                // Skip the newly inserted replacement, we don't want to visit it.
                i += replacement.len();

                for &subtree_idx in &subtrees_stack {
                    let tt::TokenTree::Subtree(subtree) = &mut tt[subtree_idx] else {
                        unreachable!("non-subtree on subtrees stack");
                    };
                    subtree.len = (i64::from(subtree.len) + len_diff).try_into().unwrap();
                }
            }
        }
    }
}

fn reverse_fixups_(tt: &mut TopSubtree, undo_info: &[TopSubtree]) {
    let mut tts = std::mem::take(&mut tt.0).into_vec();
    transform_tt(&mut tts, |tt| match tt {
        tt::TokenTree::Leaf(leaf) => {
            let span = leaf.span();
            let is_real_leaf = span.anchor.ast_id != FIXUP_DUMMY_AST_ID;
            let is_replaced_node = span.range.end() == FIXUP_DUMMY_RANGE_END;
            if !is_real_leaf && !is_replaced_node {
                return TransformTtAction::remove();
            }

            if !is_real_leaf {
                // we have a fake node here, we need to replace it again with the original
                let original = &undo_info[u32::from(leaf.span().range.start()) as usize];
                TransformTtAction::ReplaceWith(original.view().strip_invisible())
            } else {
                // just a normal leaf
                TransformTtAction::Keep
            }
        }
        tt::TokenTree::Subtree(tt) => {
            // fixup should only create matching delimiters, but proc macros
            // could just copy the span to one of the delimiters. We don't want
            // to leak the dummy ID, so we remove both.
            if tt.delimiter.close.anchor.ast_id == FIXUP_DUMMY_AST_ID
                || tt.delimiter.open.anchor.ast_id == FIXUP_DUMMY_AST_ID
            {
                return TransformTtAction::remove();
            }
            TransformTtAction::Keep
        }
    });
    tt.0 = tts.into_boxed_slice();
}

#[cfg(test)]
mod tests {
    use expect_test::{Expect, expect};
    use span::{Edition, EditionedFileId, FileId};
    use syntax::TextRange;
    use syntax_bridge::DocCommentDesugarMode;
    use triomphe::Arc;

    use crate::{
        fixup::reverse_fixups,
        span_map::{RealSpanMap, SpanMap},
        tt,
    };

    // The following three functions are only meant to check partial structural equivalence of
    // `TokenTree`s, see the last assertion in `check()`.
    fn check_leaf_eq(a: &tt::Leaf, b: &tt::Leaf) -> bool {
        match (a, b) {
            (tt::Leaf::Literal(a), tt::Leaf::Literal(b)) => a.symbol == b.symbol,
            (tt::Leaf::Punct(a), tt::Leaf::Punct(b)) => a.char == b.char,
            (tt::Leaf::Ident(a), tt::Leaf::Ident(b)) => a.sym == b.sym,
            _ => false,
        }
    }

    fn check_subtree_eq(a: &tt::TopSubtree, b: &tt::TopSubtree) -> bool {
        let a = a.view().as_token_trees().flat_tokens();
        let b = b.view().as_token_trees().flat_tokens();
        a.len() == b.len() && std::iter::zip(a, b).all(|(a, b)| check_tt_eq(a, b))
    }

    fn check_tt_eq(a: &tt::TokenTree, b: &tt::TokenTree) -> bool {
        match (a, b) {
            (tt::TokenTree::Leaf(a), tt::TokenTree::Leaf(b)) => check_leaf_eq(a, b),
            (tt::TokenTree::Subtree(a), tt::TokenTree::Subtree(b)) => {
                a.delimiter.kind == b.delimiter.kind
            }
            _ => false,
        }
    }

    #[track_caller]
    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, mut expect: Expect) {
        let parsed = syntax::SourceFile::parse(ra_fixture, span::Edition::CURRENT);
        let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(EditionedFileId::new(
            FileId::from_raw(0),
            Edition::CURRENT,
        ))));
        let fixups = super::fixup_syntax(
            span_map.as_ref(),
            &parsed.syntax_node(),
            span_map.span_for_range(TextRange::empty(0.into())),
            DocCommentDesugarMode::Mbe,
        );
        let mut tt = syntax_bridge::syntax_node_to_token_tree_modified(
            &parsed.syntax_node(),
            span_map.as_ref(),
            fixups.append,
            fixups.remove,
            span_map.span_for_range(TextRange::empty(0.into())),
            DocCommentDesugarMode::Mbe,
        );

        let actual = format!("{tt}\n");

        expect.indent(false);
        expect.assert_eq(&actual);

        // the fixed-up tree should be syntactically valid
        let (parse, _) = syntax_bridge::token_tree_to_syntax_node(
            &tt,
            syntax_bridge::TopEntryPoint::MacroItems,
            &mut |_| parser::Edition::CURRENT,
            parser::Edition::CURRENT,
        );
        assert!(
            parse.errors().is_empty(),
            "parse has syntax errors. parse tree:\n{:#?}",
            parse.syntax_node()
        );

        // the fixed-up tree should not contain braces as punct
        // FIXME: should probably instead check that it's a valid punctuation character
        for x in tt.token_trees().flat_tokens() {
            match x {
                ::tt::TokenTree::Leaf(::tt::Leaf::Punct(punct)) => {
                    assert!(!matches!(punct.char, '{' | '}' | '(' | ')' | '[' | ']'))
                }
                _ => (),
            }
        }

        reverse_fixups(&mut tt, &fixups.undo_info);

        // the fixed-up + reversed version should be equivalent to the original input
        // modulo token IDs and `Punct`s' spacing.
        let original_as_tt = syntax_bridge::syntax_node_to_token_tree(
            &parsed.syntax_node(),
            span_map.as_ref(),
            span_map.span_for_range(TextRange::empty(0.into())),
            DocCommentDesugarMode::Mbe,
        );
        assert!(
            check_subtree_eq(&tt, &original_as_tt),
            "different token tree:\n{tt:?}\n\n{original_as_tt:?}"
        );
    }

    #[test]
    fn just_for_token() {
        check(
            r#"
fn foo() {
    for
}
"#,
            expect![[r#"
fn foo () {for _ in __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn for_no_iter_pattern() {
        check(
            r#"
fn foo() {
    for {}
}
"#,
            expect![[r#"
fn foo () {for _ in __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn for_no_body() {
        check(
            r#"
fn foo() {
    for bar in qux
}
"#,
            expect![[r#"
fn foo () {for bar in qux {}}
"#]],
        )
    }

    // FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
    #[test]
    fn for_no_pat() {
        check(
            r#"
fn foo() {
    for in qux {

    }
}
"#,
            expect![[r#"
fn foo () {__ra_fixup}
"#]],
        )
    }

    #[test]
    fn match_no_expr_no_arms() {
        check(
            r#"
fn foo() {
    match
}
"#,
            expect![[r#"
fn foo () {match __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn match_expr_no_arms() {
        check(
            r#"
fn foo() {
    match it {

    }
}
"#,
            expect![[r#"
fn foo () {match it {}}
"#]],
        )
    }

    #[test]
    fn match_no_expr() {
        check(
            r#"
fn foo() {
    match {
        _ => {}
    }
}
"#,
            expect![[r#"
fn foo () {match __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn incomplete_field_expr_1() {
        check(
            r#"
fn foo() {
    a.
}
"#,
            expect![[r#"
fn foo () {a . __ra_fixup}
"#]],
        )
    }

    #[test]
    fn incomplete_field_expr_2() {
        check(
            r#"
fn foo() {
    a.;
}
"#,
            expect![[r#"
fn foo () {a . __ra_fixup ;}
"#]],
        )
    }

    #[test]
    fn incomplete_field_expr_3() {
        check(
            r#"
fn foo() {
    a.;
    bar();
}
"#,
            expect![[r#"
fn foo () {a . __ra_fixup ; bar () ;}
"#]],
        )
    }

    #[test]
    fn incomplete_let() {
        check(
            r#"
fn foo() {
    let it = a
}
"#,
            expect![[r#"
fn foo () {let it = a ;}
"#]],
        )
    }

    #[test]
    fn incomplete_field_expr_in_let() {
        check(
            r#"
fn foo() {
    let it = a.
}
"#,
            expect![[r#"
fn foo () {let it = a . __ra_fixup ;}
"#]],
        )
    }

    #[test]
    fn field_expr_before_call() {
        // another case that easily happens while typing
        check(
            r#"
fn foo() {
    a.b
    bar();
}
"#,
            expect![[r#"
fn foo () {a . b ; bar () ;}
"#]],
        )
    }

    #[test]
    fn extraneous_comma() {
        check(
            r#"
fn foo() {
    bar(,);
}
"#,
            expect![[r#"
fn foo () {__ra_fixup ;}
"#]],
        )
    }

    #[test]
    fn fixup_if_1() {
        check(
            r#"
fn foo() {
    if a
}
"#,
            expect![[r#"
fn foo () {if a {}}
"#]],
        )
    }

    #[test]
    fn fixup_if_2() {
        check(
            r#"
fn foo() {
    if
}
"#,
            expect![[r#"
fn foo () {if __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn fixup_if_3() {
        check(
            r#"
fn foo() {
    if {}
}
"#,
            expect![[r#"
fn foo () {if __ra_fixup {} {}}
"#]],
        )
    }

    #[test]
    fn fixup_while_1() {
        check(
            r#"
fn foo() {
    while
}
"#,
            expect![[r#"
fn foo () {while __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn fixup_while_2() {
        check(
            r#"
fn foo() {
    while foo
}
"#,
            expect![[r#"
fn foo () {while foo {}}
"#]],
        )
    }
    #[test]
    fn fixup_while_3() {
        check(
            r#"
fn foo() {
    while {}
}
"#,
            expect![[r#"
fn foo () {while __ra_fixup {}}
"#]],
        )
    }

    #[test]
    fn fixup_loop() {
        check(
            r#"
fn foo() {
    loop
}
"#,
            expect![[r#"
fn foo () {loop {}}
"#]],
        )
    }

    #[test]
    fn fixup_path() {
        check(
            r#"
fn foo() {
    path::
}
"#,
            expect![[r#"
fn foo () {path :: __ra_fixup}
"#]],
        )
    }

    #[test]
    fn fixup_record_ctor_field() {
        check(
            r#"
fn foo() {
    R { f: }
}
"#,
            expect![[r#"
fn foo () {R {f : __ra_fixup}}
"#]],
        )
    }

    #[test]
    fn no_fixup_record_ctor_field() {
        check(
            r#"
fn foo() {
    R { f: a }
}
"#,
            expect![[r#"
fn foo () {R {f : a}}
"#]],
        )
    }

    #[test]
    fn fixup_arg_list() {
        check(
            r#"
fn foo() {
    foo(a
}
"#,
            expect![[r#"
fn foo () {foo (a)}
"#]],
        );
        check(
            r#"
fn foo() {
    bar.foo(a
}
"#,
            expect![[r#"
fn foo () {bar . foo (a)}
"#]],
        );
    }

    #[test]
    fn fixup_closure() {
        check(
            r#"
fn foo() {
    ||
}
"#,
            expect![[r#"
fn foo () {|| __ra_fixup}
"#]],
        );
    }

    #[test]
    fn fixup_regression_() {
        check(
            r#"
fn foo() {
    {}
    {}
}
"#,
            expect![[r#"
fn foo () {{} {}}
"#]],
        );
    }
}
