diff options
Diffstat (limited to 'src/test/ui/proc-macro/auxiliary/expand-expr.rs')
-rw-r--r-- | src/test/ui/proc-macro/auxiliary/expand-expr.rs | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/src/test/ui/proc-macro/auxiliary/expand-expr.rs b/src/test/ui/proc-macro/auxiliary/expand-expr.rs deleted file mode 100644 index 1d6ef8a13..000000000 --- a/src/test/ui/proc-macro/auxiliary/expand-expr.rs +++ /dev/null @@ -1,166 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] -#![deny(warnings)] -#![feature(proc_macro_expand, proc_macro_span)] - -extern crate proc_macro; - -use proc_macro::*; -use std::str::FromStr; - -// Flatten the TokenStream, removing any toplevel `Delimiter::None`s for -// comparison. -fn flatten(ts: TokenStream) -> Vec<TokenTree> { - ts.into_iter() - .flat_map(|tt| match &tt { - TokenTree::Group(group) if group.delimiter() == Delimiter::None => { - flatten(group.stream()) - } - _ => vec![tt], - }) - .collect() -} - -// Assert that two TokenStream values are roughly equal to one-another. -fn assert_ts_eq(lhs: &TokenStream, rhs: &TokenStream) { - let ltts = flatten(lhs.clone()); - let rtts = flatten(rhs.clone()); - - if ltts.len() != rtts.len() { - panic!( - "expected the same number of tts ({} == {})\nlhs:\n{:#?}\nrhs:\n{:#?}", - ltts.len(), - rtts.len(), - lhs, - rhs - ) - } - - for (ltt, rtt) in ltts.iter().zip(&rtts) { - match (ltt, rtt) { - (TokenTree::Group(l), TokenTree::Group(r)) => { - assert_eq!( - l.delimiter(), - r.delimiter(), - "expected delimiters to match for {:?} and {:?}", - l, - r - ); - assert_ts_eq(&l.stream(), &r.stream()); - } - (TokenTree::Punct(l), TokenTree::Punct(r)) => assert_eq!( - (l.as_char(), l.spacing()), - (r.as_char(), r.spacing()), - "expected punct to match for {:?} and {:?}", - l, - r - ), - (TokenTree::Ident(l), TokenTree::Ident(r)) => assert_eq!( - l.to_string(), - r.to_string(), - "expected ident to match for {:?} and {:?}", - l, - r - ), - (TokenTree::Literal(l), TokenTree::Literal(r)) => assert_eq!( - l.to_string(), - r.to_string(), - "expected literal to match for {:?} and {:?}", - l, - r - ), - (l, r) => panic!("expected type to match for {:?} and {:?}", l, r), - } - } -} - -#[proc_macro] -pub fn expand_expr_is(input: TokenStream) -> TokenStream { - let mut iter = input.into_iter(); - let mut expected_tts = Vec::new(); - let comma = loop { - match iter.next() { - Some(TokenTree::Punct(p)) if p.as_char() == ',' => break p, - Some(tt) => expected_tts.push(tt), - None => panic!("expected comma"), - } - }; - - // Make sure that `Ident` and `Literal` objects from this proc-macro's - // environment are not invalidated when `expand_expr` recursively invokes - // another macro by taking a local copy, and checking it after the fact. - let pre_expand_span = comma.span(); - let pre_expand_ident = Ident::new("ident", comma.span()); - let pre_expand_literal = Literal::string("literal"); - let pre_expand_call_site = Span::call_site(); - - let expected = expected_tts.into_iter().collect::<TokenStream>(); - let expanded = iter.collect::<TokenStream>().expand_expr().expect("expand_expr failed"); - assert!( - expected.to_string() == expanded.to_string(), - "assert failed\nexpected: `{}`\nexpanded: `{}`", - expected.to_string(), - expanded.to_string() - ); - - // Also compare the raw tts to make sure they line up. - assert_ts_eq(&expected, &expanded); - - assert!(comma.span().eq(&pre_expand_span), "pre-expansion span is still equal"); - assert_eq!(pre_expand_ident.to_string(), "ident", "pre-expansion identifier is still valid"); - assert_eq!( - pre_expand_literal.to_string(), - "\"literal\"", - "pre-expansion literal is still valid" - ); - assert!(Span::call_site().eq(&pre_expand_call_site), "pre-expansion call-site is still equal"); - - TokenStream::new() -} - -#[proc_macro] -pub fn expand_expr_fail(input: TokenStream) -> TokenStream { - match input.expand_expr() { - Ok(ts) => panic!("expand_expr unexpectedly succeeded: `{}`", ts), - Err(_) => TokenStream::new(), - } -} - -#[proc_macro] -pub fn check_expand_expr_file(ts: TokenStream) -> TokenStream { - // Check that the passed in `file!()` invocation and a parsed `file!` - // invocation expand to the same literal. - let input_t = ts.expand_expr().expect("expand_expr failed on macro input").to_string(); - let parse_t = TokenStream::from_str("file!{}") - .unwrap() - .expand_expr() - .expect("expand_expr failed on internal macro") - .to_string(); - assert_eq!(input_t, parse_t); - - // Check that the literal matches `Span::call_site().source_file().path()` - let expect_t = - Literal::string(&Span::call_site().source_file().path().to_string_lossy()).to_string(); - assert_eq!(input_t, expect_t); - - TokenStream::new() -} - -#[proc_macro] -pub fn recursive_expand(_: TokenStream) -> TokenStream { - // Recursively call until we hit the recursion limit and get an error. - // - // NOTE: This doesn't panic if expansion fails because that'll cause a very - // large number of errors to fill the output. - TokenStream::from_str("recursive_expand!{}") - .unwrap() - .expand_expr() - .unwrap_or(std::iter::once(TokenTree::Literal(Literal::u32_suffixed(0))).collect()) -} - -#[proc_macro] -pub fn echo_pm(input: TokenStream) -> TokenStream { - input -} |