Rewrite the unit tests in ext/expand.rs as a compile-fail test.

This commit is contained in:
Jeffrey Seyfried 2016-09-08 00:04:43 +00:00
parent a9821e1658
commit 20b43b2323
2 changed files with 46 additions and 107 deletions

View File

@ -803,110 +803,3 @@ impl Folder for Marker {
fn mark_tts(tts: &[TokenTree], m: Mark) -> Vec<TokenTree> {
noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None})
}
#[cfg(test)]
mod tests {
use super::{expand_crate, ExpansionConfig};
use ast;
use ext::base::{ExtCtxt, DummyResolver};
use parse;
use util::parser_testing::{string_to_parser};
use visit;
use visit::Visitor;
// a visitor that extracts the paths
// from a given thingy and puts them in a mutable
// array (passed in to the traversal)
#[derive(Clone)]
struct PathExprFinderContext {
path_accumulator: Vec<ast::Path> ,
}
impl Visitor for PathExprFinderContext {
fn visit_expr(&mut self, expr: &ast::Expr) {
if let ast::ExprKind::Path(None, ref p) = expr.node {
self.path_accumulator.push(p.clone());
}
visit::walk_expr(self, expr);
}
}
// these following tests are quite fragile, in that they don't test what
// *kind* of failure occurs.
fn test_ecfg() -> ExpansionConfig<'static> {
ExpansionConfig::default("test".to_string())
}
// make sure that macros can't escape fns
#[should_panic]
#[test] fn macros_cant_escape_fns_test () {
let src = "fn bogus() {macro_rules! z (() => (3+4));}\
fn inty() -> i32 { z!() }".to_string();
let sess = parse::ParseSess::new();
let crate_ast = parse::parse_crate_from_source_str(
"<test>".to_string(),
src,
Vec::new(), &sess).unwrap();
// should fail:
let mut loader = DummyResolver;
let mut ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut loader);
expand_crate(&mut ecx, vec![], crate_ast);
}
// make sure that macros can't escape modules
#[should_panic]
#[test] fn macros_cant_escape_mods_test () {
let src = "mod foo {macro_rules! z (() => (3+4));}\
fn inty() -> i32 { z!() }".to_string();
let sess = parse::ParseSess::new();
let crate_ast = parse::parse_crate_from_source_str(
"<test>".to_string(),
src,
Vec::new(), &sess).unwrap();
let mut loader = DummyResolver;
let mut ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut loader);
expand_crate(&mut ecx, vec![], crate_ast);
}
// macro_use modules should allow macros to escape
#[test] fn macros_can_escape_flattened_mods_test () {
let src = "#[macro_use] mod foo {macro_rules! z (() => (3+4));}\
fn inty() -> i32 { z!() }".to_string();
let sess = parse::ParseSess::new();
let crate_ast = parse::parse_crate_from_source_str(
"<test>".to_string(),
src,
Vec::new(), &sess).unwrap();
let mut loader = DummyResolver;
let mut ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut loader);
expand_crate(&mut ecx, vec![], crate_ast);
}
fn expand_crate_str(crate_str: String) -> ast::Crate {
let ps = parse::ParseSess::new();
let crate_ast = panictry!(string_to_parser(&ps, crate_str).parse_crate_mod());
// the cfg argument actually does matter, here...
let mut loader = DummyResolver;
let mut ecx = ExtCtxt::new(&ps, vec![], test_ecfg(), &mut loader);
expand_crate(&mut ecx, vec![], crate_ast)
}
#[test] fn macro_tokens_should_match(){
expand_crate_str(
"macro_rules! m((a)=>(13)) ;fn main(){m!(a);}".to_string());
}
// should be able to use a bound identifier as a literal in a macro definition:
#[test] fn self_macro_parsing(){
expand_crate_str(
"macro_rules! foo ((zz) => (287;));
fn f(zz: i32) {foo!(zz);}".to_string()
);
}
// create a really evil test case where a $x appears inside a binding of $x
// but *shouldn't* bind because it was inserted by a different macro....
// can't write this test case until we have macro-generating macros.
}

View File

@ -0,0 +1,46 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod macros_cant_escape_fns {
fn f() {
macro_rules! m { () => { 3 + 4 } }
}
fn g() -> i32 { m!() } //~ ERROR macro undefined
}
mod macros_cant_escape_mods {
mod f {
macro_rules! m { () => { 3 + 4 } }
}
fn g() -> i32 { m!() } //~ ERROR macro undefined
}
mod macros_can_escape_flattened_mods_test {
#[macro_use]
mod f {
macro_rules! m { () => { 3 + 4 } }
}
fn g() -> i32 { m!() }
}
fn macro_tokens_should_match() {
macro_rules! m { (a) => { 13 } }
m!(a);
}
// should be able to use a bound identifier as a literal in a macro definition:
fn self_macro_parsing() {
macro_rules! foo { (zz) => { 287; } }
fn f(zz: i32) {
foo!(zz);
}
}
fn main() {}