about summary refs log tree commit diff
path: root/compiler/rustc_expand/src
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-05-03 09:26:34 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2024-05-06 09:06:02 +1000
commit2acbe9c7438478b022fa52e54ba3ceb8ca570c20 (patch)
tree7f15534ca6ba98686bfce608a293379046a14f14 /compiler/rustc_expand/src
parent9c9b568792ef20d8459c745345dd3e79b7c7fa8c (diff)
downloadrust-2acbe9c7438478b022fa52e54ba3ceb8ca570c20.tar.gz
rust-2acbe9c7438478b022fa52e54ba3ceb8ca570c20.zip
Move some tests from `rustc_expand` to `rustc_parse`.
There are some test cases involving `parse` and `tokenstream` and
`mut_visit` that are located in `rustc_expand`. Because it used to be
the case that constructing a `ParseSess` required the involvement of
`rustc_expand`. However, since #64197 merged (a long time ago)
`rust_expand` no longer needs to be involved.

This commit moves the tests into `rustc_parse`. This is the optimal
place for the `parse` tests. It's not ideal for the `tokenstream` and
`mut_visit` tests -- they would be better in `rustc_ast` -- but they
still rely on parsing, which is not available in `rustc_ast`. But
`rustc_parse` is lower down in the crate graph and closer to `rustc_ast`
than `rust_expand`, so it's still an improvement for them.

The exact renaming is as follows:

- rustc_expand/src/mut_visit/tests.rs -> rustc_parse/src/parser/mut_visit/tests.rs
- rustc_expand/src/tokenstream/tests.rs -> rustc_parse/src/parser/tokenstream/tests.rs
- rustc_expand/src/tests.rs + rustc_expand/src/parse/tests.rs ->
  compiler/rustc_parse/src/parser/tests.rs

The latter two test files are combined because there's no need for them
to be separate, and having a `rustc_parse::parser::parse` module would
be weird. This also means some `pub(crate)`s can be removed.
Diffstat (limited to 'compiler/rustc_expand/src')
-rw-r--r--compiler/rustc_expand/src/lib.rs20
-rw-r--r--compiler/rustc_expand/src/mut_visit/tests.rs72
-rw-r--r--compiler/rustc_expand/src/parse/tests.rs382
-rw-r--r--compiler/rustc_expand/src/tests.rs1055
-rw-r--r--compiler/rustc_expand/src/tokenstream/tests.rs109
5 files changed, 0 insertions, 1638 deletions
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index c2c3b777699..4222c9fe906 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -34,24 +34,4 @@ pub mod module;
 #[allow(rustc::untranslatable_diagnostic)]
 pub mod proc_macro;
 
-// HACK(Centril, #64197): These shouldn't really be here.
-// Rather, they should be with their respective modules which are defined in other crates.
-// However, since for now constructing a `ParseSess` sorta requires `config` from this crate,
-// these tests will need to live here in the interim.
-
-#[cfg(test)]
-mod tests;
-#[cfg(test)]
-mod parse {
-    mod tests;
-}
-#[cfg(test)]
-mod tokenstream {
-    mod tests;
-}
-#[cfg(test)]
-mod mut_visit {
-    mod tests;
-}
-
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_expand/src/mut_visit/tests.rs b/compiler/rustc_expand/src/mut_visit/tests.rs
deleted file mode 100644
index 8974d45b4d8..00000000000
--- a/compiler/rustc_expand/src/mut_visit/tests.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-use crate::tests::{matches_codepattern, string_to_crate};
-
-use rustc_ast as ast;
-use rustc_ast::mut_visit::MutVisitor;
-use rustc_ast_pretty::pprust;
-use rustc_span::create_default_session_globals_then;
-use rustc_span::symbol::Ident;
-
-// This version doesn't care about getting comments or doc-strings in.
-fn print_crate_items(krate: &ast::Crate) -> String {
-    krate.items.iter().map(|i| pprust::item_to_string(i)).collect::<Vec<_>>().join(" ")
-}
-
-// Change every identifier to "zz".
-struct ToZzIdentMutVisitor;
-
-impl MutVisitor for ToZzIdentMutVisitor {
-    const VISIT_TOKENS: bool = true;
-
-    fn visit_ident(&mut self, ident: &mut Ident) {
-        *ident = Ident::from_str("zz");
-    }
-}
-
-// Maybe add to `expand.rs`.
-macro_rules! assert_pred {
-    ($pred:expr, $predname:expr, $a:expr , $b:expr) => {{
-        let pred_val = $pred;
-        let a_val = $a;
-        let b_val = $b;
-        if !(pred_val(&a_val, &b_val)) {
-            panic!("expected args satisfying {}, got {} and {}", $predname, a_val, b_val);
-        }
-    }};
-}
-
-// Make sure idents get transformed everywhere.
-#[test]
-fn ident_transformation() {
-    create_default_session_globals_then(|| {
-        let mut zz_visitor = ToZzIdentMutVisitor;
-        let mut krate =
-            string_to_crate("#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string());
-        zz_visitor.visit_crate(&mut krate);
-        assert_pred!(
-            matches_codepattern,
-            "matches_codepattern",
-            print_crate_items(&krate),
-            "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()
-        );
-    })
-}
-
-// Make sure idents get transformed even inside macro defs.
-#[test]
-fn ident_transformation_in_defs() {
-    create_default_session_globals_then(|| {
-        let mut zz_visitor = ToZzIdentMutVisitor;
-        let mut krate = string_to_crate(
-            "macro_rules! a {(b $c:expr $(d $e:token)f+ => \
-            (g $(d $d $e)+))} "
-                .to_string(),
-        );
-        zz_visitor.visit_crate(&mut krate);
-        assert_pred!(
-            matches_codepattern,
-            "matches_codepattern",
-            print_crate_items(&krate),
-            "macro_rules! zz{(zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+))}".to_string()
-        );
-    })
-}
diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs
deleted file mode 100644
index 066afd7a41d..00000000000
--- a/compiler/rustc_expand/src/parse/tests.rs
+++ /dev/null
@@ -1,382 +0,0 @@
-use crate::tests::{
-    matches_codepattern, psess, string_to_stream, with_error_checking_parse,
-    with_expected_parse_error,
-};
-
-use ast::token::IdentIsRaw;
-use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter, Token};
-use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
-use rustc_ast::visit;
-use rustc_ast::{self as ast, PatKind};
-use rustc_ast_pretty::pprust::item_to_string;
-use rustc_errors::PResult;
-use rustc_parse::new_parser_from_source_str;
-use rustc_parse::parser::ForceCollect;
-use rustc_session::parse::ParseSess;
-use rustc_span::create_default_session_globals_then;
-use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::{BytePos, FileName, Pos, Span};
-use std::path::PathBuf;
-
-/// Parses an item.
-///
-/// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err`
-/// when a syntax error occurred.
-fn parse_item_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-) -> PResult<'_, Option<P<ast::Item>>> {
-    new_parser_from_source_str(psess, name, source).parse_item(ForceCollect::No)
-}
-
-// Produces a `rustc_span::span`.
-fn sp(a: u32, b: u32) -> Span {
-    Span::with_root_ctxt(BytePos(a), BytePos(b))
-}
-
-/// Parses a string, return an expression.
-fn string_to_expr(source_str: String) -> P<ast::Expr> {
-    with_error_checking_parse(source_str, &psess(), |p| p.parse_expr())
-}
-
-/// Parses a string, returns an item.
-fn string_to_item(source_str: String) -> Option<P<ast::Item>> {
-    with_error_checking_parse(source_str, &psess(), |p| p.parse_item(ForceCollect::No))
-}
-
-#[test]
-fn bad_path_expr_1() {
-    // This should trigger error: expected identifier, found keyword `return`
-    create_default_session_globals_then(|| {
-        with_expected_parse_error(
-            "::abc::def::return",
-            "expected identifier, found keyword `return`",
-            |p| p.parse_expr(),
-        );
-    })
-}
-
-// Checks the token-tree-ization of macros.
-#[test]
-fn string_to_tts_macro() {
-    create_default_session_globals_then(|| {
-        let stream = string_to_stream("macro_rules! zip (($a)=>($a))".to_string());
-        let tts = &stream.trees().collect::<Vec<_>>()[..];
-
-        match tts {
-            [
-                TokenTree::Token(
-                    Token { kind: token::Ident(name_macro_rules, IdentIsRaw::No), .. },
-                    _,
-                ),
-                TokenTree::Token(Token { kind: token::Not, .. }, _),
-                TokenTree::Token(Token { kind: token::Ident(name_zip, IdentIsRaw::No), .. }, _),
-                TokenTree::Delimited(.., macro_delim, macro_tts),
-            ] if name_macro_rules == &kw::MacroRules && name_zip.as_str() == "zip" => {
-                let tts = &macro_tts.trees().collect::<Vec<_>>();
-                match &tts[..] {
-                    [
-                        TokenTree::Delimited(.., first_delim, first_tts),
-                        TokenTree::Token(Token { kind: token::FatArrow, .. }, _),
-                        TokenTree::Delimited(.., second_delim, second_tts),
-                    ] if macro_delim == &Delimiter::Parenthesis => {
-                        let tts = &first_tts.trees().collect::<Vec<_>>();
-                        match &tts[..] {
-                            [
-                                TokenTree::Token(Token { kind: token::Dollar, .. }, _),
-                                TokenTree::Token(
-                                    Token { kind: token::Ident(name, IdentIsRaw::No), .. },
-                                    _,
-                                ),
-                            ] if first_delim == &Delimiter::Parenthesis && name.as_str() == "a" => {
-                            }
-                            _ => panic!("value 3: {:?} {:?}", first_delim, first_tts),
-                        }
-                        let tts = &second_tts.trees().collect::<Vec<_>>();
-                        match &tts[..] {
-                            [
-                                TokenTree::Token(Token { kind: token::Dollar, .. }, _),
-                                TokenTree::Token(
-                                    Token { kind: token::Ident(name, IdentIsRaw::No), .. },
-                                    _,
-                                ),
-                            ] if second_delim == &Delimiter::Parenthesis
-                                && name.as_str() == "a" => {}
-                            _ => panic!("value 4: {:?} {:?}", second_delim, second_tts),
-                        }
-                    }
-                    _ => panic!("value 2: {:?} {:?}", macro_delim, macro_tts),
-                }
-            }
-            _ => panic!("value: {:?}", tts),
-        }
-    })
-}
-
-#[test]
-fn string_to_tts_1() {
-    create_default_session_globals_then(|| {
-        let tts = string_to_stream("fn a(b: i32) { b; }".to_string());
-
-        let expected = TokenStream::new(vec![
-            TokenTree::token_alone(token::Ident(kw::Fn, IdentIsRaw::No), sp(0, 2)),
-            TokenTree::token_joint_hidden(
-                token::Ident(Symbol::intern("a"), IdentIsRaw::No),
-                sp(3, 4),
-            ),
-            TokenTree::Delimited(
-                DelimSpan::from_pair(sp(4, 5), sp(11, 12)),
-                // `JointHidden` because the `(` is followed immediately by
-                // `b`, `Alone` because the `)` is followed by whitespace.
-                DelimSpacing::new(Spacing::JointHidden, Spacing::Alone),
-                Delimiter::Parenthesis,
-                TokenStream::new(vec![
-                    TokenTree::token_joint(
-                        token::Ident(Symbol::intern("b"), IdentIsRaw::No),
-                        sp(5, 6),
-                    ),
-                    TokenTree::token_alone(token::Colon, sp(6, 7)),
-                    // `JointHidden` because the `i32` is immediately followed by the `)`.
-                    TokenTree::token_joint_hidden(
-                        token::Ident(sym::i32, IdentIsRaw::No),
-                        sp(8, 11),
-                    ),
-                ])
-                .into(),
-            ),
-            TokenTree::Delimited(
-                DelimSpan::from_pair(sp(13, 14), sp(18, 19)),
-                // First `Alone` because the `{` is followed by whitespace,
-                // second `Alone` because the `}` is followed immediately by
-                // EOF.
-                DelimSpacing::new(Spacing::Alone, Spacing::Alone),
-                Delimiter::Brace,
-                TokenStream::new(vec![
-                    TokenTree::token_joint(
-                        token::Ident(Symbol::intern("b"), IdentIsRaw::No),
-                        sp(15, 16),
-                    ),
-                    // `Alone` because the `;` is followed by whitespace.
-                    TokenTree::token_alone(token::Semi, sp(16, 17)),
-                ])
-                .into(),
-            ),
-        ]);
-
-        assert_eq!(tts, expected);
-    })
-}
-
-#[test]
-fn parse_use() {
-    create_default_session_globals_then(|| {
-        let use_s = "use foo::bar::baz;";
-        let vitem = string_to_item(use_s.to_string()).unwrap();
-        let vitem_s = item_to_string(&vitem);
-        assert_eq!(&vitem_s[..], use_s);
-
-        let use_s = "use foo::bar as baz;";
-        let vitem = string_to_item(use_s.to_string()).unwrap();
-        let vitem_s = item_to_string(&vitem);
-        assert_eq!(&vitem_s[..], use_s);
-    })
-}
-
-#[test]
-fn parse_extern_crate() {
-    create_default_session_globals_then(|| {
-        let ex_s = "extern crate foo;";
-        let vitem = string_to_item(ex_s.to_string()).unwrap();
-        let vitem_s = item_to_string(&vitem);
-        assert_eq!(&vitem_s[..], ex_s);
-
-        let ex_s = "extern crate foo as bar;";
-        let vitem = string_to_item(ex_s.to_string()).unwrap();
-        let vitem_s = item_to_string(&vitem);
-        assert_eq!(&vitem_s[..], ex_s);
-    })
-}
-
-fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
-    let item = string_to_item(src.to_string()).unwrap();
-
-    struct PatIdentVisitor {
-        spans: Vec<Span>,
-    }
-    impl<'a> visit::Visitor<'a> for PatIdentVisitor {
-        fn visit_pat(&mut self, p: &'a ast::Pat) {
-            match &p.kind {
-                PatKind::Ident(_, ident, _) => {
-                    self.spans.push(ident.span);
-                }
-                _ => {
-                    visit::walk_pat(self, p);
-                }
-            }
-        }
-    }
-    let mut v = PatIdentVisitor { spans: Vec::new() };
-    visit::walk_item(&mut v, &item);
-    return v.spans;
-}
-
-#[test]
-fn span_of_self_arg_pat_idents_are_correct() {
-    create_default_session_globals_then(|| {
-        let srcs = [
-            "impl z { fn a (&self, &myarg: i32) {} }",
-            "impl z { fn a (&mut self, &myarg: i32) {} }",
-            "impl z { fn a (&'a self, &myarg: i32) {} }",
-            "impl z { fn a (self, &myarg: i32) {} }",
-            "impl z { fn a (self: Foo, &myarg: i32) {} }",
-        ];
-
-        for src in srcs {
-            let spans = get_spans_of_pat_idents(src);
-            let (lo, hi) = (spans[0].lo(), spans[0].hi());
-            assert!(
-                "self" == &src[lo.to_usize()..hi.to_usize()],
-                "\"{}\" != \"self\". src=\"{}\"",
-                &src[lo.to_usize()..hi.to_usize()],
-                src
-            )
-        }
-    })
-}
-
-#[test]
-fn parse_exprs() {
-    create_default_session_globals_then(|| {
-        // just make sure that they parse....
-        string_to_expr("3 + 4".to_string());
-        string_to_expr("a::z.froob(b,&(987+3))".to_string());
-    })
-}
-
-#[test]
-fn attrs_fix_bug() {
-    create_default_session_globals_then(|| {
-        string_to_item(
-            "pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-                -> Result<Box<Writer>, String> {
-#[cfg(windows)]
-fn wb() -> c_int {
-    (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
-}
-
-#[cfg(unix)]
-fn wb() -> c_int { O_WRONLY as c_int }
-
-let mut fflags: c_int = wb();
-}"
-            .to_string(),
-        );
-    })
-}
-
-#[test]
-fn crlf_doc_comments() {
-    create_default_session_globals_then(|| {
-        let psess = psess();
-
-        let name_1 = FileName::Custom("crlf_source_1".to_string());
-        let source = "/// doc comment\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name_1, source, &psess).unwrap().unwrap();
-        let doc = item.attrs.iter().filter_map(|at| at.doc_str()).next().unwrap();
-        assert_eq!(doc.as_str(), " doc comment");
-
-        let name_2 = FileName::Custom("crlf_source_2".to_string());
-        let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name_2, source, &psess).unwrap().unwrap();
-        let docs = item.attrs.iter().filter_map(|at| at.doc_str()).collect::<Vec<_>>();
-        let b: &[_] = &[Symbol::intern(" doc comment"), Symbol::intern(" line 2")];
-        assert_eq!(&docs[..], b);
-
-        let name_3 = FileName::Custom("clrf_source_3".to_string());
-        let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name_3, source, &psess).unwrap().unwrap();
-        let doc = item.attrs.iter().filter_map(|at| at.doc_str()).next().unwrap();
-        assert_eq!(doc.as_str(), " doc comment\n *  with CRLF ");
-    });
-}
-
-#[test]
-fn ttdelim_span() {
-    fn parse_expr_from_source_str(
-        name: FileName,
-        source: String,
-        psess: &ParseSess,
-    ) -> PResult<'_, P<ast::Expr>> {
-        new_parser_from_source_str(psess, name, source).parse_expr()
-    }
-
-    create_default_session_globals_then(|| {
-        let psess = psess();
-        let expr = parse_expr_from_source_str(
-            PathBuf::from("foo").into(),
-            "foo!( fn main() { body } )".to_string(),
-            &psess,
-        )
-        .unwrap();
-
-        let ast::ExprKind::MacCall(mac) = &expr.kind else { panic!("not a macro") };
-        let span = mac.args.tokens.trees().last().unwrap().span();
-
-        match psess.source_map().span_to_snippet(span) {
-            Ok(s) => assert_eq!(&s[..], "{ body }"),
-            Err(_) => panic!("could not get snippet"),
-        }
-    });
-}
-
-// This tests that when parsing a string (rather than a file) we don't try
-// and read in a file for a module declaration and just parse a stub.
-// See `recurse_into_file_modules` in the parser.
-#[test]
-fn out_of_line_mod() {
-    create_default_session_globals_then(|| {
-        let item = parse_item_from_source_str(
-            PathBuf::from("foo").into(),
-            "mod foo { struct S; mod this_does_not_exist; }".to_owned(),
-            &psess(),
-        )
-        .unwrap()
-        .unwrap();
-
-        let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() };
-        assert!(matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2));
-    });
-}
-
-#[test]
-fn eqmodws() {
-    assert_eq!(matches_codepattern("", ""), true);
-    assert_eq!(matches_codepattern("", "a"), false);
-    assert_eq!(matches_codepattern("a", ""), false);
-    assert_eq!(matches_codepattern("a", "a"), true);
-    assert_eq!(matches_codepattern("a b", "a   \n\t\r  b"), true);
-    assert_eq!(matches_codepattern("a b ", "a   \n\t\r  b"), true);
-    assert_eq!(matches_codepattern("a b", "a   \n\t\r  b "), false);
-    assert_eq!(matches_codepattern("a   b", "a b"), true);
-    assert_eq!(matches_codepattern("ab", "a b"), false);
-    assert_eq!(matches_codepattern("a   b", "ab"), true);
-    assert_eq!(matches_codepattern(" a   b", "ab"), true);
-}
-
-#[test]
-fn pattern_whitespace() {
-    assert_eq!(matches_codepattern("", "\x0C"), false);
-    assert_eq!(matches_codepattern("a b ", "a   \u{0085}\n\t\r  b"), true);
-    assert_eq!(matches_codepattern("a b", "a   \u{0085}\n\t\r  b "), false);
-}
-
-#[test]
-fn non_pattern_whitespace() {
-    // These have the property 'White_Space' but not 'Pattern_White_Space'
-    assert_eq!(matches_codepattern("a b", "a\u{2002}b"), false);
-    assert_eq!(matches_codepattern("a   b", "a\u{2002}b"), false);
-    assert_eq!(matches_codepattern("\u{205F}a   b", "ab"), false);
-    assert_eq!(matches_codepattern("a  \u{3000}b", "ab"), false);
-}
diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs
deleted file mode 100644
index 2b0b58eb1d9..00000000000
--- a/compiler/rustc_expand/src/tests.rs
+++ /dev/null
@@ -1,1055 +0,0 @@
-use rustc_ast as ast;
-use rustc_ast::tokenstream::TokenStream;
-use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream};
-use rustc_session::parse::ParseSess;
-use rustc_span::create_default_session_globals_then;
-use rustc_span::source_map::{FilePathMapping, SourceMap};
-use rustc_span::{BytePos, Span};
-
-use rustc_data_structures::sync::Lrc;
-use rustc_errors::emitter::HumanEmitter;
-use rustc_errors::{DiagCtxt, MultiSpan, PResult};
-use termcolor::WriteColor;
-
-use std::io;
-use std::io::prelude::*;
-use std::iter::Peekable;
-use std::path::{Path, PathBuf};
-use std::str;
-use std::sync::{Arc, Mutex};
-
-pub(crate) fn psess() -> ParseSess {
-    ParseSess::new(vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE])
-}
-
-/// Map string to parser (via tts).
-fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
-    new_parser_from_source_str(psess, PathBuf::from("bogofile").into(), source_str)
-}
-
-fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
-    let output = Arc::new(Mutex::new(Vec::new()));
-    let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-    let fallback_bundle = rustc_errors::fallback_fluent_bundle(
-        vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
-        false,
-    );
-    let emitter = HumanEmitter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
-        .sm(Some(source_map.clone()))
-        .diagnostic_width(Some(140));
-    let dcx = DiagCtxt::new(Box::new(emitter));
-    (dcx, source_map, output)
-}
-
-/// Returns the result of parsing the given string via the given callback.
-///
-/// If there are any errors, this will panic.
-pub(crate) fn with_error_checking_parse<'a, T, F>(s: String, psess: &'a ParseSess, f: F) -> T
-where
-    F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
-{
-    let mut p = string_to_parser(&psess, s);
-    let x = f(&mut p).unwrap();
-    p.psess.dcx.abort_if_errors();
-    x
-}
-
-/// Verifies that parsing the given string using the given callback will
-/// generate an error that contains the given text.
-pub(crate) fn with_expected_parse_error<T, F>(source_str: &str, expected_output: &str, f: F)
-where
-    F: for<'a> FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
-{
-    let (handler, source_map, output) = create_test_handler();
-    let psess = ParseSess::with_dcx(handler, source_map);
-    let mut p = string_to_parser(&psess, source_str.to_string());
-    let result = f(&mut p);
-    assert!(result.is_ok());
-
-    let bytes = output.lock().unwrap();
-    let actual_output = str::from_utf8(&bytes).unwrap();
-    println!("expected output:\n------\n{}------", expected_output);
-    println!("actual output:\n------\n{}------", actual_output);
-
-    assert!(actual_output.contains(expected_output))
-}
-
-/// Maps a string to tts, using a made-up filename.
-pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
-    let psess = psess();
-    source_file_to_stream(
-        &psess,
-        psess.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str),
-        None,
-    )
-}
-
-/// Parses a string, returns a crate.
-pub(crate) fn string_to_crate(source_str: String) -> ast::Crate {
-    let psess = psess();
-    with_error_checking_parse(source_str, &psess, |p| p.parse_crate_mod())
-}
-
-/// Does the given string match the pattern? whitespace in the first string
-/// may be deleted or replaced with other whitespace to match the pattern.
-/// This function is relatively Unicode-ignorant; fortunately, the careful design
-/// of UTF-8 mitigates this ignorance. It doesn't do NKF-normalization(?).
-pub(crate) fn matches_codepattern(a: &str, b: &str) -> bool {
-    let mut a_iter = a.chars().peekable();
-    let mut b_iter = b.chars().peekable();
-
-    loop {
-        let (a, b) = match (a_iter.peek(), b_iter.peek()) {
-            (None, None) => return true,
-            (None, _) => return false,
-            (Some(&a), None) => {
-                if rustc_lexer::is_whitespace(a) {
-                    break; // Trailing whitespace check is out of loop for borrowck.
-                } else {
-                    return false;
-                }
-            }
-            (Some(&a), Some(&b)) => (a, b),
-        };
-
-        if rustc_lexer::is_whitespace(a) && rustc_lexer::is_whitespace(b) {
-            // Skip whitespace for `a` and `b`.
-            scan_for_non_ws_or_end(&mut a_iter);
-            scan_for_non_ws_or_end(&mut b_iter);
-        } else if rustc_lexer::is_whitespace(a) {
-            // Skip whitespace for `a`.
-            scan_for_non_ws_or_end(&mut a_iter);
-        } else if a == b {
-            a_iter.next();
-            b_iter.next();
-        } else {
-            return false;
-        }
-    }
-
-    // Check if a has *only* trailing whitespace.
-    a_iter.all(rustc_lexer::is_whitespace)
-}
-
-/// Advances the given peekable `Iterator` until it reaches a non-whitespace character.
-fn scan_for_non_ws_or_end<I: Iterator<Item = char>>(iter: &mut Peekable<I>) {
-    while iter.peek().copied().is_some_and(rustc_lexer::is_whitespace) {
-        iter.next();
-    }
-}
-
-/// Identifies a position in the text by the n'th occurrence of a string.
-struct Position {
-    string: &'static str,
-    count: usize,
-}
-
-struct SpanLabel {
-    start: Position,
-    end: Position,
-    label: &'static str,
-}
-
-pub(crate) struct Shared<T: Write> {
-    pub data: Arc<Mutex<T>>,
-}
-
-impl<T: Write> WriteColor for Shared<T> {
-    fn supports_color(&self) -> bool {
-        false
-    }
-
-    fn set_color(&mut self, _spec: &termcolor::ColorSpec) -> io::Result<()> {
-        Ok(())
-    }
-
-    fn reset(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-impl<T: Write> Write for Shared<T> {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.data.lock().unwrap().write(buf)
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        self.data.lock().unwrap().flush()
-    }
-}
-
-#[allow(rustc::untranslatable_diagnostic)] // no translation needed for tests
-fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
-    create_default_session_globals_then(|| {
-        let (handler, source_map, output) = create_test_handler();
-        source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());
-
-        let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end);
-        let mut msp = MultiSpan::from_span(primary_span);
-        for span_label in span_labels {
-            let span = make_span(&file_text, &span_label.start, &span_label.end);
-            msp.push_span_label(span, span_label.label);
-            println!("span: {:?} label: {:?}", span, span_label.label);
-            println!("text: {:?}", source_map.span_to_snippet(span));
-        }
-
-        handler.span_err(msp, "foo");
-
-        assert!(
-            expected_output.chars().next() == Some('\n'),
-            "expected output should begin with newline"
-        );
-        let expected_output = &expected_output[1..];
-
-        let bytes = output.lock().unwrap();
-        let actual_output = str::from_utf8(&bytes).unwrap();
-        println!("expected output:\n------\n{}------", expected_output);
-        println!("actual output:\n------\n{}------", actual_output);
-
-        assert!(expected_output == actual_output)
-    })
-}
-
-fn make_span(file_text: &str, start: &Position, end: &Position) -> Span {
-    let start = make_pos(file_text, start);
-    let end = make_pos(file_text, end) + end.string.len(); // just after matching thing ends
-    assert!(start <= end);
-    Span::with_root_ctxt(BytePos(start as u32), BytePos(end as u32))
-}
-
-fn make_pos(file_text: &str, pos: &Position) -> usize {
-    let mut remainder = file_text;
-    let mut offset = 0;
-    for _ in 0..pos.count {
-        if let Some(n) = remainder.find(&pos.string) {
-            offset += n;
-            remainder = &remainder[n + 1..];
-        } else {
-            panic!("failed to find {} instances of {:?} in {:?}", pos.count, pos.string, file_text);
-        }
-    }
-    offset
-}
-
-#[test]
-fn ends_on_col0() {
-    test_harness(
-        r#"
-fn foo() {
-}
-"#,
-        vec![SpanLabel {
-            start: Position { string: "{", count: 1 },
-            end: Position { string: "}", count: 1 },
-            label: "test",
-        }],
-        r#"
-error: foo
- --> test.rs:2:10
-  |
-2 |   fn foo() {
-  |  __________^
-3 | | }
-  | |_^ test
-
-"#,
-    );
-}
-
-#[test]
-fn ends_on_col2() {
-    test_harness(
-        r#"
-fn foo() {
-
-
-  }
-"#,
-        vec![SpanLabel {
-            start: Position { string: "{", count: 1 },
-            end: Position { string: "}", count: 1 },
-            label: "test",
-        }],
-        r#"
-error: foo
- --> test.rs:2:10
-  |
-2 |   fn foo() {
-  |  __________^
-... |
-5 | |   }
-  | |___^ test
-
-"#,
-    );
-}
-#[test]
-fn non_nested() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0
-  X1 Y1
-  X2 Y2
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X2", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "Y2", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn nested() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0
-  Y1 X1
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X1", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "Y1", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |      X0 Y0
-  |   ___^__-
-  |  |___|
-  | ||
-4 | ||   Y1 X1
-  | ||____-__^ `X` is a good letter
-  |  |____|
-  |       `Y` is a good letter too
-
-"#,
-    );
-}
-
-#[test]
-fn different_overlap() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0 Z0
-  X1 Y1 Z1
-  X2 Y2 Z2
-  X3 Y3 Z3
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "X2", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Z1", count: 1 },
-                end: Position { string: "X3", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn triple_overlap() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0 Z0
-  X1 Y1 Z1
-  X2 Y2 Z2
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X2", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "Y2", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-            SpanLabel {
-                start: Position { string: "Z0", count: 1 },
-                end: Position { string: "Z2", count: 1 },
-                label: "`Z` label",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn triple_exact_overlap() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0 Z0
-  X1 Y1 Z1
-  X2 Y2 Z2
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X2", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X2", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X2", count: 1 },
-                label: "`Z` label",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn minimum_depth() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0 Z0
-  X1 Y1 Z1
-  X2 Y2 Z2
-  X3 Y3 Z3
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "X1", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Y1", count: 1 },
-                end: Position { string: "Z2", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-            SpanLabel {
-                start: Position { string: "X2", count: 1 },
-                end: Position { string: "Y3", count: 1 },
-                label: "`Z`",
-            },
-        ],
-        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`
-
-"#,
-    );
-}
-
-#[test]
-fn non_overlapping() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0 Z0
-  X1 Y1 Z1
-  X2 Y2 Z2
-  X3 Y3 Z3
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "X0", count: 1 },
-                end: Position { string: "X1", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Y2", count: 1 },
-                end: Position { string: "Z3", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn overlapping_start_and_end() {
-    test_harness(
-        r#"
-fn foo() {
-  X0 Y0 Z0
-  X1 Y1 Z1
-  X2 Y2 Z2
-  X3 Y3 Z3
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "X1", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Z1", count: 1 },
-                end: Position { string: "Z3", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_primary_without_message() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "",
-            },
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "`a` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "c", count: 1 },
-                end: Position { string: "c", count: 1 },
-                label: "",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:7
-  |
-3 |   a { b { c } d }
-  |   ----^^^^-^^-- `a` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_secondary_without_message() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "`a` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a { b { c } d }
-  |   ^^^^-------^^ `a` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_primary_without_message_2() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "`b` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "",
-            },
-            SpanLabel {
-                start: Position { string: "c", count: 1 },
-                end: Position { string: "c", count: 1 },
-                label: "",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:7
-  |
-3 |   a { b { c } d }
-  |   ----^^^^-^^--
-  |       |
-  |       `b` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_secondary_without_message_2() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "",
-            },
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "`b` is a good letter",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a { b { c } d }
-  |   ^^^^-------^^
-  |       |
-  |       `b` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_secondary_without_message_3() {
-    test_harness(
-        r#"
-fn foo() {
-  a  bc  d
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "b", count: 1 },
-                label: "`a` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "c", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a  bc  d
-  |   ^^^^----
-  |   |
-  |   `a` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_without_message() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "",
-            },
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a { b { c } d }
-  |   ^^^^-------^^
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_without_message_2() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "",
-            },
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "",
-            },
-            SpanLabel {
-                start: Position { string: "c", count: 1 },
-                end: Position { string: "c", count: 1 },
-                label: "",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:7
-  |
-3 |   a { b { c } d }
-  |   ----^^^^-^^--
-
-"#,
-    );
-}
-
-#[test]
-fn multiple_labels_with_message() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "a", count: 1 },
-                end: Position { string: "d", count: 1 },
-                label: "`a` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "b", count: 1 },
-                end: Position { string: "}", count: 1 },
-                label: "`b` is a good letter",
-            },
-        ],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a { b { c } d }
-  |   ^^^^-------^^
-  |   |   |
-  |   |   `b` is a good letter
-  |   `a` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn single_label_with_message() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![SpanLabel {
-            start: Position { string: "a", count: 1 },
-            end: Position { string: "d", count: 1 },
-            label: "`a` is a good letter",
-        }],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a { b { c } d }
-  |   ^^^^^^^^^^^^^ `a` is a good letter
-
-"#,
-    );
-}
-
-#[test]
-fn single_label_without_message() {
-    test_harness(
-        r#"
-fn foo() {
-  a { b { c } d }
-}
-"#,
-        vec![SpanLabel {
-            start: Position { string: "a", count: 1 },
-            end: Position { string: "d", count: 1 },
-            label: "",
-        }],
-        r#"
-error: foo
- --> test.rs:3:3
-  |
-3 |   a { b { c } d }
-  |   ^^^^^^^^^^^^^
-
-"#,
-    );
-}
-
-#[test]
-fn long_snippet() {
-    test_harness(
-        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
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "X1", count: 1 },
-                label: "`X` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Z1", count: 1 },
-                end: Position { string: "Z3", count: 1 },
-                label: "`Y` is a good letter too",
-            },
-        ],
-        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
-
-"#,
-    );
-}
-
-#[test]
-fn long_snippet_multiple_spans() {
-    test_harness(
-        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
-}
-"#,
-        vec![
-            SpanLabel {
-                start: Position { string: "Y0", count: 1 },
-                end: Position { string: "Y3", count: 1 },
-                label: "`Y` is a good letter",
-            },
-            SpanLabel {
-                start: Position { string: "Z1", count: 1 },
-                end: Position { string: "Z2", count: 1 },
-                label: "`Z` is a good letter too",
-            },
-        ],
-        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
-
-"#,
-    );
-}
diff --git a/compiler/rustc_expand/src/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs
deleted file mode 100644
index 78795e86fd5..00000000000
--- a/compiler/rustc_expand/src/tokenstream/tests.rs
+++ /dev/null
@@ -1,109 +0,0 @@
-use crate::tests::string_to_stream;
-
-use rustc_ast::token::{self, IdentIsRaw};
-use rustc_ast::tokenstream::{TokenStream, TokenTree};
-use rustc_span::create_default_session_globals_then;
-use rustc_span::{BytePos, Span, Symbol};
-
-fn string_to_ts(string: &str) -> TokenStream {
-    string_to_stream(string.to_owned())
-}
-
-fn sp(a: u32, b: u32) -> Span {
-    Span::with_root_ctxt(BytePos(a), BytePos(b))
-}
-
-#[test]
-fn test_concat() {
-    create_default_session_globals_then(|| {
-        let test_res = string_to_ts("foo::bar::baz");
-        let test_fst = string_to_ts("foo::bar");
-        let test_snd = string_to_ts("::baz");
-        let mut eq_res = TokenStream::default();
-        eq_res.push_stream(test_fst);
-        eq_res.push_stream(test_snd);
-        assert_eq!(test_res.trees().count(), 5);
-        assert_eq!(eq_res.trees().count(), 5);
-        assert_eq!(test_res.eq_unspanned(&eq_res), true);
-    })
-}
-
-#[test]
-fn test_to_from_bijection() {
-    create_default_session_globals_then(|| {
-        let test_start = string_to_ts("foo::bar(baz)");
-        let test_end = test_start.trees().cloned().collect();
-        assert_eq!(test_start, test_end)
-    })
-}
-
-#[test]
-fn test_eq_0() {
-    create_default_session_globals_then(|| {
-        let test_res = string_to_ts("foo");
-        let test_eqs = string_to_ts("foo");
-        assert_eq!(test_res, test_eqs)
-    })
-}
-
-#[test]
-fn test_eq_1() {
-    create_default_session_globals_then(|| {
-        let test_res = string_to_ts("::bar::baz");
-        let test_eqs = string_to_ts("::bar::baz");
-        assert_eq!(test_res, test_eqs)
-    })
-}
-
-#[test]
-fn test_eq_3() {
-    create_default_session_globals_then(|| {
-        let test_res = string_to_ts("");
-        let test_eqs = string_to_ts("");
-        assert_eq!(test_res, test_eqs)
-    })
-}
-
-#[test]
-fn test_diseq_0() {
-    create_default_session_globals_then(|| {
-        let test_res = string_to_ts("::bar::baz");
-        let test_eqs = string_to_ts("bar::baz");
-        assert_eq!(test_res == test_eqs, false)
-    })
-}
-
-#[test]
-fn test_diseq_1() {
-    create_default_session_globals_then(|| {
-        let test_res = string_to_ts("(bar,baz)");
-        let test_eqs = string_to_ts("bar,baz");
-        assert_eq!(test_res == test_eqs, false)
-    })
-}
-
-#[test]
-fn test_is_empty() {
-    create_default_session_globals_then(|| {
-        let test0 = TokenStream::default();
-        let test1 =
-            TokenStream::token_alone(token::Ident(Symbol::intern("a"), IdentIsRaw::No), sp(0, 1));
-        let test2 = string_to_ts("foo(bar::baz)");
-
-        assert_eq!(test0.is_empty(), true);
-        assert_eq!(test1.is_empty(), false);
-        assert_eq!(test2.is_empty(), false);
-    })
-}
-
-#[test]
-fn test_dotdotdot() {
-    create_default_session_globals_then(|| {
-        let mut stream = TokenStream::default();
-        stream.push_tree(TokenTree::token_joint(token::Dot, sp(0, 1)));
-        stream.push_tree(TokenTree::token_joint(token::Dot, sp(1, 2)));
-        stream.push_tree(TokenTree::token_alone(token::Dot, sp(2, 3)));
-        assert!(stream.eq_unspanned(&string_to_ts("...")));
-        assert_eq!(stream.trees().count(), 1);
-    })
-}