//! These tests have been adapted from [Rust's parser tests][parser-tests].
//!
//! [parser-tests]: https://github.com/rust-lang/rust/blob/894f7a4ba6554d3797404bbf550d9919df060b97/compiler/rustc_parse/src/parser/tests.rs

use annotate_snippets::{AnnotationKind, Group, Level, Origin, Padding, Patch, Renderer, Snippet};

use annotate_snippets::renderer::DecorStyle;
use snapbox::{IntoData, assert_data_eq, str};

#[test]
fn ends_on_col0() {
    let source = r#"
fn foo() {
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(10..13).label("test")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:2:10
  |
2 |   fn foo() {
  |  __________^
3 | | }
  | |_^ test
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:2:10
  │
2 │   fn foo() {
  │ ┏━━━━━━━━━━┛
3 │ ┃ }
  ╰╴┗━┛ test
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn ends_on_col2() {
    let source = r#"
fn foo() {


  }
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(10..17).label("test")),
    )];
    let expected_ascii = str![[r#"
error: foo
 --> test.rs:2:10
  |
2 |   fn foo() {
  |  __________^
... |
5 | |   }
  | |___^ test
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:2:10
  │
2 │   fn foo() {
  │ ┏━━━━━━━━━━┛
  ┆ ┇
5 │ ┃   }
  ╰╴┗━━━┛ test
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn non_nested() {
    let source = r#"
fn foo() {
  X0 Y0
  X1 Y1
  X2 Y2
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..32)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(17..35)
                    .label("`Y` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |      X0 Y0
  |  ____^  -
  | | ______|
4 | ||   X1 Y1
5 | ||   X2 Y2
  | ||____^__- `Y` is a good letter too
  | |_____|
  |       `X` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │      X0 Y0
  │ ┏━━━━┛  │
  │ ┃┌──────┘
4 │ ┃│   X1 Y1
5 │ ┃│   X2 Y2
  │ ┃└────╿──┘ `Y` is a good letter too
  │ ┗━━━━━┥
  ╰╴      `X` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn nested() {
    let source = r#"
fn foo() {
  X0 Y0
  Y1 X1
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..27)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(17..24)
                    .label("`Y` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |      X0 Y0
  |  ____^  -
  | | ______|
4 | ||   Y1 X1
  | ||____-__^ `X` is a good letter
  |  |____|
  |       `Y` is a good letter too
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │      X0 Y0
  │ ┏━━━━┛  │
  │ ┃┌──────┘
4 │ ┃│   Y1 X1
  │ ┗│━━━━│━━┛ `X` is a good letter
  │  └────┤
  ╰╴      `Y` is a good letter too
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn different_overlap() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
  X2 Y2 Z2
  X3 Y3 Z3
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(17..38)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(31..49)
                    .label("`Y` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:6
  |
3 |      X0 Y0 Z0
  |  _______^
4 | |    X1 Y1 Z1
  | | _________-
5 | ||   X2 Y2 Z2
  | ||____^ `X` is a good letter
6 |  |   X3 Y3 Z3
  |  |____- `Y` is a good letter too
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:6
  │
3 │      X0 Y0 Z0
  │ ┏━━━━━━━┛
4 │ ┃    X1 Y1 Z1
  │ ┃┌─────────┘
5 │ ┃│   X2 Y2 Z2
  │ ┗│━━━━┛ `X` is a good letter
6 │  │   X3 Y3 Z3
  ╰╴ └────┘ `Y` is a good letter too
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn triple_overlap() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
  X2 Y2 Z2
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..38)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(17..41)
                    .label("`Y` is a good letter too"),
            )
            .annotation(AnnotationKind::Context.span(20..44).label("`Z` label")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |       X0 Y0 Z0
  |  _____^  -  -
  | | _______|  |
  | || _________|
4 | |||   X1 Y1 Z1
5 | |||   X2 Y2 Z2
  | |||____^__-__- `Z` label
  | ||_____|__|
  | |______|  `Y` is a good letter too
  |        `X` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │       X0 Y0 Z0
  │ ┏━━━━━┛  │  │
  │ ┃┌───────┘  │
  │ ┃│┌─────────┘
4 │ ┃││   X1 Y1 Z1
5 │ ┃││   X2 Y2 Z2
  │ ┃│└────╿──│──┘ `Z` label
  │ ┃└─────│──┤
  │ ┗━━━━━━┥  `Y` is a good letter too
  ╰╴       `X` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn triple_exact_overlap() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
  X2 Y2 Z2
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..38)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(14..38)
                    .label("`Y` is a good letter too"),
            )
            .annotation(AnnotationKind::Context.span(14..38).label("`Z` label")),
    )];

    // This should have a `^` but we currently don't support the idea of a
    // "primary" annotation, which would solve this
    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 | /   X0 Y0 Z0
4 | |   X1 Y1 Z1
5 | |   X2 Y2 Z2
  | |    ^
  | |    |
  | |    `X` is a good letter
  | |____`Y` is a good letter too
  |      `Z` label
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │ ┏   X0 Y0 Z0
4 │ ┃   X1 Y1 Z1
5 │ ┃   X2 Y2 Z2
  │ ┃    ╿
  │ ┃    │
  │ ┃    `X` is a good letter
  │ ┗━━━━`Y` is a good letter too
  ╰╴     `Z` label
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn minimum_depth() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
  X2 Y2 Z2
  X3 Y3 Z3
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(17..27)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(28..44)
                    .label("`Y` is a good letter too"),
            )
            .annotation(AnnotationKind::Context.span(36..52).label("`Z`")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:6
  |
3 |      X0 Y0 Z0
  |  _______^
4 | |    X1 Y1 Z1
  | | ____^_-
  | ||____|
  |  |    `X` is a good letter
5 |  |   X2 Y2 Z2
  |  |___-______- `Y` is a good letter too
  |   ___|
  |  |
6 |  |   X3 Y3 Z3
  |  |_______- `Z`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:6
  │
3 │      X0 Y0 Z0
  │ ┏━━━━━━━┛
4 │ ┃    X1 Y1 Z1
  │ ┃┌────╿─┘
  │ ┗│━━━━┥
  │  │    `X` is a good letter
5 │  │   X2 Y2 Z2
  │  └───│──────┘ `Y` is a good letter too
  │  ┌───┘
  │  │
6 │  │   X3 Y3 Z3
  ╰╴ └───────┘ `Z`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn non_overlapping() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
  X2 Y2 Z2
  X3 Y3 Z3
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..27)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(39..55)
                    .label("`Y` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 | /   X0 Y0 Z0
4 | |   X1 Y1 Z1
  | |____^ `X` is a good letter
5 |     X2 Y2 Z2
  |  ______-
6 | |   X3 Y3 Z3
  | |__________- `Y` is a good letter too
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │ ┏   X0 Y0 Z0
4 │ ┃   X1 Y1 Z1
  │ ┗━━━━┛ `X` is a good letter
5 │     X2 Y2 Z2
  │ ┌──────┘
6 │ │   X3 Y3 Z3
  ╰╴└──────────┘ `Y` is a good letter too
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn overlapping_start_and_end() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
  X2 Y2 Z2
  X3 Y3 Z3
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(17..27)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(31..55)
                    .label("`Y` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:6
  |
3 |      X0 Y0 Z0
  |  _______^
4 | |    X1 Y1 Z1
  | | ____^____-
  | ||____|
  |  |    `X` is a good letter
5 |  |   X2 Y2 Z2
6 |  |   X3 Y3 Z3
  |  |__________- `Y` is a good letter too
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:6
  │
3 │      X0 Y0 Z0
  │ ┏━━━━━━━┛
4 │ ┃    X1 Y1 Z1
  │ ┃┌────╿────┘
  │ ┗│━━━━┥
  │  │    `X` is a good letter
5 │  │   X2 Y2 Z2
6 │  │   X3 Y3 Z3
  ╰╴ └──────────┘ `Y` is a good letter too
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_primary_without_message() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(18..25).label(""))
            .annotation(
                AnnotationKind::Context
                    .span(14..27)
                    .label("`a` is a good letter"),
            )
            .annotation(AnnotationKind::Context.span(22..23).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:7
  |
3 |   a { b { c } d }
  |   ----^^^^-^^-- `a` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:7
  │
3 │   a { b { c } d }
  ╰╴  ────━━━━─━━── `a` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_secondary_without_message() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..27)
                    .label("`a` is a good letter"),
            )
            .annotation(AnnotationKind::Context.span(18..25).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a { b { c } d }
  |   ^^^^-------^^ `a` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a { b { c } d }
  ╰╴  ━━━━───────━━ `a` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_primary_without_message_2() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(18..25)
                    .label("`b` is a good letter"),
            )
            .annotation(AnnotationKind::Context.span(14..27).label(""))
            .annotation(AnnotationKind::Context.span(22..23).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:7
  |
3 |   a { b { c } d }
  |   ----^^^^-^^--
  |       |
  |       `b` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:7
  │
3 │   a { b { c } d }
  │   ────┯━━━─━━──
  │       │
  ╰╴      `b` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_secondary_without_message_2() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(14..27).label(""))
            .annotation(
                AnnotationKind::Context
                    .span(18..25)
                    .label("`b` is a good letter"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a { b { c } d }
  |   ^^^^-------^^
  |       |
  |       `b` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a { b { c } d }
  │   ━━━━┬──────━━
  │       │
  ╰╴      `b` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_secondary_without_message_3() {
    let source = r#"
fn foo() {
  a  bc  d
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..18)
                    .label("`a` is a good letter"),
            )
            .annotation(AnnotationKind::Context.span(18..22).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a  bc  d
  |   ^^^^----
  |   |
  |   `a` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a  bc  d
  │   ┯━━━────
  │   │
  ╰╴  `a` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_without_message() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(14..27).label(""))
            .annotation(AnnotationKind::Context.span(18..25).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a { b { c } d }
  |   ^^^^-------^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a { b { c } d }
  ╰╴  ━━━━───────━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_without_message_2() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(18..25).label(""))
            .annotation(AnnotationKind::Context.span(14..27).label(""))
            .annotation(AnnotationKind::Context.span(22..23).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:7
  |
3 |   a { b { c } d }
  |   ----^^^^-^^--
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:7
  │
3 │   a { b { c } d }
  ╰╴  ────━━━━─━━──
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn multiple_labels_with_message() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..27)
                    .label("`a` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(18..25)
                    .label("`b` is a good letter"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a { b { c } d }
  |   ^^^^-------^^
  |   |   |
  |   |   `b` is a good letter
  |   `a` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a { b { c } d }
  │   ┯━━━┬──────━━
  │   │   │
  │   │   `b` is a good letter
  ╰╴  `a` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn ingle_label_with_message() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(14..27)
                    .label("`a` is a good letter"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a { b { c } d }
  |   ^^^^^^^^^^^^^ `a` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a { b { c } d }
  ╰╴  ━━━━━━━━━━━━━ `a` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn single_label_without_message() {
    let source = r#"
fn foo() {
  a { b { c } d }
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(AnnotationKind::Primary.span(14..27).label("")),
    )];

    let expected_ascii = str![[r#"
error: foo
 --> test.rs:3:3
  |
3 |   a { b { c } d }
  |   ^^^^^^^^^^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
  ╭▸ test.rs:3:3
  │
3 │   a { b { c } d }
  ╰╴  ━━━━━━━━━━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn long_snippet() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
  X1 Y1 Z1
1
2
3
4
5
6
7
8
9
10
  X2 Y2 Z2
  X3 Y3 Z3
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(17..27)
                    .label("`X` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(31..76)
                    .label("`Y` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
  --> test.rs:3:6
   |
 3 |      X0 Y0 Z0
   |  _______^
 4 | |    X1 Y1 Z1
   | | ____^____-
   | ||____|
   |  |    `X` is a good letter
 5 |  | 1
 6 |  | 2
 7 |  | 3
...   |
15 |  |   X2 Y2 Z2
16 |  |   X3 Y3 Z3
   |  |__________- `Y` is a good letter too
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
   ╭▸ test.rs:3:6
   │
 3 │      X0 Y0 Z0
   │ ┏━━━━━━━┛
 4 │ ┃    X1 Y1 Z1
   │ ┃┌────╿────┘
   │ ┗│━━━━┥
   │  │    `X` is a good letter
 5 │  │ 1
 6 │  │ 2
 7 │  │ 3
   ┆  ┆
15 │  │   X2 Y2 Z2
16 │  │   X3 Y3 Z3
   ╰╴ └──────────┘ `Y` is a good letter too
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}
#[test]
fn long_snippet_multiple_spans() {
    let source = r#"
fn foo() {
  X0 Y0 Z0
1
2
3
  X1 Y1 Z1
4
5
6
  X2 Y2 Z2
7
8
9
10
  X3 Y3 Z3
}
"#;
    let input = &[Level::ERROR.primary_title("foo").element(
        Snippet::source(source)
            .line_start(1)
            .path("test.rs")
            .annotation(
                AnnotationKind::Primary
                    .span(17..73)
                    .label("`Y` is a good letter"),
            )
            .annotation(
                AnnotationKind::Context
                    .span(37..56)
                    .label("`Z` is a good letter too"),
            ),
    )];

    let expected_ascii = str![[r#"
error: foo
  --> test.rs:3:6
   |
 3 |      X0 Y0 Z0
   |  _______^
 4 | |  1
 5 | |  2
 6 | |  3
 7 | |    X1 Y1 Z1
   | | _________-
 8 | || 4
 9 | || 5
10 | || 6
11 | ||   X2 Y2 Z2
   | ||__________- `Z` is a good letter too
...  |
15 | |  10
16 | |    X3 Y3 Z3
   | |________^ `Y` is a good letter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: foo
   ╭▸ test.rs:3:6
   │
 3 │      X0 Y0 Z0
   │ ┏━━━━━━━┛
 4 │ ┃  1
 5 │ ┃  2
 6 │ ┃  3
 7 │ ┃    X1 Y1 Z1
   │ ┃┌─────────┘
 8 │ ┃│ 4
 9 │ ┃│ 5
10 │ ┃│ 6
11 │ ┃│   X2 Y2 Z2
   │ ┃└──────────┘ `Z` is a good letter too
   ┆ ┇
15 │ ┃  10
16 │ ┃    X3 Y3 Z3
   ╰╴┗━━━━━━━━┛ `Y` is a good letter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn issue_91334() {
    let source = r#"// Regression test for the ICE described in issue #91334.

//@ error-pattern: this file contains an unclosed delimiter

#![feature(coroutines)]

fn f(){||yield(((){),
"#;
    let input = &[Level::ERROR
        .primary_title("this file contains an unclosed delimiter")
        .element(
            Snippet::source(source)
                .line_start(1)
                .path("$DIR/issue-91334.rs")
                .annotation(
                    AnnotationKind::Context
                        .span(151..152)
                        .label("unclosed delimiter"),
                )
                .annotation(
                    AnnotationKind::Context
                        .span(159..160)
                        .label("unclosed delimiter"),
                )
                .annotation(
                    AnnotationKind::Context
                        .span(164..164)
                        .label("missing open `(` for this delimiter"),
                )
                .annotation(AnnotationKind::Primary.span(167..167)),
        )];
    let expected_ascii = str![[r#"
error: this file contains an unclosed delimiter
 --> $DIR/issue-91334.rs:7:23
  |
7 | fn f(){||yield(((){),
  |       -       -    - ^
  |       |       |    |
  |       |       |    missing open `(` for this delimiter
  |       |       unclosed delimiter
  |       unclosed delimiter
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: this file contains an unclosed delimiter
  ╭▸ $DIR/issue-91334.rs:7:23
  │
7 │ fn f(){||yield(((){),
  │       ┬       ┬    ┬ ━
  │       │       │    │
  │       │       │    missing open `(` for this delimiter
  │       │       unclosed delimiter
  ╰╴      unclosed delimiter
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn issue_114529_illegal_break_with_value() {
    // tests/ui/typeck/issue-114529-illegal-break-with-value.rs
    let source = r#"// Regression test for issue #114529
// Tests that we do not ICE during const eval for a
// break-with-value in contexts where it is illegal

#[allow(while_true)]
fn main() {
    [(); {
        while true {
            break 9; //~ ERROR `break` with value from a `while` loop
        };
        51
    }];

    [(); {
        while let Some(v) = Some(9) {
            break v; //~ ERROR `break` with value from a `while` loop
        };
        51
    }];

    while true {
        break (|| { //~ ERROR `break` with value from a `while` loop
            let local = 9;
        });
    }
}
"#;
    let input = &[
        Level::ERROR
            .primary_title("`break` with value from a `while` loop")
            .id("E0571")
            .element(
                Snippet::source(source)
                    .line_start(1)
                    .path("$DIR/issue-114529-illegal-break-with-value.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(483..581)
                            .label("can only break with a value inside `loop` or breakable block"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(462..472)
                            .label("you can't `break` with a value in a `while` loop"),
                    ),
            ),
        Level::HELP
            .secondary_title("use `break` on its own without a value inside this `while` loop")
            .element(
                Snippet::source(source)
                    .line_start(1)
                    .path("$DIR/issue-114529-illegal-break-with-value.rs")
                    .annotation(AnnotationKind::Context.span(483..581).label("break")),
            ),
    ];
    let expected_ascii = str![[r#"
error[E0571]: `break` with value from a `while` loop
  --> $DIR/issue-114529-illegal-break-with-value.rs:22:9
   |
21 |       while true {
   |       ---------- you can't `break` with a value in a `while` loop
22 | /         break (|| { //~ ERROR `break` with value from a `while` loop
23 | |             let local = 9;
24 | |         });
   | |__________^ can only break with a value inside `loop` or breakable block
   |
help: use `break` on its own without a value inside this `while` loop
  --> $DIR/issue-114529-illegal-break-with-value.rs:22:9
   |
22 | /         break (|| { //~ ERROR `break` with value from a `while` loop
23 | |             let local = 9;
24 | |         });
   | |__________- break
"#]];

    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0571]: `break` with value from a `while` loop
   ╭▸ $DIR/issue-114529-illegal-break-with-value.rs:22:9
   │
21 │       while true {
   │       ────────── you can't `break` with a value in a `while` loop
22 │ ┏         break (|| { //~ ERROR `break` with value from a `while` loop
23 │ ┃             let local = 9;
24 │ ┃         });
   │ ┗━━━━━━━━━━┛ can only break with a value inside `loop` or breakable block
   ╰╴
help: use `break` on its own without a value inside this `while` loop
   ╭▸ $DIR/issue-114529-illegal-break-with-value.rs:22:9
   │
22 │ ┌         break (|| { //~ ERROR `break` with value from a `while` loop
23 │ │             let local = 9;
24 │ │         });
   ╰╴└──────────┘ break
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn primitive_reprs_should_have_correct_length() {
    // tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
    let source = r#"//! An enum with a primitive repr should have exactly the size of that primitive.

#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]

mod assert {
    use std::mem::{Assume, TransmuteFrom};

    pub fn is_transmutable<Src, Dst>()
    where
        Dst: TransmuteFrom<Src, {
            Assume {
                alignment: true,
                lifetimes: true,
                safety: true,
                validity: true,
            }
        }>
    {}
}

#[repr(C)]
struct Zst;

#[derive(Clone, Copy)]
#[repr(i8)] enum V0i8 { V }
#[repr(u8)] enum V0u8 { V }
#[repr(i16)] enum V0i16 { V }
#[repr(u16)] enum V0u16 { V }
#[repr(i32)] enum V0i32 { V }
#[repr(u32)] enum V0u32 { V }
#[repr(i64)] enum V0i64 { V }
#[repr(u64)] enum V0u64 { V }
#[repr(isize)] enum V0isize { V }
#[repr(usize)] enum V0usize { V }

fn n8() {
    type Smaller = Zst;
    type Analog = u8;
    type Larger = u16;

    fn i_should_have_correct_length() {
        type Current = V0i8;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }

    fn u_should_have_correct_length() {
        type Current = V0u8;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }
}

fn n16() {
    type Smaller = u8;
    type Analog = u16;
    type Larger = u32;

    fn i_should_have_correct_length() {
        type Current = V0i16;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }

    fn u_should_have_correct_length() {
        type Current = V0u16;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }
}

fn n32() {
    type Smaller = u16;
    type Analog = u32;
    type Larger = u64;

    fn i_should_have_correct_length() {
        type Current = V0i32;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }

    fn u_should_have_correct_length() {
        type Current = V0u32;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }
}

fn n64() {
    type Smaller = u32;
    type Analog = u64;
    type Larger = u128;

    fn i_should_have_correct_length() {
        type Current = V0i64;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }

    fn u_should_have_correct_length() {
        type Current = V0u64;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }
}

fn nsize() {
    type Smaller = u8;
    type Analog = usize;
    type Larger = [usize; 2];

    fn i_should_have_correct_length() {
        type Current = V0isize;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }

    fn u_should_have_correct_length() {
        type Current = V0usize;

        assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
        assert::is_transmutable::<Current, Analog>();
        assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    }
}
"#;
    let input =
        &[
            Level::ERROR
                .primary_title("`V0usize` cannot be safely transmuted into `[usize; 2]`")
                .id("E0277")
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/primitive_reprs_should_have_correct_length.rs")
                        .annotation(AnnotationKind::Primary.span(4375..4381).label(
                            "the size of `V0usize` is smaller than the size of `[usize; 2]`",
                        )),
                ),
            Level::NOTE
                .secondary_title("required by a bound in `is_transmutable`")
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/primitive_reprs_should_have_correct_length.rs")
                        .annotation(
                            AnnotationKind::Context
                                .span(225..240)
                                .label("required by a bound in this function"),
                        )
                        .annotation(
                            AnnotationKind::Primary
                                .span(276..470)
                                .label("required by this bound in `is_transmutable`"),
                        ),
                ),
        ];
    let expected_ascii = str![[r#"
error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44
    |
144 |         assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    |                                            ^^^^^^ the size of `V0usize` is smaller than the size of `[usize; 2]`
    |
note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    |
 10 |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 11 |       where
 12 |           Dst: TransmuteFrom<Src, {
    |  ______________^
 13 | |             Assume {
 14 | |                 alignment: true,
 15 | |                 lifetimes: true,
...   |
 19 | |         }>
    | |__________^ required by this bound in `is_transmutable`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]`
    ╭▸ $DIR/primitive_reprs_should_have_correct_length.rs:144:44
    │
144 │         assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
    │                                            ━━━━━━ the size of `V0usize` is smaller than the size of `[usize; 2]`
    ╰╴
note: required by a bound in `is_transmutable`
    ╭▸ $DIR/primitive_reprs_should_have_correct_length.rs:12:14
    │
 10 │       pub fn is_transmutable<Src, Dst>()
    │              ─────────────── required by a bound in this function
 11 │       where
 12 │           Dst: TransmuteFrom<Src, {
    │ ┏━━━━━━━━━━━━━━┛
 13 │ ┃             Assume {
 14 │ ┃                 alignment: true,
 15 │ ┃                 lifetimes: true,
    ┆ ┇
 19 │ ┃         }>
    ╰╴┗━━━━━━━━━━┛ required by this bound in `is_transmutable`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn align_fail() {
    // tests/ui/transmutability/alignment/align-fail.rs
    let source = r#"//@ check-fail
#![feature(transmutability)]

mod assert {
    use std::mem::{Assume, TransmuteFrom};

    pub fn is_maybe_transmutable<Src, Dst>()
    where
        Dst: TransmuteFrom<Src, {
            Assume {
                alignment: false,
                lifetimes: true,
                safety: true,
                validity: true,
            }
        }>
    {}
}

fn main() {
    assert::is_maybe_transmutable::<&'static [u8; 0], &'static [u16; 0]>(); //~ ERROR `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
}
"#;
    let input = &[Level::ERROR
        .primary_title("`&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`")
        .id("E027s7").element(
                Snippet::source(source)
                    .line_start(1)

                    .path("$DIR/align-fail.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(442..459)
                            .label("the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2)")
                    ),
            )];
    let expected_ascii = str![[r#"
error[E027s7]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
  --> $DIR/align-fail.rs:21:55
   |
21 | ...ic [u8; 0], &'static [u16; 0]>(); //~ ERROR `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
   |                ^^^^^^^^^^^^^^^^^ the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2)
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E027s7]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
   ╭▸ $DIR/align-fail.rs:21:55
   │
21 │ …atic [u8; 0], &'static [u16; 0]>(); //~ ERROR `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
   ╰╴               ━━━━━━━━━━━━━━━━━ the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2)
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn missing_semicolon() {
    // tests/ui/suggestions/missing-semicolon.rs
    let source = r#"//@ run-rustfix
#![allow(dead_code, unused_variables, path_statements)]
fn a() {
    let x = 5;
    let y = x //~ ERROR expected function
    () //~ ERROR expected `;`, found `}`
}

fn b() {
    let x = 5;
    let y = x //~ ERROR expected function
    ();
}
fn c() {
    let x = 5;
    x //~ ERROR expected function
    ()
}
fn d() { // ok
    let x = || ();
    x
    ()
}
fn e() { // ok
    let x = || ();
    x
    ();
}
fn f()
 {
    let y = 5 //~ ERROR expected function
    () //~ ERROR expected `;`, found `}`
}
fn g() {
    5 //~ ERROR expected function
    ();
}
fn main() {}
"#;
    let input =
        &[Level::ERROR
            .primary_title("expected function, found `{integer}`")
            .id("E0618")
            .element(
                Snippet::source(source)
                    .line_start(1)
                    .path("$DIR/missing-semicolon.rs")
                    .annotation(
                        AnnotationKind::Context
                            .span(108..144)
                            .label("call expression requires function"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(89..90)
                            .label("`x` has type `{integer}`"),
                    )
                    .annotation(AnnotationKind::Context.span(109..109).label(
                        "help: consider using a semicolon here to finish the statement: `;`",
                    ))
                    .annotation(AnnotationKind::Primary.span(108..109)),
            )];
    let expected_ascii = str![[r#"
error[E0618]: expected function, found `{integer}`
 --> $DIR/missing-semicolon.rs:5:13
  |
4 |       let x = 5;
  |           - `x` has type `{integer}`
5 |       let y = x //~ ERROR expected function
  |               ^- help: consider using a semicolon here to finish the statement: `;`
  |  _____________|
  | |
6 | |     () //~ ERROR expected `;`, found `}`
  | |______- call expression requires function
"#]];

    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0618]: expected function, found `{integer}`
  ╭▸ $DIR/missing-semicolon.rs:5:13
  │
4 │       let x = 5;
  │           ─ `x` has type `{integer}`
5 │       let y = x //~ ERROR expected function
  │               ━─ help: consider using a semicolon here to finish the statement: `;`
  │ ┌─────────────┘
  │ │
6 │ │     () //~ ERROR expected `;`, found `}`
  ╰╴└──────┘ call expression requires function
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn nested_macro_rules() {
    // tests/ui/proc-macro/nested-macro-rules.rs
    let source = r#"//@ run-pass
//@ aux-build:nested-macro-rules.rs
//@ proc-macro: test-macros.rs
//@ compile-flags: -Z span-debug -Z macro-backtrace
//@ edition:2018

#![no_std] // Don't load unnecessary hygiene information from std
#![warn(non_local_definitions)]

extern crate std;

extern crate nested_macro_rules;
extern crate test_macros;

use test_macros::{print_bang, print_attr};

use nested_macro_rules::FirstStruct;
struct SecondStruct;

fn main() {
    nested_macro_rules::inner_macro!(print_bang, print_attr);

    nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
    //~^ WARN non-local `macro_rules!` definition
    inner_macro!(print_bang, print_attr);
}
"#;

    let aux_source = r#"pub struct FirstStruct;

#[macro_export]
macro_rules! outer_macro {
    ($name:ident, $attr_struct_name:ident) => {
        #[macro_export]
        macro_rules! inner_macro {
            ($bang_macro:ident, $attr_macro:ident) => {
                $bang_macro!($name);
                #[$attr_macro] struct $attr_struct_name {}
            }
        }
    }
}

outer_macro!(FirstStruct, FirstAttrStruct);
"#;
    let input =
           &[ Level::WARNING
                .primary_title("non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module")
                .element(
                    Snippet::source(aux_source)
                        .line_start(1)
                        .path("$DIR/auxiliary/nested-macro-rules.rs")

                        .annotation(
                            AnnotationKind::Context
                                .span(41..65)
                                .label("in this expansion of `nested_macro_rules::outer_macro!`"),
                        )
                        .annotation(AnnotationKind::Primary.span(148..350)),
                )
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/nested-macro-rules.rs")

                        .annotation(
                            AnnotationKind::Context
                                .span(510..574)
                                .label("in this macro invocation"),
                        ),
                )
                .element(
                    Level::HELP
                        .message("remove the `#[macro_export]` or move this `macro_rules!` outside the of the current function `main`")
                )
                .element(
                    Level::NOTE
                        .message("a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute")
                ),
            Level::NOTE.secondary_title("the lint level is defined here")
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/nested-macro-rules.rs")

                        .annotation(AnnotationKind::Primary.span(224..245)),
                )];
    let expected_ascii = str![[r#"
warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
  --> $DIR/auxiliary/nested-macro-rules.rs:7:9
   |
 4 |   macro_rules! outer_macro {
   |   ------------------------ in this expansion of `nested_macro_rules::outer_macro!`
...
 7 | /         macro_rules! inner_macro {
 8 | |             ($bang_macro:ident, $attr_macro:ident) => {
 9 | |                 $bang_macro!($name);
10 | |                 #[$attr_macro] struct $attr_struct_name {}
11 | |             }
12 | |         }
   | |_________^
   |
  ::: $DIR/nested-macro-rules.rs:23:5
   |
23 |       nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
   |       ---------------------------------------------------------------- in this macro invocation
   |
   = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current function `main`
   = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
note: the lint level is defined here
  --> $DIR/nested-macro-rules.rs:8:9
   |
 8 | #![warn(non_local_definitions)]
   |         ^^^^^^^^^^^^^^^^^^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   ╭▸ $DIR/auxiliary/nested-macro-rules.rs:7:9
   │
 4 │   macro_rules! outer_macro {
   │   ──────────────────────── in this expansion of `nested_macro_rules::outer_macro!`
   ┆
 7 │ ┏         macro_rules! inner_macro {
 8 │ ┃             ($bang_macro:ident, $attr_macro:ident) => {
 9 │ ┃                 $bang_macro!($name);
10 │ ┃                 #[$attr_macro] struct $attr_struct_name {}
11 │ ┃             }
12 │ ┃         }
   │ ┗━━━━━━━━━┛
   │
   ⸬  $DIR/nested-macro-rules.rs:23:5
   │
23 │       nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
   │       ──────────────────────────────────────────────────────────────── in this macro invocation
   │
   ├ help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current function `main`
   ╰ note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
note: the lint level is defined here
   ╭▸ $DIR/nested-macro-rules.rs:8:9
   │
 8 │ #![warn(non_local_definitions)]
   ╰╴        ━━━━━━━━━━━━━━━━━━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn method_on_ambiguous_numeric_type() {
    // tests/ui/methods/method-on-ambiguous-numeric-type.rs
    let source = r#"//@ aux-build:macro-in-other-crate.rs

#[macro_use] extern crate macro_in_other_crate;

macro_rules! local_mac {
    ($ident:ident) => { let $ident = 42; }
}
macro_rules! local_mac_tt {
    ($tt:tt) => { let $tt = 42; }
}

fn main() {
    let x = 2.0.neg();
    //~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`

    let y = 2.0;
    let x = y.neg();
    //~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
    println!("{:?}", x);

    for i in 0..100 {
        println!("{}", i.pow(2));
        //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
    }

    local_mac!(local_bar);
    local_bar.pow(2);
    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`

    local_mac_tt!(local_bar_tt);
    local_bar_tt.pow(2);
    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
}

fn qux() {
    mac!(bar);
    bar.pow(2);
    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
}
"#;

    let aux_source = r#"#[macro_export]
macro_rules! mac {
    ($ident:ident) => { let $ident = 42; }
}

#[macro_export]
macro_rules! inline {
    () => ()
}
"#;
    let input = &[
        Level::ERROR
            .primary_title("can't call method `pow` on ambiguous numeric type `{integer}`")
            .id("E0689")
            .element(
                Snippet::source(source)
                    .line_start(1)
                    .path("$DIR/method-on-ambiguous-numeric-type.rs")
                    .annotation(AnnotationKind::Primary.span(916..919)),
            ),
        Level::HELP
            .secondary_title("you must specify a type for this binding, like `i32`")
            .element(
                Snippet::source(aux_source)
                    .line_start(1)
                    .path("$DIR/auxiliary/macro-in-other-crate.rs")
                    .annotation(AnnotationKind::Context.span(69..69).label(": i32")),
            ),
    ];
    let expected_ascii = str![[r#"
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
  --> $DIR/method-on-ambiguous-numeric-type.rs:37:9
   |
37 |     bar.pow(2);
   |         ^^^
   |
help: you must specify a type for this binding, like `i32`
  --> $DIR/auxiliary/macro-in-other-crate.rs:3:35
   |
 3 |     ($ident:ident) => { let $ident = 42; }
   |                                   - : i32
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
   ╭▸ $DIR/method-on-ambiguous-numeric-type.rs:37:9
   │
37 │     bar.pow(2);
   │         ━━━
   ╰╴
help: you must specify a type for this binding, like `i32`
   ╭▸ $DIR/auxiliary/macro-in-other-crate.rs:3:35
   │
 3 │     ($ident:ident) => { let $ident = 42; }
   ╰╴                                  ─ : i32
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn issue_42234_unknown_receiver_type() {
    // tests/ui/span/issue-42234-unknown-receiver-type.rs
    let source = r#"//@ revisions: full generic_arg
#![cfg_attr(generic_arg, feature(generic_arg_infer))]

// When the type of a method call's receiver is unknown, the span should point
// to the receiver (and not the entire call, as was previously the case before
// the fix of which this tests).

fn shines_a_beacon_through_the_darkness() {
    let x: Option<_> = None; //~ ERROR type annotations needed
    x.unwrap().method_that_could_exist_on_some_type();
}

fn courier_to_des_moines_and_points_west(data: &[u32]) -> String {
    data.iter()
        .sum::<_>() //~ ERROR type annotations needed
        .to_string()
}

fn main() {}
"#;

    let input = &[Level::ERROR
        .primary_title("type annotations needed")
        .id("E0282")
        .element(
            Snippet::source(source)
                .line_start(1)
                .path("$DIR/issue-42234-unknown-receiver-type.rs")
                .annotation(AnnotationKind::Primary.span(536..539).label(
                    "cannot infer type of the type parameter `S` declared on the method `sum`",
                )),
        )];
    let expected_ascii = str![[r#"
error[E0282]: type annotations needed
  --> $DIR/issue-42234-unknown-receiver-type.rs:15:10
   |
15 |         .sum::<_>() //~ ERROR type annotations needed
   |          ^^^ cannot infer type of the type parameter `S` declared on the method `sum`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0282]: type annotations needed
   ╭▸ $DIR/issue-42234-unknown-receiver-type.rs:15:10
   │
15 │         .sum::<_>() //~ ERROR type annotations needed
   ╰╴         ━━━ cannot infer type of the type parameter `S` declared on the method `sum`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn pattern_usefulness_empty_match() {
    // tests/ui/pattern/usefulness/empty-match.rs
    let source = r##"//@ revisions: normal exhaustive_patterns
//
// This tests a match with no arms on various types.
#![feature(never_type)]
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![deny(unreachable_patterns)]

fn nonempty<const N: usize>(arrayN_of_empty: [!; N]) {
    macro_rules! match_no_arms {
        ($e:expr) => {
            match $e {}
        };
    }
    macro_rules! match_guarded_arm {
        ($e:expr) => {
            match $e {
                _ if false => {}
            }
        };
    }

    struct NonEmptyStruct1;
    struct NonEmptyStruct2(bool);
    union NonEmptyUnion1 {
        foo: (),
    }
    union NonEmptyUnion2 {
        foo: (),
        bar: !,
    }
    enum NonEmptyEnum1 {
        Foo(bool),
    }
    enum NonEmptyEnum2 {
        Foo(bool),
        Bar,
    }
    enum NonEmptyEnum5 {
        V1,
        V2,
        V3,
        V4,
        V5,
    }
    let array0_of_empty: [!; 0] = [];

    match_no_arms!(0u8); //~ ERROR type `u8` is non-empty
    match_no_arms!(0i8); //~ ERROR type `i8` is non-empty
    match_no_arms!(0usize); //~ ERROR type `usize` is non-empty
    match_no_arms!(0isize); //~ ERROR type `isize` is non-empty
    match_no_arms!(NonEmptyStruct1); //~ ERROR type `NonEmptyStruct1` is non-empty
    match_no_arms!(NonEmptyStruct2(true)); //~ ERROR type `NonEmptyStruct2` is non-empty
    match_no_arms!((NonEmptyUnion1 { foo: () })); //~ ERROR type `NonEmptyUnion1` is non-empty
    match_no_arms!((NonEmptyUnion2 { foo: () })); //~ ERROR type `NonEmptyUnion2` is non-empty
    match_no_arms!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
    match_no_arms!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
    match_no_arms!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
    match_no_arms!(array0_of_empty); //~ ERROR type `[!; 0]` is non-empty
    match_no_arms!(arrayN_of_empty); //~ ERROR type `[!; N]` is non-empty

    match_guarded_arm!(0u8); //~ ERROR `0_u8..=u8::MAX` not covered
    match_guarded_arm!(0i8); //~ ERROR `i8::MIN..=i8::MAX` not covered
    match_guarded_arm!(0usize); //~ ERROR `0_usize..` not covered
    match_guarded_arm!(0isize); //~ ERROR `_` not covered
    match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered
    match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered
    match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered
    match_guarded_arm!((NonEmptyUnion2 { foo: () })); //~ ERROR `NonEmptyUnion2 { .. }` not covered
    match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
    match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
    match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
    match_guarded_arm!(array0_of_empty); //~ ERROR `[]` not covered
    match_guarded_arm!(arrayN_of_empty); //~ ERROR `[]` not covered
}

fn main() {}
"##;

    let input =
           &[Level::ERROR
                .primary_title(
                    "non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered"
                )
                .id("E0004")
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/empty-match.rs")

                        .annotation(
                            AnnotationKind::Primary
                                .span(2911..2928)
                                .label("patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered")
                        ),
                ),
            Level::NOTE.secondary_title("`NonEmptyEnum5` defined here")
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/empty-match.rs")

                        .annotation(AnnotationKind::Primary.span(818..831))
                        .annotation(AnnotationKind::Context.span(842..844).label("not covered"))
                        .annotation(AnnotationKind::Context.span(854..856).label("not covered"))
                        .annotation(AnnotationKind::Context.span(866..868).label("not covered"))
                        .annotation(AnnotationKind::Context.span(878..880).label("not covered"))
                        .annotation(AnnotationKind::Context.span(890..892).label("not covered"))
                )
                .element(Level::NOTE.message("the matched value is of type `NonEmptyEnum5`"))
                .element(Level::NOTE.message("match arms with guards don't count towards exhaustivity")
            ),
            Level::HELP
                .secondary_title("ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms")
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/empty-match.rs")
                        .annotation(AnnotationKind::Context.span(485..485).label(",\n                _ => todo!()"))
            )
    ];
    let expected_ascii = str![[r#"
error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
  --> $DIR/empty-match.rs:71:24
   |
71 |     match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
   |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
   |
note: `NonEmptyEnum5` defined here
  --> $DIR/empty-match.rs:38:10
   |
38 |     enum NonEmptyEnum5 {
   |          ^^^^^^^^^^^^^
39 |         V1,
   |         -- not covered
40 |         V2,
   |         -- not covered
41 |         V3,
   |         -- not covered
42 |         V4,
   |         -- not covered
43 |         V5,
   |         -- not covered
   = note: the matched value is of type `NonEmptyEnum5`
   = note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
  --> $DIR/empty-match.rs:17:33
   |
17 |                 _ if false => {}
   |                                 - ,
                _ => todo!()
"#]];
    let renderer =
        Renderer::plain().term_width(annotate_snippets::renderer::DEFAULT_TERM_WIDTH + 4);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
   ╭▸ $DIR/empty-match.rs:71:24
   │
71 │     match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
   │                        ━━━━━━━━━━━━━━━━━ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
   ╰╴
note: `NonEmptyEnum5` defined here
   ╭▸ $DIR/empty-match.rs:38:10
   │
38 │     enum NonEmptyEnum5 {
   │          ━━━━━━━━━━━━━
39 │         V1,
   │         ── not covered
40 │         V2,
   │         ── not covered
41 │         V3,
   │         ── not covered
42 │         V4,
   │         ── not covered
43 │         V5,
   │         ── not covered
   ├ note: the matched value is of type `NonEmptyEnum5`
   ╰ note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
   ╭▸ $DIR/empty-match.rs:17:33
   │
17 │                 _ if false => {}
   ╰╴                                ─ ,
                _ => todo!()
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn object_fail() {
    // tests/ui/traits/alias/object-fail.rs
    let source = r#"#![feature(trait_alias)]

trait EqAlias = Eq;
trait IteratorAlias = Iterator;

fn main() {
    let _: &dyn EqAlias = &123;
    //~^ ERROR the trait alias `EqAlias` is not dyn compatible [E0038]
    let _: &dyn IteratorAlias = &vec![123].into_iter();
    //~^ ERROR must be specified
}
"#;
    let input = &[Level::ERROR
        .primary_title("the trait alias `EqAlias` is not dyn compatible")
        .id("E0038").element(
                Snippet::source(source)
                    .line_start(1)
                    .path("$DIR/object-fail.rs")

                    .annotation(
                        AnnotationKind::Primary
                            .span(107..114)
                            .label("`EqAlias` is not dyn compatible"),
                    ),
            ),
                    Level::NOTE
                        .secondary_title("for a trait to be dyn compatible it needs to allow building a vtable\nfor more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>")
                .element(
                    Origin::path("$SRC_DIR/core/src/cmp.rs")
                        .line(334)
                        .char_column(14)
                )
                .element(Padding)
                .element(Level::NOTE.message("...because it uses `Self` as a type parameter"))
                .element(
                    Snippet::source(source)
                        .line_start(1)
                        .path("$DIR/object-fail.rs")

                        .annotation(
                            AnnotationKind::Context
                                .span(32..39)
                                .label("this trait is not dyn compatible..."),
                        ),
                )];
    let expected_ascii = str![[r#"
error[E0038]: the trait alias `EqAlias` is not dyn compatible
 --> $DIR/object-fail.rs:7:17
  |
7 |     let _: &dyn EqAlias = &123;
  |                 ^^^^^^^ `EqAlias` is not dyn compatible
  |
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
 --> $SRC_DIR/core/src/cmp.rs:334:14
  |
  = note: ...because it uses `Self` as a type parameter
  |
 ::: $DIR/object-fail.rs:3:7
  |
3 | trait EqAlias = Eq;
  |       ------- this trait is not dyn compatible...
"#]];

    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0038]: the trait alias `EqAlias` is not dyn compatible
  ╭▸ $DIR/object-fail.rs:7:17
  │
7 │     let _: &dyn EqAlias = &123;
  │                 ━━━━━━━ `EqAlias` is not dyn compatible
  ╰╴
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
  ╭▸ $SRC_DIR/core/src/cmp.rs:334:14
  │
  ├ note: ...because it uses `Self` as a type parameter
  │
  ⸬  $DIR/object-fail.rs:3:7
  │
3 │ trait EqAlias = Eq;
  ╰╴      ─────── this trait is not dyn compatible...
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn long_span_shortest() {
    // tests/ui/diagnostic-width/long-span.rs
    let source = r#"
const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

fn main() {}
"#;
    let input = &[Level::ERROR
        .primary_title("mismatched types")
        .id("E0038")
        .element(
            Snippet::source(source)
                .path("$DIR/long-span.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(15..5055)
                        .label("expected `u8`, found `[{integer}; 1680]`"),
                ),
        )];
    let expected_ascii = str![[r#"
error[E0038]: mismatched types
 --> $DIR/long-span.rs:2:15
  |
2 | ... = [0, 0...0, 0];
  |       ^^^^^...^^^^^ expected `u8`, found `[{integer}; 1680]`
"#]];

    let renderer = Renderer::plain().term_width(8);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0038]: mismatched types
  ╭▸ $DIR/long-span.rs:2:15
  │
2 │ …u8 = [0, 0…0, 0];
  ╰╴      ━━━━━…━━━━━ expected `u8`, found `[{integer}; 1680]`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn long_span_short() {
    // tests/ui/diagnostic-width/long-span.rs
    let source = r#"
const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

fn main() {}
"#;
    let input = &[Level::ERROR
        .primary_title("mismatched types")
        .id("E0038")
        .element(
            Snippet::source(source)
                .path("$DIR/long-span.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(15..5055)
                        .label("expected `u8`, found `[{integer}; 1680]`"),
                ),
        )];
    let expected_ascii = str![[r#"
error[E0038]: mismatched types
  ╭▸ $DIR/long-span.rs:2:15
  │
2 │ …u8 = [0, 0…0, 0];
  ╰╴      ━━━━━…━━━━━ expected `u8`, found `[{integer}; 1680]`
"#]];

    let renderer = Renderer::plain()
        .term_width(12)
        .decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0038]: mismatched types
  ╭▸ $DIR/long-span.rs:2:15
  │
2 │ …u8 = [0, 0…0, 0];
  ╰╴      ━━━━━…━━━━━ expected `u8`, found `[{integer}; 1680]`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn long_span_long() {
    // tests/ui/diagnostic-width/long-span.rs
    let source = r#"
const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

fn main() {}
"#;
    let input = &[Level::ERROR
        .primary_title("mismatched types")
        .id("E0038")
        .element(
            Snippet::source(source)
                .path("$DIR/long-span.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(15..5055)
                        .label("expected `u8`, found `[{integer}; 1680]`"),
                ),
        )];
    let expected_ascii = str![[r#"
error[E0038]: mismatched types
  ╭▸ $DIR/long-span.rs:2:15
  │
2 │ …u8 = [0, 0, 0, 0, 0, 0, 0, 0, …, 0, 0, 0, 0, 0, 0, 0, 0];
  ╰╴      ━━━━━━━━━━━━━━━━━━━━━━━━━…━━━━━━━━━━━━━━━━━━━━━━━━━ expected `u8`, found `[{integer}; 1680]`
"#]];

    let renderer = Renderer::plain()
        .term_width(80)
        .decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0038]: mismatched types
  ╭▸ $DIR/long-span.rs:2:15
  │
2 │ …u8 = [0, 0, 0, 0, 0, 0, 0, 0, …, 0, 0, 0, 0, 0, 0, 0, 0];
  ╰╴      ━━━━━━━━━━━━━━━━━━━━━━━━━…━━━━━━━━━━━━━━━━━━━━━━━━━ expected `u8`, found `[{integer}; 1680]`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn long_span_longest() {
    // tests/ui/diagnostic-width/long-span.rs
    let source = r#"
const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

fn main() {}
"#;
    let input = &[Level::ERROR
        .primary_title("mismatched types")
        .id("E0038")
        .element(
            Snippet::source(source)
                .path("$DIR/long-span.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(15..5055)
                        .label("expected `u8`, found `[{integer}; 1680]`"),
                ),
        )];
    let expected_ascii = str![[r#"
error[E0038]: mismatched types
 --> $DIR/long-span.rs:2:15
  |
2 | ... = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `[{integer}; 1680]`
"#]];

    let renderer = Renderer::plain().term_width(120);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0038]: mismatched types
  ╭▸ $DIR/long-span.rs:2:15
  │
2 │ …u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  ╰╴      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━…━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ expected `u8`, found `[{integer}; 1680]`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn lint_map_unit_fn() {
    // tests/ui/lint/lint_map_unit_fn.rs
    let source = r#"#![deny(map_unit_fn)]

fn foo(items: &mut Vec<u8>) {
    items.sort();
}

fn main() {
    let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
    x.iter_mut().map(foo);
    //~^ ERROR `Iterator::map` call that discard the iterator's values
    x.iter_mut().map(|items| {
    //~^ ERROR `Iterator::map` call that discard the iterator's values
        items.sort();
    });
    let f = |items: &mut Vec<u8>| {
        items.sort();
    };
    x.iter_mut().map(f);
    //~^ ERROR `Iterator::map` call that discard the iterator's values
}
"#;

    let input = &[Level::ERROR
        .primary_title("`Iterator::map` call that discard the iterator's values")
                .element(
                    Snippet::source(source)
                        .path("$DIR/lint_map_unit_fn.rs")

                        .annotation(AnnotationKind::Context.span(271..278).label(
                            "this function returns `()`, which is likely not what you wanted",
                        ))
                        .annotation(
                            AnnotationKind::Context
                                .span(271..379)
                                .label("called `Iterator::map` with callable that returns `()`"),
                        )
                        .annotation(
                            AnnotationKind::Context
                                .span(267..380)
                                .label("after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items")
                        )
                        .annotation(AnnotationKind::Primary.span(267..380)),
                )
                .element(
                    Level::NOTE.message("`Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated")),
            Level::HELP.secondary_title("you might have meant to use `Iterator::for_each`")
                .element(
                    Snippet::source(source)
                        .path("$DIR/lint_map_unit_fn.rs")

                        .patch(Patch::new(267..270, r#"for_each"#)),
                )];

    let expected_ascii = str![[r#"
error: `Iterator::map` call that discard the iterator's values
  --> $DIR/lint_map_unit_fn.rs:11:18
   |
11 |         x.iter_mut().map(|items| {
   |                      ^   -------
   |                      |   |
   |  ____________________|___this function returns `()`, which is likely not what you wanted
   | |  __________________|
   | | |
12 | | |     //~^ ERROR `Iterator::map` call that discard the iterator's values
13 | | |         items.sort();
14 | | |     });
   | | |     -^ after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
   | | |_____||
   | |_______|
   |         called `Iterator::map` with callable that returns `()`
   |
   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
help: you might have meant to use `Iterator::for_each`
   |
11 -     x.iter_mut().map(|items| {
11 +     x.iter_mut().for_each(|items| {
   |
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: `Iterator::map` call that discard the iterator's values
   ╭▸ $DIR/lint_map_unit_fn.rs:11:18
   │
11 │         x.iter_mut().map(|items| {
   │                      ╿   │──────
   │                      │   │
   │ ┌────────────────────│───this function returns `()`, which is likely not what you wanted
   │ │ ┏━━━━━━━━━━━━━━━━━━┙
   │ │ ┃
12 │ │ ┃     //~^ ERROR `Iterator::map` call that discard the iterator's values
13 │ │ ┃         items.sort();
14 │ │ ┃     });
   │ │ ┃     │╿ after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
   │ │ ┗━━━━━││
   │ └───────┤
   │         called `Iterator::map` with callable that returns `()`
   │
   ╰ note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
help: you might have meant to use `Iterator::for_each`
   ╭╴
11 -     x.iter_mut().map(|items| {
11 +     x.iter_mut().for_each(|items| {
   ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn bad_char_literals() {
    // tests/ui/parser/bad-char-literals.rs

    let source = r#"// ignore-tidy-cr
// ignore-tidy-tab

fn main() {
    // these literals are just silly.
    ''';
    //~^ ERROR: character constant must be escaped: `'`

    // note that this is a literal "\n" byte
    '
';
    //~^^ ERROR: character constant must be escaped: `\n`

    // note that this is a literal "\r" byte
; //~ ERROR: character constant must be escaped: `\r`

    // note that this is a literal NULL
    '--'; //~ ERROR: character literal may only contain one codepoint

    // note that this is a literal tab character here
    '  ';
    //~^ ERROR: character constant must be escaped: `\t`
}
"#;

    let input = &[
        Level::ERROR
            .primary_title("character constant must be escaped: `\\n`")
            .element(
                Snippet::source(source)
                    .path("$DIR/bad-char-literals.rs")
                    .annotation(AnnotationKind::Primary.span(204..205)),
            ),
        Level::HELP.secondary_title("escape the character").element(
            Snippet::source(source)
                .path("$DIR/bad-char-literals.rs")
                .line_start(1)
                .patch(Patch::new(204..205, r#"\n"#)),
        ),
    ];
    let expected_ascii = str![[r#"
error: character constant must be escaped: `/n`
  --> $DIR/bad-char-literals.rs:10:6
   |
10 |     '
   |      ^
   |
help: escape the character
   |
10 |     '/n
   |      ++
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: character constant must be escaped: `/n`
   ╭▸ $DIR/bad-char-literals.rs:10:6
   │
10 │     '
   │      ━
   ╰╴
help: escape the character
   ╭╴
10 │     '/n
   ╰╴     ++
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unclosed_1() {
    // tests/ui/frontmatter/unclosed-1.rs

    let source = r#"----cargo
//~^ ERROR: unclosed frontmatter

// This test checks that the #! characters can help us recover a frontmatter
// close. There should not be a "missing `main` function" error as the rest
// are properly parsed.

#![feature(frontmatter)]

fn main() {}
"#;

    let input = &[
        Level::ERROR.primary_title("unclosed frontmatter").element(
            Snippet::source(source)
                .path("$DIR/unclosed-1.rs")
                .annotation(AnnotationKind::Primary.span(0..221)),
        ),
        Level::NOTE
            .secondary_title("frontmatter opening here was not closed")
            .element(
                Snippet::source(source)
                    .path("$DIR/unclosed-1.rs")
                    .annotation(AnnotationKind::Primary.span(0..4)),
            ),
    ];
    let expected_ascii = str![[r#"
error: unclosed frontmatter
 --> $DIR/unclosed-1.rs:1:1
  |
1 | / ----cargo
... |
6 | | // are properly parsed.
  | |_______________________^
  |
note: frontmatter opening here was not closed
 --> $DIR/unclosed-1.rs:1:1
  |
1 | ----cargo
  | ^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: unclosed frontmatter
  ╭▸ $DIR/unclosed-1.rs:1:1
  │
1 │ ┏ ----cargo
  ┆ ┇
6 │ ┃ // are properly parsed.
  │ ┗━━━━━━━━━━━━━━━━━━━━━━━┛
  ╰╴
note: frontmatter opening here was not closed
  ╭▸ $DIR/unclosed-1.rs:1:1
  │
1 │ ----cargo
  ╰╴━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unclosed_2() {
    // tests/ui/frontmatter/unclosed-2.rs

    let source = r#"----cargo
//~^ ERROR: unclosed frontmatter
//~| ERROR: frontmatters are experimental

//@ compile-flags: --crate-type lib

// Leading whitespace on the feature line prevents recovery. However
// the dashes quoted will not be used for recovery and the entire file
// should be treated as within the frontmatter block.

 #![feature(frontmatter)]

fn foo() -> &str {
    "----"
}
"#;

    let input = &[
        Level::ERROR.primary_title("unclosed frontmatter").element(
            Snippet::source(source)
                .path("$DIR/unclosed-2.rs")
                .annotation(AnnotationKind::Primary.span(0..377)),
        ),
        Level::NOTE
            .secondary_title("frontmatter opening here was not closed")
            .element(
                Snippet::source(source)
                    .path("$DIR/unclosed-2.rs")
                    .annotation(AnnotationKind::Primary.span(0..4)),
            ),
    ];
    let expected_ascii = str![[r#"
error: unclosed frontmatter
  --> $DIR/unclosed-2.rs:1:1
   |
 1 | / ----cargo
...  |
14 | |     "----"
15 | | }
   | |__^
   |
note: frontmatter opening here was not closed
  --> $DIR/unclosed-2.rs:1:1
   |
 1 | ----cargo
   | ^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: unclosed frontmatter
   ╭▸ $DIR/unclosed-2.rs:1:1
   │
 1 │ ┏ ----cargo
   ┆ ┇
14 │ ┃     "----"
15 │ ┃ }
   │ ┗━━┛
   ╰╴
note: frontmatter opening here was not closed
   ╭▸ $DIR/unclosed-2.rs:1:1
   │
 1 │ ----cargo
   ╰╴━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unclosed_3() {
    // tests/ui/frontmatter/unclosed-3.rs

    let source = r#"----cargo
//~^ ERROR: frontmatter close does not match the opening

//@ compile-flags: --crate-type lib

// Unfortunate recovery situation. Not really preventable with improving the
// recovery strategy, but this type of code is rare enough already.

 #![feature(frontmatter)]

fn foo(x: i32) -> i32 {
    ---x
    //~^ ERROR: invalid preceding whitespace for frontmatter close
    //~| ERROR: extra characters after frontmatter close are not allowed
}
//~^ ERROR: unexpected closing delimiter: `}`
"#;

    let input = &[
        Level::ERROR
            .primary_title("invalid preceding whitespace for frontmatter close")
            .element(
                Snippet::source(source)
                    .path("$DIR/unclosed-3.rs")
                    .annotation(AnnotationKind::Primary.span(302..310)),
            ),
        Level::NOTE
            .secondary_title("frontmatter close should not be preceded by whitespace")
            .element(
                Snippet::source(source)
                    .path("$DIR/unclosed-3.rs")
                    .annotation(AnnotationKind::Primary.span(302..306)),
            ),
    ];
    let expected_ascii = str![[r#"
error: invalid preceding whitespace for frontmatter close
  --> $DIR/unclosed-3.rs:12:1
   |
12 |     ---x
   | ^^^^^^^^
   |
note: frontmatter close should not be preceded by whitespace
  --> $DIR/unclosed-3.rs:12:1
   |
12 |     ---x
   | ^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: invalid preceding whitespace for frontmatter close
   ╭▸ $DIR/unclosed-3.rs:12:1
   │
12 │     ---x
   │ ━━━━━━━━
   ╰╴
note: frontmatter close should not be preceded by whitespace
   ╭▸ $DIR/unclosed-3.rs:12:1
   │
12 │     ---x
   ╰╴━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unclosed_4() {
    // tests/ui/frontmatter/unclosed-4.rs

    let source = r#"----cargo
//~^ ERROR: unclosed frontmatter

//! Similarly, a module-level content should allow for recovery as well (as
//! per unclosed-1.rs)

#![feature(frontmatter)]

fn main() {}
"#;

    let input = &[
        Level::ERROR.primary_title("unclosed frontmatter").element(
            Snippet::source(source)
                .path("$DIR/unclosed-4.rs")
                .annotation(AnnotationKind::Primary.span(0..43)),
        ),
        Level::NOTE
            .secondary_title("frontmatter opening here was not closed")
            .element(
                Snippet::source(source)
                    .path("$DIR/unclosed-4.rs")
                    .annotation(AnnotationKind::Primary.span(0..4)),
            ),
    ];
    let expected_ascii = str![[r#"
error: unclosed frontmatter
 --> $DIR/unclosed-4.rs:1:1
  |
1 | / ----cargo
2 | | //~^ ERROR: unclosed frontmatter
  | |________________________________^
  |
note: frontmatter opening here was not closed
 --> $DIR/unclosed-4.rs:1:1
  |
1 | ----cargo
  | ^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: unclosed frontmatter
  ╭▸ $DIR/unclosed-4.rs:1:1
  │
1 │ ┏ ----cargo
2 │ ┃ //~^ ERROR: unclosed frontmatter
  │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
  ╰╴
note: frontmatter opening here was not closed
  ╭▸ $DIR/unclosed-4.rs:1:1
  │
1 │ ----cargo
  ╰╴━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unclosed_5() {
    // tests/ui/frontmatter/unclosed-5.rs

    let source = r#"----cargo
//~^ ERROR: unclosed frontmatter
//~| ERROR: frontmatters are experimental

// Similarly, a use statement should allow for recovery as well (as
// per unclosed-1.rs)

use std::env;

fn main() {}
"#;

    let input = &[
        Level::ERROR.primary_title("unclosed frontmatter").element(
            Snippet::source(source)
                .path("$DIR/unclosed-5.rs")
                .annotation(AnnotationKind::Primary.span(0..176)),
        ),
        Level::NOTE
            .secondary_title("frontmatter opening here was not closed")
            .element(
                Snippet::source(source)
                    .path("$DIR/unclosed-5.rs")
                    .annotation(AnnotationKind::Primary.span(0..4)),
            ),
    ];

    let expected_ascii = str![[r#"
error: unclosed frontmatter
 --> $DIR/unclosed-5.rs:1:1
  |
1 | / ----cargo
... |
6 | | // per unclosed-1.rs)
  | |_____________________^
  |
note: frontmatter opening here was not closed
 --> $DIR/unclosed-5.rs:1:1
  |
1 | ----cargo
  | ^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: unclosed frontmatter
  ╭▸ $DIR/unclosed-5.rs:1:1
  │
1 │ ┏ ----cargo
  ┆ ┇
6 │ ┃ // per unclosed-1.rs)
  │ ┗━━━━━━━━━━━━━━━━━━━━━┛
  ╰╴
note: frontmatter opening here was not closed
  ╭▸ $DIR/unclosed-5.rs:1:1
  │
1 │ ----cargo
  ╰╴━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn pat_tuple_field_count_cross() {
    // tests/ui/pattern/pat-tuple-field-count-cross.stderr

    let source = r#"//@ aux-build:declarations-for-tuple-field-count-errors.rs

extern crate declarations_for_tuple_field_count_errors;

use declarations_for_tuple_field_count_errors::*;

fn main() {
    match Z0 {
        Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
        Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
    }
    match Z1() {
        Z1 => {} //~ ERROR match bindings cannot shadow tuple structs
        Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 0 fields
    }

    match S(1, 2, 3) {
        S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields
        S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields
        S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields
        S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
    }
    match M(1, 2, 3) {
        M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields
        M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields
        M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields
        M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
    }

    match E1::Z0 {
        E1::Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
        E1::Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
    }
    match E1::Z1() {
        E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
        E1::Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 0 fields
    }
    match E1::S(1, 2, 3) {
        E1::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields
        E1::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields
        E1::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
        E1::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields
    }

    match E2::S(1, 2, 3) {
        E2::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields
        E2::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields
        E2::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
        E2::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields
    }
    match E2::M(1, 2, 3) {
        E2::M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields
        E2::M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields
        E2::M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
        E2::M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields
    }
}
"#;
    let source1 = r#"pub struct Z0;
pub struct Z1();

pub struct S(pub u8, pub u8, pub u8);
pub struct M(
    pub u8,
    pub u8,
    pub u8,
);

pub enum E1 { Z0, Z1(), S(u8, u8, u8) }

pub enum E2 {
    S(u8, u8, u8),
    M(
        u8,
        u8,
        u8,
    ),
}
"#;

    let input = &[
        Level::ERROR
            .primary_title(
                "expected unit struct, unit variant or constant, found tuple variant `E1::Z1`",
            )
            .id(r#"E0532"#)
            .element(
                Snippet::source(source)
                    .path("$DIR/pat-tuple-field-count-cross.rs")
                    .annotation(AnnotationKind::Primary.span(1760..1766)),
            )
            .element(
                Snippet::source(source1)
                    .path("$DIR/auxiliary/declarations-for-tuple-field-count-errors.rs")
                    .annotation(
                        AnnotationKind::Context
                            .span(143..145)
                            .label("`E1::Z1` defined here"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(139..141)
                            .label("similarly named unit variant `Z0` defined here"),
                    ),
            ),
        Level::HELP
            .secondary_title("use the tuple variant pattern syntax instead")
            .element(
                Snippet::source(source)
                    .path("$DIR/pat-tuple-field-count-cross.rs")
                    .patch(Patch::new(1760..1766, r#"E1::Z1()"#)),
            ),
        Level::HELP
            .secondary_title("a unit variant with a similar name exists")
            .element(
                Snippet::source(source)
                    .path("$DIR/pat-tuple-field-count-cross.rs")
                    .patch(Patch::new(1764..1766, r#"Z0"#)),
            ),
    ];
    let expected_ascii = str![[r#"
error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
  --> $DIR/pat-tuple-field-count-cross.rs:35:9
   |
35 |         E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   |         ^^^^^^
   |
  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
   |
11 | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
   |               --  -- `E1::Z1` defined here
   |               |
   |               similarly named unit variant `Z0` defined here
   |
help: use the tuple variant pattern syntax instead
   |
35 |         E1::Z1() => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   |               ++
help: a unit variant with a similar name exists
   |
35 -         E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
35 +         E1::Z0 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   |
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   ╭▸ $DIR/pat-tuple-field-count-cross.rs:35:9
   │
35 │         E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   │         ━━━━━━
   │
   ⸬  $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
   │
11 │ pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
   │               ┬─  ── `E1::Z1` defined here
   │               │
   │               similarly named unit variant `Z0` defined here
   ╰╴
help: use the tuple variant pattern syntax instead
   ╭╴
35 │         E1::Z1() => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   ╰╴              ++
help: a unit variant with a similar name exists
   ╭╴
35 -         E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
35 +         E1::Z0 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
   ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unterminated_nested_comment() {
    // tests/ui/lexer/unterminated-nested-comment.rs

    let source = r#"/* //~ ERROR E0758
/* */
/*
*/
"#;

    let input = &[Level::ERROR
        .primary_title("unterminated block comment")
        .id("E0758")
        .element(
            Snippet::source(source)
                .path("$DIR/unterminated-nested-comment.rs")
                .annotation(
                    AnnotationKind::Context
                        .span(0..2)
                        .label("unterminated block comment"),
                )
                .annotation(AnnotationKind::Context.span(25..27).label(
                    "...as last nested comment starts here, maybe you want to close this instead?",
                ))
                .annotation(
                    AnnotationKind::Context
                        .span(28..30)
                        .label("...and last nested comment terminates here."),
                )
                .annotation(AnnotationKind::Primary.span(0..31)),
        )];

    let expected_ascii = str![[r#"
error[E0758]: unterminated block comment
 --> $DIR/unterminated-nested-comment.rs:1:1
  |
1 |   /* //~ ERROR E0758
  |   ^-
  |   |
  |  _unterminated block comment
  | |
2 | | /* */
3 | | /*
  | | --
  | | |
  | | ...as last nested comment starts here, maybe you want to close this instead?
4 | | */
  | |_--^
  |   |
  |   ...and last nested comment terminates here.
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0758]: unterminated block comment
  ╭▸ $DIR/unterminated-nested-comment.rs:1:1
  │
1 │   /* //~ ERROR E0758
  │   ╿─
  │   │
  │ ┏━unterminated block comment
  │ ┃
2 │ ┃ /* */
3 │ ┃ /*
  │ ┃ ┬─
  │ ┃ │
  │ ┃ ...as last nested comment starts here, maybe you want to close this instead?
4 │ ┃ */
  │ ┗━┬─┛
  │   │
  ╰╴  ...and last nested comment terminates here.
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn mismatched_types1() {
    // tests/ui/include-macros/mismatched-types.rs

    let file_txt_source = r#""#;

    let rust_source = r#"fn main() {
    let b: &[u8] = include_str!("file.txt");    //~ ERROR mismatched types
    let s: &str = include_bytes!("file.txt");   //~ ERROR mismatched types
}"#;

    let input = &[Level::ERROR
        .primary_title("mismatched types")
        .id("E0308")
        .element(
            Snippet::source(file_txt_source)
                .line_start(3)
                .path("$DIR/file.txt")
                .annotation(
                    AnnotationKind::Primary
                        .span(0..0)
                        .label("expected `&[u8]`, found `&str`"),
                ),
        )
        .element(
            Snippet::source(rust_source)
                .path("$DIR/mismatched-types.rs")
                .annotation(
                    AnnotationKind::Context
                        .span(23..28)
                        .label("expected due to this"),
                )
                .annotation(
                    AnnotationKind::Context
                        .span(31..55)
                        .label("in this macro invocation"),
                ),
        )
        .element(
            Level::NOTE.message("expected reference `&[u8]`\n   found reference `&'static str`"),
        )];

    let expected_ascii = str![[r#"
error[E0308]: mismatched types
 --> $DIR/file.txt:3:1
  |
3 |
  | ^ expected `&[u8]`, found `&str`
  |
 ::: $DIR/mismatched-types.rs:2:12
  |
2 |     let b: &[u8] = include_str!("file.txt");    //~ ERROR mismatched types
  |            -----   ------------------------ in this macro invocation
  |            |
  |            expected due to this
  |
  = note: expected reference `&[u8]`
   found reference `&'static str`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0308]: mismatched types
  ╭▸ $DIR/file.txt:3:1
  │
3 │
  │ ━ expected `&[u8]`, found `&str`
  │
  ⸬  $DIR/mismatched-types.rs:2:12
  │
2 │     let b: &[u8] = include_str!("file.txt");    //~ ERROR mismatched types
  │            ┬────   ──────────────────────── in this macro invocation
  │            │
  │            expected due to this
  │
  ╰ note: expected reference `&[u8]`
   found reference `&'static str`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn mismatched_types2() {
    // tests/ui/include-macros/mismatched-types.rs

    let source = r#"fn main() {
    let b: &[u8] = include_str!("file.txt");    //~ ERROR mismatched types
    let s: &str = include_bytes!("file.txt");   //~ ERROR mismatched types
}"#;

    let input = &[Level::ERROR
        .primary_title("mismatched types")
        .id("E0308")
        .element(
            Snippet::source(source)
                .path("$DIR/mismatched-types.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(105..131)
                        .label("expected `&str`, found `&[u8; 0]`"),
                )
                .annotation(
                    AnnotationKind::Context
                        .span(98..102)
                        .label("expected due to this"),
                ),
        )
        .element(
            Level::NOTE.message("expected reference `&str`\n   found reference `&'static [u8; 0]`"),
        )];

    let expected_ascii = str![[r#"
error[E0308]: mismatched types
 --> $DIR/mismatched-types.rs:3:19
  |
3 |     let s: &str = include_bytes!("file.txt");   //~ ERROR mismatched types
  |            ----   ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `&[u8; 0]`
  |            |
  |            expected due to this
  |
  = note: expected reference `&str`
   found reference `&'static [u8; 0]`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0308]: mismatched types
  ╭▸ $DIR/mismatched-types.rs:3:19
  │
3 │     let s: &str = include_bytes!("file.txt");   //~ ERROR mismatched types
  │            ┬───   ━━━━━━━━━━━━━━━━━━━━━━━━━━ expected `&str`, found `&[u8; 0]`
  │            │
  │            expected due to this
  │
  ╰ note: expected reference `&str`
   found reference `&'static [u8; 0]`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn short_error_format1() {
    // tests/ui/short-error-format.rs

    let source = r#"//@ compile-flags: --error-format=short

fn foo(_: u32) {}

fn main() {
    foo("Bonjour".to_owned());
    let x = 0u32;
    x.salut();
}
"#;

    let input = &[
        Level::ERROR
            .primary_title("mismatched types")
            .id("E0308")
            .element(
                Snippet::source(source)
                    .path("$DIR/short-error-format.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(80..100)
                            .label("expected `u32`, found `String`"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(76..79)
                            .label("arguments to this function are incorrect"),
                    ),
            ),
        Level::NOTE
            .secondary_title("function defined here")
            .element(
                Snippet::source(source)
                    .path("$DIR/short-error-format.rs")
                    .annotation(AnnotationKind::Context.span(48..54).label(""))
                    .annotation(AnnotationKind::Primary.span(44..47)),
            ),
    ];

    let expected_ascii = str![[r#"
$DIR/short-error-format.rs:6:9: error[E0308]: mismatched types: expected `u32`, found `String`
"#]];
    let renderer = Renderer::plain().short_message(true);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![
        "$DIR/short-error-format.rs:6:9: error[E0308]: mismatched types: expected `u32`, found `String`"
    ];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn short_error_format2() {
    // tests/ui/short-error-format.rs

    let source = r#"//@ compile-flags: --error-format=short

fn foo(_: u32) {}

fn main() {
    foo("Bonjour".to_owned());
    let x = 0u32;
    x.salut();
}
"#;

    let input = &[Level::ERROR
        .primary_title("no method named `salut` found for type `u32` in the current scope")
        .id("E0599")
        .element(
            Snippet::source(source)
                .path("$DIR/short-error-format.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(127..132)
                        .label("method not found in `u32`"),
                ),
        )];

    let expected_ascii = str![[r#"
$DIR/short-error-format.rs:8:7: error[E0599]: no method named `salut` found for type `u32` in the current scope: method not found in `u32`
"#]];
    let renderer = Renderer::plain().short_message(true);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![
        "$DIR/short-error-format.rs:8:7: error[E0599]: no method named `salut` found for type `u32` in the current scope: method not found in `u32`"
    ];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn rustdoc_ui_diagnostic_width() {
    // tests/rustdoc-ui/diagnostic-width.rs

    let source_0 = r#"//@ compile-flags: --diagnostic-width=10
#![deny(rustdoc::bare_urls)]

/// This is a long line that contains a http://link.com
pub struct Foo; //~^ ERROR
"#;
    let source_1 = r#"/// This is a long line that contains a http://link.com
"#;

    let input = &[
        Level::ERROR
            .primary_title("this URL is not a hyperlink")
            .element(
                Snippet::source(source_0)
                    .path("$DIR/diagnostic-width.rs")
                    .annotation(AnnotationKind::Primary.span(111..126)),
            )
            .element(
                Level::NOTE.message("bare URLs are not automatically turned into clickable links"),
            ),
        Level::NOTE
            .secondary_title("the lint level is defined here")
            .element(
                Snippet::source(source_0)
                    .path("$DIR/diagnostic-width.rs")
                    .annotation(AnnotationKind::Primary.span(49..67)),
            ),
        Level::HELP
            .secondary_title("use an automatic link instead")
            .element(
                Snippet::source(source_1)
                    .path("$DIR/diagnostic-width.rs")
                    .line_start(4)
                    .patch(Patch::new(40..40, "<"))
                    .patch(Patch::new(55..55, ">")),
            ),
    ];

    let expected_ascii = str![[r#"
error: this URL is not a hyperlink
 --> $DIR/diagnostic-width.rs:4:41
  |
4 | ... a http:...k.com
  |       ^^^^^...^^^^^
  |
  = note: bare URLs are not automatically turned into clickable links
note: the lint level is defined here
 --> $DIR/diagnostic-width.rs:2:9
  |
2 | ...ny(rustd..._urls)]
  |       ^^^^^...^^^^^
help: use an automatic link instead
  |
4 | /// This is a long line that contains a <http://link.com>
  |                                         +               +
"#]];
    let renderer = Renderer::plain().term_width(10);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: this URL is not a hyperlink
  ╭▸ $DIR/diagnostic-width.rs:4:41
  │
4 │ …ns a http:…k.com
  │       ━━━━━…━━━━━
  │
  ╰ note: bare URLs are not automatically turned into clickable links
note: the lint level is defined here
  ╭▸ $DIR/diagnostic-width.rs:2:9
  │
2 │ …deny(rustd…_urls)]
  ╰╴      ━━━━━…━━━━━
help: use an automatic link instead
  ╭╴
4 │ /// This is a long line that contains a <http://link.com>
  ╰╴                                        +               +
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn array_into_iter() {
    let source1 = r#"#![allow(unused)]
fn main() {
[1, 2, 3].into_iter().for_each(|n| { *n; });
}
"#;
    let source2 = r#"[1, 2, 3].into_iter().for_each(|n| { *n; });
"#;

    let long_title1 = "this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021";
    let long_title2 = "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>";
    let long_title3 = "or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value";

    let input = &[
        Level::WARNING
            .primary_title(long_title1)
            .element(
                Snippet::source(source1)
                    .path("lint_example.rs")
                    .annotation(AnnotationKind::Primary.span(40..49)),
            )
            .element(Level::WARNING.message("this changes meaning in Rust 2021"))
            .element(Level::NOTE.message(long_title2))
            .element(Level::NOTE.message("`#[warn(array_into_iter)]` on by default")),
        Level::HELP
            .secondary_title("use `.iter()` instead of `.into_iter()` to avoid ambiguity")
            .element(
                Snippet::source(source2)
                    .path("lint_example.rs")
                    .line_start(3)
                    .patch(Patch::new(10..19, "iter")),
            ),
        Level::HELP.secondary_title(long_title3).element(
            Snippet::source(source2)
                .path("lint_example.rs")
                .line_start(3)
                .patch(Patch::new(0..0, "IntoIterator::into_iter("))
                .patch(Patch::new(9..21, ")")),
        ),
    ];

    let expected_ascii = str![[r#"
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
 --> lint_example.rs:3:11
  |
3 | [1, 2, 3].into_iter().for_each(|n| { *n; });
  |           ^^^^^^^^^
  |
  = warning: this changes meaning in Rust 2021
  = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
  = note: `#[warn(array_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
  |
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3 + [1, 2, 3].iter().for_each(|n| { *n; });
  |
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
  |
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3 + IntoIterator::into_iter([1, 2, 3]).for_each(|n| { *n; });
  |
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
  ╭▸ lint_example.rs:3:11
  │
3 │ [1, 2, 3].into_iter().for_each(|n| { *n; });
  │           ━━━━━━━━━
  │
  ├ warning: this changes meaning in Rust 2021
  ├ note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
  ╰ note: `#[warn(array_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
  ╭╴
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3 + [1, 2, 3].iter().for_each(|n| { *n; });
  ╰╴
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
  ╭╴
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3 + IntoIterator::into_iter([1, 2, 3]).for_each(|n| { *n; });
  ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn autoderef_box_no_add() {
    // tests/ui/autoref-autoderef/autoderef-box-no-add.rs

    let source = r#"//! Tests that auto-dereferencing does not allow addition of `Box<isize>` values.
//!
//! This test ensures that `Box<isize>` fields in structs (`Clam` and `Fish`) are not
//! automatically dereferenced to `isize` during addition operations, as `Box<isize>`
//! does not implement the `Add` trait.

struct Clam {
    x: Box<isize>,
    y: Box<isize>,
}

struct Fish {
    a: Box<isize>,
}

fn main() {
    let a: Clam = Clam {
        x: Box::new(1),
        y: Box::new(2),
    };
    let b: Clam = Clam {
        x: Box::new(10),
        y: Box::new(20),
    };
    let z: isize = a.x + b.y;
    //~^ ERROR cannot add `Box<isize>` to `Box<isize>`
    println!("{}", z);
    assert_eq!(z, 21);
    let forty: Fish = Fish { a: Box::new(40) };
    let two: Fish = Fish { a: Box::new(2) };
    let answer: isize = forty.a + two.a;
    //~^ ERROR cannot add `Box<isize>` to `Box<isize>`
    println!("{}", answer);
    assert_eq!(answer, 42);
}
"#;
    let input = &[
        Level::ERROR
            .primary_title("cannot add `Box<isize>` to `Box<isize>`")
            .id("E0369")
            .element(
                Snippet::source(source)
                    .path("$DIR/autoderef-box-no-add.rs")
                    .annotation(AnnotationKind::Context.span(583..586).label("Box<isize>"))
                    .annotation(AnnotationKind::Context.span(589..592).label("Box<isize>"))
                    .annotation(AnnotationKind::Primary.span(587..588)),
            ),
        Level::NOTE
            .secondary_title("the foreign item type `Box<isize>` doesn't implement `Add`")
            .element(
                Origin::path("$SRC_DIR/alloc/src/boxed.rs")
                    .line(231)
                    .char_column(0),
            )
            .element(
                Origin::path("$SRC_DIR/alloc/src/boxed.rs")
                    .line(234)
                    .char_column(1),
            )
            .element(Padding)
            .element(Level::NOTE.message("not implement `Add`")),
    ];

    let expected_ascii = str![[r#"
error[E0369]: cannot add `Box<isize>` to `Box<isize>`
  --> $DIR/autoderef-box-no-add.rs:25:24
   |
25 |     let z: isize = a.x + b.y;
   |                    --- ^ --- Box<isize>
   |                    |
   |                    Box<isize>
   |
note: the foreign item type `Box<isize>` doesn't implement `Add`
  --> $SRC_DIR/alloc/src/boxed.rs:231:0
  ::: $SRC_DIR/alloc/src/boxed.rs:234:1
   |
   = note: not implement `Add`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0369]: cannot add `Box<isize>` to `Box<isize>`
   ╭▸ $DIR/autoderef-box-no-add.rs:25:24
   │
25 │     let z: isize = a.x + b.y;
   │                    ┬── ━ ─── Box<isize>
   │                    │
   │                    Box<isize>
   ╰╴
note: the foreign item type `Box<isize>` doesn't implement `Add`
   ╭▸ $SRC_DIR/alloc/src/boxed.rs:231:0
   ⸬  $SRC_DIR/alloc/src/boxed.rs:234:1
   │
   ╰ note: not implement `Add`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn dont_project_to_specializable_projection() {
    // tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs

    let source = r#"//@ edition: 2021
//@ known-bug: #108309

#![feature(min_specialization)]

struct MyStruct;

trait MyTrait<T> {
    async fn foo(_: T) -> &'static str;
}

impl<T> MyTrait<T> for MyStruct {
    default async fn foo(_: T) -> &'static str {
        "default"
    }
}

impl MyTrait<i32> for MyStruct {
    async fn foo(_: i32) -> &'static str {
        "specialized"
    }
}

async fn async_main() {
    assert_eq!(MyStruct::foo(42).await, "specialized");
    assert_eq!(indirection(42).await, "specialized");
}

async fn indirection<T>(x: T) -> &'static str {
    //explicit type coercion is currently necessary
    // because of https://github.com/rust-lang/rust/issues/67918
    <MyStruct as MyTrait<T>>::foo(x).await
}

// ------------------------------------------------------------------------- //
// Implementation Details Below...

use std::pin::{pin, Pin};
use std::task::*;

fn main() {
    let mut fut = pin!(async_main());

    // Poll loop, just to test the future...
    let ctx = &mut Context::from_waker(Waker::noop());

    loop {
        match fut.as_mut().poll(ctx) {
            Poll::Pending => {}
            Poll::Ready(()) => break,
        }
    }
}
"#;

    let title_0 = "no method named `poll` found for struct `Pin<&mut impl Future<Output = ()>>` in the current scope";
    let title_1 = "trait `Future` which provides `poll` is implemented but not in scope; perhaps you want to import it";

    let input = &[
        Level::ERROR.primary_title(title_0).id("E0599").element(
            Snippet::source(source)
                .path("$DIR/dont-project-to-specializable-projection.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(1071..1075)
                        .label("method not found in `Pin<&mut impl Future<Output = ()>>`"),
                ),
        ),
        Group::with_level(Level::ERROR)
            .element(
                Origin::path("$SRC_DIR/core/src/future/future.rs")
                    .line(104)
                    .char_column(7),
            )
            .element(Padding)
            .element(
                Level::NOTE.message(
                    "the method is available for `Pin<&mut impl Future<Output = ()>>` here",
                ),
            )
            .element(Padding)
            .element(
                Level::HELP.message("items from traits can only be used if the trait is in scope"),
            ),
        Level::HELP.secondary_title(title_1).element(
            Snippet::source("struct MyStruct;\n")
                .path("$DIR/dont-project-to-specializable-projection.rs")
                .line_start(6)
                .patch(Patch::new(
                    0..0,
                    r#"use std::future::Future;
"#,
                )),
        ),
    ];
    let expected_ascii = str![[r#"
error[E0599]: no method named `poll` found for struct `Pin<&mut impl Future<Output = ()>>` in the current scope
  --> $DIR/dont-project-to-specializable-projection.rs:48:28
   |
48 |         match fut.as_mut().poll(ctx) {
   |                            ^^^^ method not found in `Pin<&mut impl Future<Output = ()>>`
   |
  --> $SRC_DIR/core/src/future/future.rs:104:7
   |
   = note: the method is available for `Pin<&mut impl Future<Output = ()>>` here
   |
   = help: items from traits can only be used if the trait is in scope
help: trait `Future` which provides `poll` is implemented but not in scope; perhaps you want to import it
   |
 6 + use std::future::Future;
   |
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0599]: no method named `poll` found for struct `Pin<&mut impl Future<Output = ()>>` in the current scope
   ╭▸ $DIR/dont-project-to-specializable-projection.rs:48:28
   │
48 │         match fut.as_mut().poll(ctx) {
   │                            ━━━━ method not found in `Pin<&mut impl Future<Output = ()>>`
   ╰╴
   ╭▸ $SRC_DIR/core/src/future/future.rs:104:7
   │
   ├ note: the method is available for `Pin<&mut impl Future<Output = ()>>` here
   │
   ╰ help: items from traits can only be used if the trait is in scope
help: trait `Future` which provides `poll` is implemented but not in scope; perhaps you want to import it
   ╭╴
 6 + use std::future::Future;
   ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn binary_op_not_allowed_issue_125631() {
    // tests/ui/binop/binary-op-not-allowed-issue-125631.rs

    let source = r#"use std::io::{Error, ErrorKind};
use std::thread;

struct T1;
struct T2;

fn main() {
    (Error::new(ErrorKind::Other, "1"), T1, 1) == (Error::new(ErrorKind::Other, "1"), T1, 2);
    //~^ERROR binary operation `==` cannot be applied to type
    (Error::new(ErrorKind::Other, "2"), thread::current())
        == (Error::new(ErrorKind::Other, "2"), thread::current());
    //~^ERROR binary operation `==` cannot be applied to type
    (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2)
        == (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2);
    //~^ERROR binary operation `==` cannot be applied to type
}
"#;
    let title_0 = "binary operation `==` cannot be applied to type `(std::io::Error, Thread)`";
    let title_1 =
        "the foreign item types don't implement required traits for this operation to be valid";

    let input = &[
        Level::ERROR.primary_title(title_0).id("E0369").element(
            Snippet::source(source)
                .path("$DIR/binary-op-not-allowed-issue-125631.rs")
                .annotation(
                    AnnotationKind::Context
                        .span(246..300)
                        .label("(std::io::Error, Thread)"),
                )
                .annotation(
                    AnnotationKind::Context
                        .span(312..366)
                        .label("(std::io::Error, Thread)"),
                )
                .annotation(AnnotationKind::Primary.span(309..311)),
        ),
        Level::NOTE
            .secondary_title(title_1)
            .element(
                Origin::path("$SRC_DIR/std/src/io/error.rs")
                    .line(65)
                    .char_column(0),
            )
            .element(Padding)
            .element(Level::NOTE.message("not implement `PartialEq`")),
        Group::with_level(Level::NOTE)
            .element(
                Origin::path("$SRC_DIR/std/src/thread/mod.rs")
                    .line(1415)
                    .char_column(0),
            )
            .element(Padding)
            .element(Level::NOTE.message("not implement `PartialEq`")),
    ];

    let expected_ascii = str![[r#"
error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread)`
  --> $DIR/binary-op-not-allowed-issue-125631.rs:11:9
   |
10 |     (Error::new(ErrorKind::Other, "2"), thread::current())
   |     ------------------------------------------------------ (std::io::Error, Thread)
11 |         == (Error::new(ErrorKind::Other, "2"), thread::current());
   |         ^^ ------------------------------------------------------ (std::io::Error, Thread)
   |
note: the foreign item types don't implement required traits for this operation to be valid
  --> $SRC_DIR/std/src/io/error.rs:65:0
   |
   = note: not implement `PartialEq`
  --> $SRC_DIR/std/src/thread/mod.rs:1415:0
   |
   = note: not implement `PartialEq`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread)`
   ╭▸ $DIR/binary-op-not-allowed-issue-125631.rs:11:9
   │
10 │     (Error::new(ErrorKind::Other, "2"), thread::current())
   │     ────────────────────────────────────────────────────── (std::io::Error, Thread)
11 │         == (Error::new(ErrorKind::Other, "2"), thread::current());
   │         ━━ ────────────────────────────────────────────────────── (std::io::Error, Thread)
   ╰╴
note: the foreign item types don't implement required traits for this operation to be valid
   ╭▸ $SRC_DIR/std/src/io/error.rs:65:0
   │
   ╰ note: not implement `PartialEq`
   ╭▸ $SRC_DIR/std/src/thread/mod.rs:1415:0
   │
   ╰ note: not implement `PartialEq`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn deriving_meta_unknown_trait() {
    // tests/ui/derives/deriving-meta-unknown-trait.rs

    let source = r#"#[derive(Eqr)]
//~^ ERROR cannot find derive macro `Eqr` in this scope
//~| ERROR cannot find derive macro `Eqr` in this scope
struct Foo;

pub fn main() {}
"#;

    let input = &[
        Level::ERROR
            .primary_title("cannot find derive macro `Eqr` in this scope")
            .element(
                Snippet::source(source)
                    .path("$DIR/deriving-meta-unknown-trait.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(9..12)
                            .label("help: a derive macro with a similar name exists: `Eq`"),
                    ),
            ),
        Group::with_level(Level::ERROR)
            .element(
                Origin::path("$SRC_DIR/core/src/cmp.rs")
                    .line(356)
                    .char_column(0),
            )
            .element(Padding)
            .element(Level::NOTE.message("similarly named derive macro `Eq` defined here"))
            .element(Padding)
            .element(
                Level::NOTE
                    .message("duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`"),
            ),
    ];

    let expected_ascii = str![[r#"
error: cannot find derive macro `Eqr` in this scope
 --> $DIR/deriving-meta-unknown-trait.rs:1:10
  |
1 | #[derive(Eqr)]
  |          ^^^ help: a derive macro with a similar name exists: `Eq`
  |
 --> $SRC_DIR/core/src/cmp.rs:356:0
  |
  = note: similarly named derive macro `Eq` defined here
  |
  = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: cannot find derive macro `Eqr` in this scope
  ╭▸ $DIR/deriving-meta-unknown-trait.rs:1:10
  │
1 │ #[derive(Eqr)]
  │          ━━━ help: a derive macro with a similar name exists: `Eq`
  ╰╴
  ╭▸ $SRC_DIR/core/src/cmp.rs:356:0
  │
  ├ note: similarly named derive macro `Eq` defined here
  │
  ╰ note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn not_repeatable() {
    // tests/ui/proc-macro/quote/not-repeatable.rs

    let source = r#"#![feature(proc_macro_quote)]

extern crate proc_macro;

use proc_macro::quote;

struct Ipv4Addr;

fn main() {
    let ip = Ipv4Addr;
    let _ = quote! { $($ip)* }; //~ ERROR the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
}
"#;
    let label_0 = "method `quote_into_iter` not found for this struct because it doesn't satisfy `Ipv4Addr: Iterator`, `Ipv4Addr: ToTokens`, `Ipv4Addr: proc_macro::ext::RepIteratorExt` or `Ipv4Addr: proc_macro::ext::RepToTokensExt`";
    let title_0 = "the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied";
    let title_1 = r#"the following trait bounds were not satisfied:
`Ipv4Addr: Iterator`
which is required by `Ipv4Addr: proc_macro::ext::RepIteratorExt`
`&Ipv4Addr: Iterator`
which is required by `&Ipv4Addr: proc_macro::ext::RepIteratorExt`
`Ipv4Addr: ToTokens`
which is required by `Ipv4Addr: proc_macro::ext::RepToTokensExt`
`&mut Ipv4Addr: Iterator`
which is required by `&mut Ipv4Addr: proc_macro::ext::RepIteratorExt`"#;

    let input = &[
        Level::ERROR
            .primary_title(title_0)
            .id("E0599")
            .element(
                Snippet::source(source)
                    .path("$DIR/not-repeatable.rs")
                    .annotation(AnnotationKind::Primary.span(146..164).label(
                        "method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds",
                    ))
                    .annotation(AnnotationKind::Context.span(81..96).label(label_0)),
            )
            .element(Level::NOTE.message(title_1)),
        Level::NOTE
            .secondary_title("the traits `Iterator` and `ToTokens` must be implemented")
            .element(
                Origin::path("$SRC_DIR/proc_macro/src/to_tokens.rs")
                    .line(11)
                    .char_column(0),
            ),
        Group::with_level(Level::NOTE).element(
            Origin::path("$SRC_DIR/core/src/iter/traits/iterator.rs")
                .line(39)
                .char_column(0),
        ),
    ];
    let expected_ascii = str![[r#"
error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
  --> $DIR/not-repeatable.rs:11:13
   |
 7 | struct Ipv4Addr;
   | --------------- method `quote_into_iter` not found for this struct because it doesn't satisfy `Ipv4Addr: Iterator`, `Ipv4Addr: ToTokens`, `Ipv4Addr: proc_macro::ext::RepIteratorExt` or `Ipv4Addr: proc_macro::ext::RepToTokensExt`
...
11 |     let _ = quote! { $($ip)* }; //~ ERROR the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not s...
   |             ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
`Ipv4Addr: Iterator`
which is required by `Ipv4Addr: proc_macro::ext::RepIteratorExt`
`&Ipv4Addr: Iterator`
which is required by `&Ipv4Addr: proc_macro::ext::RepIteratorExt`
`Ipv4Addr: ToTokens`
which is required by `Ipv4Addr: proc_macro::ext::RepToTokensExt`
`&mut Ipv4Addr: Iterator`
which is required by `&mut Ipv4Addr: proc_macro::ext::RepIteratorExt`
note: the traits `Iterator` and `ToTokens` must be implemented
  --> $SRC_DIR/proc_macro/src/to_tokens.rs:11:0
  --> $SRC_DIR/core/src/iter/traits/iterator.rs:39:0
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
   ╭▸ $DIR/not-repeatable.rs:11:13
   │
 7 │ struct Ipv4Addr;
   │ ─────────────── method `quote_into_iter` not found for this struct because it doesn't satisfy `Ipv4Addr: Iterator`, `Ipv4Addr: ToTokens`, `Ipv4Addr: proc_macro::ext::RepIteratorExt` or `Ipv4Addr: proc_macro::ext::RepToTokensExt`
   ┆
11 │     let _ = quote! { $($ip)* }; //~ ERROR the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not sat…
   │             ━━━━━━━━━━━━━━━━━━ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
   │
   ╰ note: the following trait bounds were not satisfied:
`Ipv4Addr: Iterator`
which is required by `Ipv4Addr: proc_macro::ext::RepIteratorExt`
`&Ipv4Addr: Iterator`
which is required by `&Ipv4Addr: proc_macro::ext::RepIteratorExt`
`Ipv4Addr: ToTokens`
which is required by `Ipv4Addr: proc_macro::ext::RepToTokensExt`
`&mut Ipv4Addr: Iterator`
which is required by `&mut Ipv4Addr: proc_macro::ext::RepIteratorExt`
note: the traits `Iterator` and `ToTokens` must be implemented
   ─▸ $SRC_DIR/proc_macro/src/to_tokens.rs:11:0
   ─▸ $SRC_DIR/core/src/iter/traits/iterator.rs:39:0
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn not_found_self_type_differs_shadowing_trait_item() {
    // tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs

    let source = r#"#![feature(inherent_associated_types)]
#![allow(incomplete_features)]

// Check that it's okay to report “[inherent] associated type […] not found” for inherent associated
// type candidates that are not applicable (due to unsuitable Self type) even if there exists a
// “shadowed” associated type from a trait with the same name since its use would be ambiguous
// anyway if the IAT didn't exist.
// FIXME(inherent_associated_types): Figure out which error would be more helpful here.

//@ revisions: shadowed uncovered

struct S<T>(T);

trait Tr {
    type Pr;
}

impl<T> Tr for S<T> {
    type Pr = ();
}

#[cfg(shadowed)]
impl S<()> {
    type Pr = i32;
}

fn main() {
    let _: S::<bool>::Pr = ();
    //[shadowed]~^ ERROR associated type `Pr` not found
    //[uncovered]~^^ ERROR associated type `Pr` not found
}
"#;

    let input = &[Level::ERROR
        .primary_title("associated type `Pr` not found for `S<bool>` in the current scope")
        .id("E0220")
        .element(
            Snippet::source(source)
                .path("$DIR/not-found-self-type-differs-shadowing-trait-item.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(705..707)
                        .label("associated item not found in `S<bool>`"),
                )
                .annotation(
                    AnnotationKind::Context
                        .span(532..543)
                        .label("associated type `Pr` not found for this struct"),
                ),
        )
        .element(Level::NOTE.message("the associated type was found for\n"))];

    let expected_ascii = str![[r#"
error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope
  --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23
   |
12 | struct S<T>(T);
   | ----------- associated type `Pr` not found for this struct
...
28 |     let _: S::<bool>::Pr = ();
   |                       ^^ associated item not found in `S<bool>`
   |
   = note: the associated type was found for
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope
   ╭▸ $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23
   │
12 │ struct S<T>(T);
   │ ─────────── associated type `Pr` not found for this struct
   ┆
28 │     let _: S::<bool>::Pr = ();
   │                       ━━ associated item not found in `S<bool>`
   │
   ╰ note: the associated type was found for
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn unsafe_extern_suggestion() {
    // tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.rs

    let source = r#"//@ run-rustfix

#![deny(missing_unsafe_on_extern)]
#![allow(unused)]

extern "C" {
    //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern]
    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
    static TEST1: i32;
    fn test1(i: i32);
}

unsafe extern "C" {
    static TEST2: i32;
    fn test2(i: i32);
}

fn main() {}
"#;

    let title_0 =
        "this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!";
    let title_1 = "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>";

    let input = &[
        Level::ERROR
            .primary_title("extern blocks should be unsafe")
            .element(
                Snippet::source(source)
                    .path("$DIR/unsafe-extern-suggestion.rs")
                    .annotation(
                        AnnotationKind::Context
                            .span(71..71)
                            .label("help: needs `unsafe` before the extern keyword: `unsafe`"),
                    )
                    .annotation(AnnotationKind::Primary.span(71..303)),
            )
            .element(Level::WARNING.message(title_0))
            .element(Level::NOTE.message(title_1)),
        Level::NOTE
            .secondary_title("the lint level is defined here")
            .element(
                Snippet::source(source)
                    .path("$DIR/unsafe-extern-suggestion.rs")
                    .annotation(AnnotationKind::Primary.span(25..49)),
            ),
    ];

    let expected_ascii = str![[r#"
error: extern blocks should be unsafe
  --> $DIR/unsafe-extern-suggestion.rs:6:1
   |
 6 |   extern "C" {
   |   ^
   |   |
   |  _help: needs `unsafe` before the extern keyword: `unsafe`
   | |
 7 | |     //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern]
 8 | |     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
 9 | |     static TEST1: i32;
10 | |     fn test1(i: i32);
11 | | }
   | |_^
   |
   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>
note: the lint level is defined here
  --> $DIR/unsafe-extern-suggestion.rs:3:9
   |
 3 | #![deny(missing_unsafe_on_extern)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: extern blocks should be unsafe
   ╭▸ $DIR/unsafe-extern-suggestion.rs:6:1
   │
 6 │   extern "C" {
   │   ╿
   │   │
   │ ┏━help: needs `unsafe` before the extern keyword: `unsafe`
   │ ┃
 7 │ ┃     //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern]
 8 │ ┃     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
 9 │ ┃     static TEST1: i32;
10 │ ┃     fn test1(i: i32);
11 │ ┃ }
   │ ┗━┛
   │
   ├ warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
   ╰ note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>
note: the lint level is defined here
   ╭▸ $DIR/unsafe-extern-suggestion.rs:3:9
   │
 3 │ #![deny(missing_unsafe_on_extern)]
   ╰╴        ━━━━━━━━━━━━━━━━━━━━━━━━
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn alloc_error_handler_bad_signature_2() {
    // tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs

    let source = r#"//@ compile-flags:-C panic=abort

#![feature(alloc_error_handler)]
#![no_std]
#![no_main]

struct Layout;

#[alloc_error_handler]
fn oom(
    info: Layout, //~^ ERROR mismatched types
) { //~^^ ERROR mismatched types
    loop {}
}

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
"#;
    let title_0 =
        "`core::alloc::Layout` and `Layout` have similar names, but are actually distinct types";

    let input = &[
        Level::ERROR
            .primary_title("mismatched types")
            .id("E0308")
            .element(
                Snippet::source(source)
                    .path("$DIR/alloc-error-handler-bad-signature-2.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(130..230)
                            .label("expected `Layout`, found `core::alloc::Layout`"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(130..185)
                            .label("arguments to this function are incorrect"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(107..129)
                            .label("in this procedural macro expansion"),
                    ),
            )
            .element(Level::NOTE.message(title_0)),
        Level::NOTE
            .secondary_title("`core::alloc::Layout` is defined in crate `core`")
            .element(
                Origin::path("$SRC_DIR/core/src/alloc/layout.rs")
                    .line(40)
                    .char_column(0),
            ),
        Level::NOTE
            .secondary_title("`Layout` is defined in the current crate")
            .element(
                Snippet::source(source)
                    .path("$DIR/alloc-error-handler-bad-signature-2.rs")
                    .annotation(AnnotationKind::Primary.span(91..104)),
            ),
        Level::NOTE
            .secondary_title("function defined here")
            .element(
                Snippet::source(source)
                    .path("$DIR/alloc-error-handler-bad-signature-2.rs")
                    .annotation(AnnotationKind::Context.span(142..154).label(""))
                    .annotation(AnnotationKind::Primary.span(133..136)),
            ),
    ];
    let expected_ascii = str![[r#"
error[E0308]: mismatched types
  --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
   |
 9 |    #[alloc_error_handler]
   |    ---------------------- in this procedural macro expansion
10 | // fn oom(
11 | ||     info: Layout, //~^ ERROR mismatched types
12 | || ) { //~^^ ERROR mismatched types
   | ||_- arguments to this function are incorrect
13 | |      loop {}
14 | |  }
   | |__^ expected `Layout`, found `core::alloc::Layout`
   |
   = note: `core::alloc::Layout` and `Layout` have similar names, but are actually distinct types
note: `core::alloc::Layout` is defined in crate `core`
  --> $SRC_DIR/core/src/alloc/layout.rs:40:0
note: `Layout` is defined in the current crate
  --> $DIR/alloc-error-handler-bad-signature-2.rs:7:1
   |
 7 | struct Layout;
   | ^^^^^^^^^^^^^
note: function defined here
  --> $DIR/alloc-error-handler-bad-signature-2.rs:10:4
   |
10 | fn oom(
   |    ^^^
11 |     info: Layout, //~^ ERROR mismatched types
   |     ------------
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0308]: mismatched types
   ╭▸ $DIR/alloc-error-handler-bad-signature-2.rs:10:1
   │
 9 │    #[alloc_error_handler]
   │    ────────────────────── in this procedural macro expansion
10 │ ┏┌ fn oom(
11 │ ┃│     info: Layout, //~^ ERROR mismatched types
12 │ ┃│ ) { //~^^ ERROR mismatched types
   │ ┃└─┘ arguments to this function are incorrect
13 │ ┃      loop {}
14 │ ┃  }
   │ ┗━━┛ expected `Layout`, found `core::alloc::Layout`
   │
   ╰ note: `core::alloc::Layout` and `Layout` have similar names, but are actually distinct types
note: `core::alloc::Layout` is defined in crate `core`
   ─▸ $SRC_DIR/core/src/alloc/layout.rs:40:0
note: `Layout` is defined in the current crate
   ╭▸ $DIR/alloc-error-handler-bad-signature-2.rs:7:1
   │
 7 │ struct Layout;
   ╰╴━━━━━━━━━━━━━
note: function defined here
   ╭▸ $DIR/alloc-error-handler-bad-signature-2.rs:10:4
   │
10 │ fn oom(
   │    ━━━
11 │     info: Layout, //~^ ERROR mismatched types
   ╰╴    ────────────
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn str_escape() {
    // tests/ui/str/str-escape.rs

    let source = r#"//@ check-pass
// ignore-tidy-tab
//@ edition: 2021

fn main() {
    let s = "\

             ";
    //~^^^ WARNING multiple lines skipped by escaped newline
    assert_eq!(s, "");

    let s = c"foo\
             bar
             ";
    //~^^^ WARNING whitespace symbol '\u{a0}' is not skipped
    assert_eq!(s, c"foo           bar\n             ");

    let s = "a\
 b";
    assert_eq!(s, "ab");

    let s = "a\
	b";
    assert_eq!(s, "ab");

    let s = b"a\
    
    b";
    //~^^ WARNING whitespace symbol '\u{c}' is not skipped
    // '\x0c' is ASCII whitespace, but it may not need skipped
    // discussion: https://github.com/rust-lang/rust/pull/108403
    assert_eq!(s, b"a\x0cb");
}
"#;

    let input = &[Level::WARNING
        .primary_title(r#"whitespace symbol '\u{a0}' is not skipped"#)
        .element(
            Snippet::source(source)
                .path("$DIR/str-escape.rs")
                .annotation(
                    AnnotationKind::Context
                        .span(203..205)
                        .label(r#"whitespace symbol '\u{a0}' is not skipped"#),
                )
                .annotation(AnnotationKind::Primary.span(199..205)),
        )];
    let expected_ascii = str![[r#"
warning: whitespace symbol '\u{a0}' is not skipped
  --> $DIR/str-escape.rs:12:18
   |
12 |       let s = c"foo\
   |  __________________^
13 | |              bar
   | |   ^ whitespace symbol '\u{a0}' is not skipped
   | |___|
   |
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii.raw());

    let expected_unicode = str![[r#"
warning: whitespace symbol '\u{a0}' is not skipped
   ╭▸ $DIR/str-escape.rs:12:18
   │
12 │       let s = c"foo\
   │ ┏━━━━━━━━━━━━━━━━━━┛
13 │ ┃              bar
   │ ┃   ╿ whitespace symbol '\u{a0}' is not skipped
   │ ┗━━━│
   ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode.raw());
}

#[test]
fn origin_path_repeated() {
    // tests/ui/pattern/usefulness/match-privately-empty.rs
    let source = r#"//@ revisions: normal exhaustive_patterns
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![feature(never_type)]

mod private {
    pub struct Private {
        _bot: !,
        pub misc: bool,
    }
    pub const DATA: Option<Private> = None;
}

fn main() {
    match private::DATA {
        //~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
        None => {}
        Some(private::Private { misc: false, .. }) => {}
    }
}
"#;
    let title_0 = "non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered";
    let title_1 = "`Option<Private>` defined here";
    let title_2 = "ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown";

    let input = &[
        Level::ERROR.primary_title(title_0).id("E0004").element(
            Snippet::source(source)
                .path("$DIR/match-privately-empty.rs")
                .annotation(
                    AnnotationKind::Primary
                        .span(286..299)
                        .label("pattern `Some(Private { misc: true, .. })` not covered"),
                ),
        ),
        Level::NOTE
            .secondary_title(title_1)
            .element(
                Origin::path("$SRC_DIR/core/src/option.rs")
                    .line(593)
                    .char_column(0),
            )
            .element(
                Origin::path("$SRC_DIR/core/src/option.rs")
                    .line(601)
                    .char_column(4),
            )
            .element(Padding)
            .element(Level::NOTE.message("not covered"))
            .element(Level::NOTE.message("the matched value is of type `Option<Private>`")),
        Level::HELP.secondary_title(title_2).element(
            Snippet::source(source)
                .path("$DIR/match-privately-empty.rs")
                .line_start(17)
                .fold(true)
                .patch(Patch::new(
                    468..468,
                    ",
        Some(Private { misc: true, .. }) => todo!()",
                )),
        ),
    ];
    let expected_ascii = str![[r#"
error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
   ╭▸ $DIR/match-privately-empty.rs:14:11
   │
14 │     match private::DATA {
   │           ━━━━━━━━━━━━━ pattern `Some(Private { misc: true, .. })` not covered
   ╰╴
note: `Option<Private>` defined here
   ╭▸ $SRC_DIR/core/src/option.rs:593:0
   ⸬  $SRC_DIR/core/src/option.rs:601:4
   │
   ├ note: not covered
   ╰ note: the matched value is of type `Option<Private>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
   ╭╴
33 ±         Some(private::Private { misc: false, .. }) => {},
34 +         Some(Private { misc: true, .. }) => todo!()
   ╰╴
"#]];
    let renderer = Renderer::plain().decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
   ╭▸ $DIR/match-privately-empty.rs:14:11
   │
14 │     match private::DATA {
   │           ━━━━━━━━━━━━━ pattern `Some(Private { misc: true, .. })` not covered
   ╰╴
note: `Option<Private>` defined here
   ╭▸ $SRC_DIR/core/src/option.rs:593:0
   ⸬  $SRC_DIR/core/src/option.rs:601:4
   │
   ├ note: not covered
   ╰ note: the matched value is of type `Option<Private>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
   ╭╴
33 ±         Some(private::Private { misc: false, .. }) => {},
34 +         Some(Private { misc: true, .. }) => todo!()
   ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn origin_path_repeated_element_between() {
    // tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.rs
    let source = r#"//@ revisions: old new
//@[old] edition:2015
//@[new] edition:2021
//@[new] run-rustfix
#![deny(bare_trait_objects)]
fn ord_prefer_dot(s: String) -> Ord {
    //[new]~^ ERROR expected a type, found a trait
    //[old]~^^ ERROR the trait `Ord` is not dyn compatible
    //[old]~| ERROR trait objects without an explicit `dyn` are deprecated
    //[old]~| WARNING this is accepted in the current edition (Rust 2015)
    (s.starts_with("."), s)
}
fn main() {
    let _ = ord_prefer_dot(String::new());
}
"#;
    let title_0 = "for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>";

    let input = &[
        Level::ERROR
            .primary_title("the trait `Ord` is not dyn compatible")
            .id("E0038")
            .element(
                Snippet::source(source)
                    .path("$DIR/bare-trait-dont-suggest-dyn.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(149..152)
                            .label("`Ord` is not dyn compatible"),
                    ),
            ),
        Level::NOTE
            .secondary_title(title_0)
            .element(
                Origin::path("$SRC_DIR/core/src/cmp.rs")
                    .line(961)
                    .char_column(20),
            )
            .element(Padding)
            .element(Level::NOTE.message(
                "the trait is not dyn compatible because it uses `Self` as a type parameter",
            ))
            .element(
                Origin::path("$SRC_DIR/core/src/cmp.rs")
                    .line(338)
                    .char_column(14),
            )
            .element(Padding)
            .element(Level::NOTE.message(
                "the trait is not dyn compatible because it uses `Self` as a type parameter",
            )),
        Level::HELP
            .secondary_title("consider using an opaque type instead")
            .element(
                Snippet::source(source)
                    .path("$DIR/bare-trait-dont-suggest-dyn.rs")
                    .line_start(6)
                    .fold(true)
                    .patch(Patch::new(149..149, "impl ")),
            ),
    ];
    let expected_ascii = str![[r#"
error[E0038]: the trait `Ord` is not dyn compatible
   ╭▸ $DIR/bare-trait-dont-suggest-dyn.rs:6:33
   │
 6 │ fn ord_prefer_dot(s: String) -> Ord {
   │                                 ━━━ `Ord` is not dyn compatible
   ╰╴
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   ╭▸ $SRC_DIR/core/src/cmp.rs:961:20
   │
   ├ note: the trait is not dyn compatible because it uses `Self` as a type parameter
   ⸬  $SRC_DIR/core/src/cmp.rs:338:14
   │
   ╰ note: the trait is not dyn compatible because it uses `Self` as a type parameter
help: consider using an opaque type instead
   ╭╴
11 │ fn ord_prefer_dot(s: String) -> impl Ord {
   ╰╴                                ++++
"#]];
    let renderer = Renderer::plain().decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0038]: the trait `Ord` is not dyn compatible
   ╭▸ $DIR/bare-trait-dont-suggest-dyn.rs:6:33
   │
 6 │ fn ord_prefer_dot(s: String) -> Ord {
   │                                 ━━━ `Ord` is not dyn compatible
   ╰╴
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   ╭▸ $SRC_DIR/core/src/cmp.rs:961:20
   │
   ├ note: the trait is not dyn compatible because it uses `Self` as a type parameter
   ⸬  $SRC_DIR/core/src/cmp.rs:338:14
   │
   ╰ note: the trait is not dyn compatible because it uses `Self` as a type parameter
help: consider using an opaque type instead
   ╭╴
11 │ fn ord_prefer_dot(s: String) -> impl Ord {
   ╰╴                                ++++
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn multiple_origin() {
    // tests/ui/binop/binary-op-not-allowed-issue-125631.rs
    let source_0 = r#"use std::io::{Error, ErrorKind};
use std::thread;

struct T1;
struct T2;

fn main() {
    (Error::new(ErrorKind::Other, "1"), T1, 1) == (Error::new(ErrorKind::Other, "1"), T1, 2);
    //~^ERROR binary operation `==` cannot be applied to type
    (Error::new(ErrorKind::Other, "2"), thread::current())
        == (Error::new(ErrorKind::Other, "2"), thread::current());
    //~^ERROR binary operation `==` cannot be applied to type
    (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2)
        == (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2);
    //~^ERROR binary operation `==` cannot be applied to type
}
"#;
    let title_0 =
        "the foreign item types don't implement required traits for this operation to be valid";

    let input = &[
        Level::ERROR
            .primary_title(
                "binary operation `==` cannot be applied to type `(std::io::Error, Thread)`",
            )
            .id("E0369")
            .element(
                Snippet::source(source_0)
                    .path("$DIR/binary-op-not-allowed-issue-125631.rs")
                    .annotation(
                        AnnotationKind::Context
                            .span(246..300)
                            .label("(std::io::Error, Thread)"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(312..366)
                            .label("(std::io::Error, Thread)"),
                    )
                    .annotation(AnnotationKind::Primary.span(309..311)),
            ),
        Level::NOTE
            .secondary_title(title_0)
            .element(
                Origin::path("$SRC_DIR/std/src/io/error.rs")
                    .line(65)
                    .char_column(0),
            )
            .element(Padding)
            .element(Level::NOTE.message("not implement `PartialEq`")),
        Group::with_level(Level::NOTE)
            .element(
                Origin::path("$SRC_DIR/std/src/thread/mod.rs")
                    .line(1439)
                    .char_column(0),
            )
            .element(Padding)
            .element(Level::NOTE.message("not implement `PartialEq`")),
    ];
    let expected_ascii = str![[r#"
error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread)`
   ╭▸ $DIR/binary-op-not-allowed-issue-125631.rs:11:9
   │
10 │     (Error::new(ErrorKind::Other, "2"), thread::current())
   │     ────────────────────────────────────────────────────── (std::io::Error, Thread)
11 │         == (Error::new(ErrorKind::Other, "2"), thread::current());
   │         ━━ ────────────────────────────────────────────────────── (std::io::Error, Thread)
   ╰╴
note: the foreign item types don't implement required traits for this operation to be valid
   ╭▸ $SRC_DIR/std/src/io/error.rs:65:0
   │
   ╰ note: not implement `PartialEq`
   ╭▸ $SRC_DIR/std/src/thread/mod.rs:1439:0
   │
   ╰ note: not implement `PartialEq`
"#]];
    let renderer = Renderer::plain().decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread)`
   ╭▸ $DIR/binary-op-not-allowed-issue-125631.rs:11:9
   │
10 │     (Error::new(ErrorKind::Other, "2"), thread::current())
   │     ────────────────────────────────────────────────────── (std::io::Error, Thread)
11 │         == (Error::new(ErrorKind::Other, "2"), thread::current());
   │         ━━ ────────────────────────────────────────────────────── (std::io::Error, Thread)
   ╰╴
note: the foreign item types don't implement required traits for this operation to be valid
   ╭▸ $SRC_DIR/std/src/io/error.rs:65:0
   │
   ╰ note: not implement `PartialEq`
   ╭▸ $SRC_DIR/std/src/thread/mod.rs:1439:0
   │
   ╰ note: not implement `PartialEq`
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn const_generics_issue_82656() {
    // tests/ui/const-generics/issues/issue-82956.rs
    let source = r#"#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

pub struct ConstCheck<const CHECK: bool>;

pub trait True {}
impl True for ConstCheck<true> {}

pub trait OrdesDec {
    type Newlen;
    type Output;

    fn pop(self) -> (Self::Newlen, Self::Output);
}

impl<T, const N: usize> OrdesDec for [T; N]
where
    ConstCheck<{N > 1}>: True,
    [T; N - 1]: Sized,
{
    type Newlen = [T; N - 1];
    type Output = T;

    fn pop(self) -> (Self::Newlen, Self::Output) {
        let mut iter = IntoIter::new(self);
        //~^ ERROR: failed to resolve: use of undeclared type `IntoIter`
        let end = iter.next_back().unwrap();
        let new = [(); N - 1].map(move |()| iter.next().unwrap());
        (new, end)
    }
}

fn main() {}
"#;

    let input = &[
        Level::ERROR
            .primary_title("failed to resolve: use of undeclared type `IntoIter`")
            .id("E0433")
            .element(
                Snippet::source(source)
                    .path("$DIR/issue-82956.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(502..510)
                            .label("use of undeclared type `IntoIter`"),
                    ),
            ),
        Level::HELP
            .secondary_title("consider importing one of these structs")
            .element(
                Snippet::source(source)
                    .path("$DIR/issue-82956.rs")
                    .patch(Patch::new(65..65, "use std::array::IntoIter;\n\n")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/issue-82956.rs")
                    .patch(Patch::new(
                        65..65,
                        "use std::collections::binary_heap::IntoIter;\n\n",
                    )),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/issue-82956.rs")
                    .patch(Patch::new(
                        65..65,
                        "use std::collections::btree_map::IntoIter;\n\n",
                    )),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/issue-82956.rs")
                    .patch(Patch::new(
                        65..65,
                        "use std::collections::btree_set::IntoIter;\n\n",
                    )),
            )
            .element(Level::NOTE.no_name().message("and 9 other candidates")),
    ];

    let expected_ascii = str![[r#"
error[E0433]: failed to resolve: use of undeclared type `IntoIter`
  --> $DIR/issue-82956.rs:25:24
   |
25 |         let mut iter = IntoIter::new(self);
   |                        ^^^^^^^^ use of undeclared type `IntoIter`
   |
help: consider importing one of these structs
   |
 4 + use std::array::IntoIter;
   |
 4 + use std::collections::binary_heap::IntoIter;
   |
 4 + use std::collections::btree_map::IntoIter;
   |
 4 + use std::collections::btree_set::IntoIter;
   |
   = and 9 other candidates
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0433]: failed to resolve: use of undeclared type `IntoIter`
   ╭▸ $DIR/issue-82956.rs:25:24
   │
25 │         let mut iter = IntoIter::new(self);
   │                        ━━━━━━━━ use of undeclared type `IntoIter`
   ╰╴
help: consider importing one of these structs
   ╭╴
 4 + use std::array::IntoIter;
   ├╴
 4 + use std::collections::binary_heap::IntoIter;
   ├╴
 4 + use std::collections::btree_map::IntoIter;
   ├╴
 4 + use std::collections::btree_set::IntoIter;
   │
   ╰ and 9 other candidates
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn multi_suggestion() {
    // tests/ui/suggestions/multi-suggestion.rs
    let source = r#"//@ revisions: ascii unicode
//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode

#![allow(dead_code)]
struct U <T> {
    wtf: Option<Box<U<T>>>,
    x: T,
}
fn main() {
    U {
        wtf: Some(Box(U { //[ascii]~ ERROR cannot initialize a tuple struct which contains private fields
            wtf: None,
            x: (),
        })),
        x: ()
    };
    let _ = std::collections::HashMap();
    //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap`
    let _ = std::collections::HashMap {};
    //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields
    let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields
}
"#;
    let title_0 = "expected function, tuple struct or tuple variant, found struct `std::collections::HashMap`";

    let input = &[
        Level::ERROR
            .primary_title(title_0)
            .id("E0423")
            .element(
                Snippet::source(source)
                    .path("$DIR/multi-suggestion.rs")
                    .annotation(AnnotationKind::Primary.span(396..423)),
            )
            .element(
                Origin::path("$SRC_DIR/std/src/collections/hash/map.rs")
                    .line(242)
                    .char_column(0),
            )
            .element(Padding)
            .element(Level::NOTE.message("`std::collections::HashMap` defined here"))
            .element(Padding),
        Level::HELP
            .secondary_title(
                "you might have meant to use an associated function to build this type",
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/multi-suggestion.rs")
                    .patch(Patch::new(421..423, "::new()")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/multi-suggestion.rs")
                    .patch(Patch::new(421..423, "::with_capacity(_)")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/multi-suggestion.rs")
                    .patch(Patch::new(421..423, "::with_hasher(_)")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/multi-suggestion.rs")
                    .patch(Patch::new(421..423, "::with_capacity_and_hasher(_, _)")),
            ),
        Level::HELP
            .secondary_title("consider using the `Default` trait")
            .element(
                Snippet::source(source)
                    .path("$DIR/multi-suggestion.rs")
                    .patch(Patch::new(396..396, "<"))
                    .patch(Patch::new(
                        421..423,
                        " as std::default::Default>::default()",
                    )),
            ),
    ];

    let expected_ascii = str![[r#"
error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap`
  --> $DIR/multi-suggestion.rs:17:13
   |
17 |     let _ = std::collections::HashMap();
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ::: $SRC_DIR/std/src/collections/hash/map.rs:242:0
   |
   = note: `std::collections::HashMap` defined here
   |
help: you might have meant to use an associated function to build this type
   |
17 |     let _ = std::collections::HashMap::new();
   |                                      +++++
17 -     let _ = std::collections::HashMap();
17 +     let _ = std::collections::HashMap::with_capacity(_);
   |
17 -     let _ = std::collections::HashMap();
17 +     let _ = std::collections::HashMap::with_hasher(_);
   |
17 -     let _ = std::collections::HashMap();
17 +     let _ = std::collections::HashMap::with_capacity_and_hasher(_, _);
   |
help: consider using the `Default` trait
   |
17 |     let _ = <std::collections::HashMap as std::default::Default>::default();
   |             +                          ++++++++++++++++++++++++++++++++++
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap`
   ╭▸ $DIR/multi-suggestion.rs:17:13
   │
17 │     let _ = std::collections::HashMap();
   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━
   ⸬  $SRC_DIR/std/src/collections/hash/map.rs:242:0
   │
   ├ note: `std::collections::HashMap` defined here
   ╰╴
help: you might have meant to use an associated function to build this type
   ╭╴
17 │     let _ = std::collections::HashMap::new();
   ├╴                                     +++++
17 -     let _ = std::collections::HashMap();
17 +     let _ = std::collections::HashMap::with_capacity(_);
   ├╴
17 -     let _ = std::collections::HashMap();
17 +     let _ = std::collections::HashMap::with_hasher(_);
   ├╴
17 -     let _ = std::collections::HashMap();
17 +     let _ = std::collections::HashMap::with_capacity_and_hasher(_, _);
   ╰╴
help: consider using the `Default` trait
   ╭╴
17 │     let _ = <std::collections::HashMap as std::default::Default>::default();
   ╰╴            +                          ++++++++++++++++++++++++++++++++++
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn suggest_box_new() {
    // tests/ui/privacy/suggest-box-new.rs
    let source = r#"//@ revisions: ascii unicode
//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode

#![allow(dead_code)]
struct U <T> {
    wtf: Option<Box<U<T>>>,
    x: T,
}
fn main() {
    U {
        wtf: Some(Box(U {
            wtf: None,
            x: (),
        })),
        x: ()
    };
    let _ = std::collections::HashMap();
    //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap`
    let _ = std::collections::HashMap {};
    //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields
    let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields
}
"#;

    let input = &[
        Level::ERROR
            .primary_title("cannot initialize a tuple struct which contains private fields")
            .id("E0423")
            .element(
                Snippet::source(source)
                    .path("$DIR/suggest-box-new.rs")
                    .annotation(AnnotationKind::Primary.span(220..223)),
            ),
        Level::NOTE
            .secondary_title("constructor is not visible here due to private fields")
            .element(
                Origin::path("$SRC_DIR/alloc/src/boxed.rs")
                    .line(234)
                    .char_column(2),
            )
            .element(Padding)
            .element(Level::NOTE.message("private field"))
            .element(Padding)
            .element(Level::NOTE.message("private field")),
        Level::HELP
            .secondary_title(
                "you might have meant to use an associated function to build this type",
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/suggest-box-new.rs")
                    .patch(Patch::new(223..280, "::new(_)")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/suggest-box-new.rs")
                    .patch(Patch::new(223..280, "::new_uninit()")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/suggest-box-new.rs")
                    .patch(Patch::new(223..280, "::new_zeroed()")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/suggest-box-new.rs")
                    .patch(Patch::new(223..280, "::new_in(_, _)")),
            )
            .element(Level::NOTE.no_name().message("and 12 other candidates")),
        Level::HELP
            .secondary_title("consider using the `Default` trait")
            .element(
                Snippet::source(source)
                    .path("$DIR/suggest-box-new.rs")
                    .patch(Patch::new(220..220, "<"))
                    .patch(Patch::new(
                        223..280,
                        " as std::default::Default>::default()",
                    )),
            ),
    ];

    let expected_ascii = str![[r#"
error[E0423]: cannot initialize a tuple struct which contains private fields
  --> $DIR/suggest-box-new.rs:11:19
   |
11 |         wtf: Some(Box(U {
   |                   ^^^
   |
note: constructor is not visible here due to private fields
  --> $SRC_DIR/alloc/src/boxed.rs:234:2
   |
   = note: private field
   |
   = note: private field
help: you might have meant to use an associated function to build this type
   |
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new(_)),
   |
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new_uninit()),
   |
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new_zeroed()),
   |
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new_in(_, _)),
   |
   = and 12 other candidates
help: consider using the `Default` trait
   |
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(<Box as std::default::Default>::default()),
   |
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0423]: cannot initialize a tuple struct which contains private fields
   ╭▸ $DIR/suggest-box-new.rs:11:19
   │
11 │         wtf: Some(Box(U {
   │                   ━━━
   ╰╴
note: constructor is not visible here due to private fields
   ╭▸ $SRC_DIR/alloc/src/boxed.rs:234:2
   │
   ├ note: private field
   │
   ╰ note: private field
help: you might have meant to use an associated function to build this type
   ╭╴
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new(_)),
   ├╴
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new_uninit()),
   ├╴
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new_zeroed()),
   ├╴
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(Box::new_in(_, _)),
   │
   ╰ and 12 other candidates
help: consider using the `Default` trait
   ╭╴
11 -         wtf: Some(Box(U {
12 -             wtf: None,
13 -             x: (),
14 -         })),
11 +         wtf: Some(<Box as std::default::Default>::default()),
   ╰╴
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn too_many_field_suggestions() {
    // tests/ui/suggestions/too-many-field-suggestions.rs
    let source = r#"struct Thing {
    a0: Foo,
    a1: Foo,
    a2: Foo,
    a3: Foo,
    a4: Foo,
    a5: Foo,
    a6: Foo,
    a7: Foo,
    a8: Foo,
    a9: Foo,
}

struct Foo {
    field: Field,
}

struct Field;

impl Foo {
    fn bar(&self) {}
}

fn bar(t: Thing) {
    t.bar();
    t.field;
}

fn main() {}
"#;

    let input = &[
        Level::ERROR
            .primary_title("no method named `bar` found for struct `Thing` in the current scope")
            .id("E0599")
            .element(
                Snippet::source(source)
                    .path("$DIR/too-many-field-suggestions.rs")
                    .annotation(
                        AnnotationKind::Primary
                            .span(257..260)
                            .label("method not found in `Thing`"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(0..12)
                            .label("method `bar` not found for this struct"),
                    ),
            ),
        Level::HELP
            .secondary_title("some of the expressions' fields have a method of the same name")
            .element(
                Snippet::source(source)
                    .path("$DIR/too-many-field-suggestions.rs")
                    .patch(Patch::new(257..257, "a0.")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/too-many-field-suggestions.rs")
                    .patch(Patch::new(257..257, "a1.")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/too-many-field-suggestions.rs")
                    .patch(Patch::new(257..257, "a2.")),
            )
            .element(
                Snippet::source(source)
                    .path("$DIR/too-many-field-suggestions.rs")
                    .patch(Patch::new(257..257, "a3.")),
            )
            .element(Level::NOTE.no_name().message("and 6 other candidates")),
    ];

    let expected_ascii = str![[r#"
error[E0599]: no method named `bar` found for struct `Thing` in the current scope
  --> $DIR/too-many-field-suggestions.rs:25:7
   |
 1 | struct Thing {
   | ------------ method `bar` not found for this struct
...
25 |     t.bar();
   |       ^^^ method not found in `Thing`
   |
help: some of the expressions' fields have a method of the same name
   |
25 |     t.a0.bar();
   |       +++
25 |     t.a1.bar();
   |       +++
25 |     t.a2.bar();
   |       +++
25 |     t.a3.bar();
   |       +++
   = and 6 other candidates
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error[E0599]: no method named `bar` found for struct `Thing` in the current scope
   ╭▸ $DIR/too-many-field-suggestions.rs:25:7
   │
 1 │ struct Thing {
   │ ──────────── method `bar` not found for this struct
   ┆
25 │     t.bar();
   │       ━━━ method not found in `Thing`
   ╰╴
help: some of the expressions' fields have a method of the same name
   ╭╴
25 │     t.a0.bar();
   ├╴      +++
25 │     t.a1.bar();
   ├╴      +++
25 │     t.a2.bar();
   ├╴      +++
25 │     t.a3.bar();
   │       +++
   ╰ and 6 other candidates
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn invalid_arguments_unterminated() {
    // tests/ui/check-cfg/invalid-arguments.unterminated.rs
    let input = &[Level::ERROR
        .primary_title("invalid `--check-cfg` argument: `cfg(`")
        .element(
            Level::NOTE
                .message(r#"expected `cfg(name, values("value1", "value2", ... "valueN"))`"#),
        )
        .element(Level::NOTE.message(
            "visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details",
        ))];
    let expected_ascii = str![[r#"
error: invalid `--check-cfg` argument: `cfg(`
 |
 = note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
 = note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: invalid `--check-cfg` argument: `cfg(`
 │
 ├ note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
 ╰ note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn timeout() {
    // tests/ui/consts/timeout.rs
    let source = r#"//! This test checks that external macros don't hide
//! the const eval timeout lint and then subsequently
//! ICE.

//@ compile-flags: --crate-type=lib -Ztiny-const-eval-limit

static ROOK_ATTACKS_TABLE: () = {
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
    0_u64.count_ones();
};

//~? ERROR constant evaluation is taking a long time
"#;

    let title_0 =
        "this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
If your compilation actually takes a long time, you can safely allow the lint.";
    let title_1 = "this error originates in the macro `uint_impl` (in Nightly builds, run with -Z macro-backtrace for more info)";

    let input = &[
        Level::ERROR
            .primary_title("constant evaluation is taking a long time")
            .element(
                Origin::path("$SRC_DIR/core/src/num/mod.rs")
                    .line(1151)
                    .char_column(4),
            )
            .element(Level::NOTE.message(title_0)),
        Level::HELP
            .secondary_title("the constant being evaluated")
            .element(
                Snippet::source(source)
                    .path("$DIR/timeout.rs")
                    .annotation(AnnotationKind::Primary.span(178..207)),
            )
            .element(Level::NOTE.message("`#[deny(long_running_const_eval)]` on by default"))
            .element(Level::NOTE.message(title_1)),
    ];
    let expected_ascii = str![[r#"
error: constant evaluation is taking a long time
 --> $SRC_DIR/core/src/num/mod.rs:1151:4
  = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
If your compilation actually takes a long time, you can safely allow the lint.
help: the constant being evaluated
 --> $DIR/timeout.rs:7:1
  |
7 | static ROOK_ATTACKS_TABLE: () = {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: `#[deny(long_running_const_eval)]` on by default
  = note: this error originates in the macro `uint_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
"#]];
    let renderer = Renderer::plain();
    assert_data_eq!(renderer.render(input), expected_ascii);

    let expected_unicode = str![[r#"
error: constant evaluation is taking a long time
  ╭▸ $SRC_DIR/core/src/num/mod.rs:1151:4
  ╰ note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
If your compilation actually takes a long time, you can safely allow the lint.
help: the constant being evaluated
  ╭▸ $DIR/timeout.rs:7:1
  │
7 │ static ROOK_ATTACKS_TABLE: () = {
  │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ├ note: `#[deny(long_running_const_eval)]` on by default
  ╰ note: this error originates in the macro `uint_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
"#]];
    let renderer = renderer.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer.render(input), expected_unicode);
}

#[test]
fn emitter_overflow_bad_whitespace() {
    // tests/ui/errors/emitter-overflow-bad-whitespace.rs
    let source = r#"                                         fn main() {              return;              }
"#;
    let title_0 = "Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not";

    let report = &[
        Group::with_title(Level::ERROR.primary_title("unknown start of token: \u{a0}")).element(
            Snippet::source(source)
                .path("$DIR/emitter-overflow-bad-whitespace.rs")
                .line_start(10)
                .annotation(AnnotationKind::Primary.span(0..2)),
        ),
        Group::with_title(Level::HELP.secondary_title(title_0)).element(
            Snippet::source(source)
                .path("$DIR/emitter-overflow-bad-whitespace.rs")
                .line_start(10)
                .patch(Patch::new(0..2, " ")),
        ),
    ];
    let expected_ascii = str![[r#"
error: unknown start of token:  
  --> $DIR/emitter-overflow-bad-whitespace.rs:10:1
   |
10 |     ...
   | ^
   |
help: Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not
   |
10 |                                          fn main() {              return;              }
   | +
"#]];
    let renderer_ascii = Renderer::plain().term_width(1);
    assert_data_eq!(renderer_ascii.render(report), expected_ascii);

    let expected_unicode = str![[r#"
error: unknown start of token:  
   ╭▸ $DIR/emitter-overflow-bad-whitespace.rs:10:1
   │
10 │       …
   │ ━
   ╰╴
help: Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not
   ╭╴
10 │                                          fn main() {              return;              }
   ╰╴+
"#]];
    let renderer_unicode = renderer_ascii.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer_unicode.render(report), expected_unicode);
}

#[test]
fn issue_109854() {
    // tests/ui/suggestions/issue-109854.rs
    let source_0 = r##"    String::with_capacity(
    //~^ ERROR this function takes 1 argument but 3 arguments were supplied
    generate_setter,
    r#"
pub(crate) struct Person<T: Clone> {}
"#,
     r#""#,
"##;
    let source_1 = r#"    generate_setter,
"#;
    let title_0 = "expected type `[22;1;35musize[22;39m`
found fn item `[22;1;35mfn() {generate_setter}[22;39m`";
    let source_2 = r##"    generate_setter,
    r#"
pub(crate) struct Person<T: Clone> {}
"#,
     r#""#,
"##;

    let report = &[
        Level::ERROR
            .primary_title("this function takes 1 argument but 3 arguments were supplied")
            .id("E0061")
            .element(
                Snippet::source(source_0)
                    .path("$DIR/issue-109854.rs")
                    .line_start(2)
                    .annotation(AnnotationKind::Primary.span(4..25))
                    .annotation(
                        AnnotationKind::Context
                            .span(128..172)
                            .label("unexpected argument #2 of type `&'static str`"),
                    )
                    .annotation(
                        AnnotationKind::Context
                            .span(179..184)
                            .label("unexpected argument #3 of type `&'static str`"),
                    ),
            ),
        Level::NOTE
            .secondary_title("expected `usize`, found fn item")
            .element(
                Snippet::source(source_1)
                    .path("$DIR/issue-109854.rs")
                    .line_start(4)
                    .annotation(AnnotationKind::Primary.span(4..19)),
            )
            .element(Level::NOTE.message(title_0)),
        Level::NOTE
            .secondary_title("associated function defined here")
            .element(
                Origin::path("$SRC_DIR/alloc/src/string.rs")
                    .line(480)
                    .char_column(11),
            ),
        Level::HELP
            .secondary_title("remove the extra arguments")
            .element(
                Snippet::source(source_2)
                    .path("$DIR/issue-109854.rs")
                    .line_start(4)
                    .patch(Patch::new(4..19, "/* usize */"))
                    .patch(Patch::new(19..69, ""))
                    .patch(Patch::new(69..81, "")),
            ),
    ];
    let expected_ascii = str![[r##"
error[E0061]: this function takes 1 argument but 3 arguments were supplied
 --> $DIR/issue-109854.rs:2:5
  |
2 |       String::with_capacity(
  |       ^^^^^^^^^^^^^^^^^^^^^
...
5 | /     r#"
6 | | pub(crate) struct Person<T: Clone> {}
7 | | "#,
  | |__- unexpected argument #2 of type `&'static str`
8 |        r#""#,
  |        ----- unexpected argument #3 of type `&'static str`
  |
note: expected `usize`, found fn item
 --> $DIR/issue-109854.rs:4:5
  |
4 |     generate_setter,
  |     ^^^^^^^^^^^^^^^
  = note: expected type `[22;1;35musize[22;39m`
found fn item `[22;1;35mfn() {generate_setter}[22;39m`
note: associated function defined here
 --> $SRC_DIR/alloc/src/string.rs:480:11
help: remove the extra arguments
  |
4 -     generate_setter,
5 -     r#"
6 - pub(crate) struct Person<T: Clone> {}
7 - "#,
8 -      r#""#,
4 +     /* usize */,
  |
"##]];
    let renderer_ascii = Renderer::plain();
    assert_data_eq!(renderer_ascii.render(report), expected_ascii);

    let expected_unicode = str![[r##"
error[E0061]: this function takes 1 argument but 3 arguments were supplied
  ╭▸ $DIR/issue-109854.rs:2:5
  │
2 │       String::with_capacity(
  │       ━━━━━━━━━━━━━━━━━━━━━
  ┆
5 │ ┌     r#"
6 │ │ pub(crate) struct Person<T: Clone> {}
7 │ │ "#,
  │ └──┘ unexpected argument #2 of type `&'static str`
8 │        r#""#,
  │        ───── unexpected argument #3 of type `&'static str`
  ╰╴
note: expected `usize`, found fn item
  ╭▸ $DIR/issue-109854.rs:4:5
  │
4 │     generate_setter,
  │     ━━━━━━━━━━━━━━━
  ╰ note: expected type `[22;1;35musize[22;39m`
found fn item `[22;1;35mfn() {generate_setter}[22;39m`
note: associated function defined here
  ─▸ $SRC_DIR/alloc/src/string.rs:480:11
help: remove the extra arguments
  ╭╴
4 -     generate_setter,
5 -     r#"
6 - pub(crate) struct Person<T: Clone> {}
7 - "#,
8 -      r#""#,
4 +     /* usize */,
  ╰╴
"##]];
    let renderer_unicode = renderer_ascii.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer_unicode.render(report), expected_unicode);
}

#[test]
fn match_same_arms() {
    // src/tools/clippy/tests/ui/match_same_arms.rs
    let source = r#"        2 => 'b',
        3 => 'b',
        _ => 'b',
"#;

    let report = &[
        Level::ERROR
            .primary_title("these match arms have identical bodies")
            .element(
                Snippet::source(source)
                    .path("tests/ui/match_same_arms.rs")
                    .line_start(20)
                    .annotation(AnnotationKind::Primary.span(8..16))
                    .annotation(AnnotationKind::Primary.span(26..34))
                    .annotation(
                        AnnotationKind::Primary
                            .span(44..52)
                            .label("the wildcard arm"),
                    ),
            )
            .element(
                Level::HELP
                    .message("if this is unintentional make the arms return different values"),
            ),
        Level::HELP
            .secondary_title("otherwise remove the non-wildcard arms")
            .element(
                Snippet::source(source)
                    .path("tests/ui/match_same_arms.rs")
                    .line_start(20)
                    .patch(Patch::new(8..26, ""))
                    .patch(Patch::new(26..44, "")),
            ),
    ];
    let expected_ascii = str![[r#"
error: these match arms have identical bodies
  --> tests/ui/match_same_arms.rs:20:9
   |
20 |         2 => 'b',
   |         ^^^^^^^^
21 |         3 => 'b',
   |         ^^^^^^^^
22 |         _ => 'b',
   |         ^^^^^^^^ the wildcard arm
   |
   = help: if this is unintentional make the arms return different values
help: otherwise remove the non-wildcard arms
   |
20 -         2 => 'b',
21 -         3 => 'b',
   |
"#]];
    let renderer_ascii = Renderer::plain();
    assert_data_eq!(renderer_ascii.render(report), expected_ascii);

    let expected_unicode = str![[r#"
error: these match arms have identical bodies
   ╭▸ tests/ui/match_same_arms.rs:20:9
   │
20 │         2 => 'b',
   │         ━━━━━━━━
21 │         3 => 'b',
   │         ━━━━━━━━
22 │         _ => 'b',
   │         ━━━━━━━━ the wildcard arm
   │
   ╰ help: if this is unintentional make the arms return different values
help: otherwise remove the non-wildcard arms
   ╭╴
20 -         2 => 'b',
21 -         3 => 'b',
   ╰╴
"#]];
    let renderer_unicode = renderer_ascii.decor_style(DecorStyle::Unicode);
    assert_data_eq!(renderer_unicode.render(report), expected_unicode);
}
