Skip to content

Commit 7947c58

Browse files
committed
Allow unnameable tests
1 parent caab47d commit 7947c58

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/libsyntax/ext/expand.rs

+28-8
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
475475
cx: self.cx,
476476
invocations: Vec::new(),
477477
monotonic: self.monotonic,
478+
tests_nameable: true,
478479
};
479480
(fragment.fold_with(&mut collector), collector.invocations)
480481
};
@@ -1050,6 +1051,11 @@ struct InvocationCollector<'a, 'b: 'a> {
10501051
cfg: StripUnconfigured<'a>,
10511052
invocations: Vec<Invocation>,
10521053
monotonic: bool,
1054+
1055+
/// Test functions need to be nameable. Tests inside functions or in other
1056+
/// unnameable locations need to be ignored. `tests_nameable` tracks whether
1057+
/// any test functions found in the current context would be nameable.
1058+
tests_nameable: bool,
10531059
}
10541060

10551061
impl<'a, 'b> InvocationCollector<'a, 'b> {
@@ -1067,6 +1073,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10671073
placeholder(fragment_kind, NodeId::placeholder_from_mark(mark))
10681074
}
10691075

1076+
/// Folds the item allowing tests to be expanded because they are still nameable.
1077+
/// This should probably only be called with module items
1078+
fn fold_nameable(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
1079+
fold::noop_fold_item(item, self)
1080+
}
1081+
1082+
/// Folds the item but doesn't allow tests to occur within it
1083+
fn fold_unnameable(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
1084+
let was_nameable = mem::replace(&mut self.tests_nameable, false);
1085+
let items = fold::noop_fold_item(item, self);
1086+
self.tests_nameable = was_nameable;
1087+
items
1088+
}
1089+
10701090
fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment {
10711091
self.collect(kind, InvocationKind::Bang { mac: mac, ident: None, span: span })
10721092
}
@@ -1307,7 +1327,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
13071327
}
13081328
ast::ItemKind::Mod(ast::Mod { inner, .. }) => {
13091329
if item.ident == keywords::Invalid.ident() {
1310-
return noop_fold_item(item, self);
1330+
return self.fold_nameable(item);
13111331
}
13121332

13131333
let orig_directory_ownership = self.cx.current_expansion.directory_ownership;
@@ -1347,14 +1367,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
13471367

13481368
let orig_module =
13491369
mem::replace(&mut self.cx.current_expansion.module, Rc::new(module));
1350-
let result = noop_fold_item(item, self);
1370+
let result = self.fold_nameable(item);
13511371
self.cx.current_expansion.module = orig_module;
13521372
self.cx.current_expansion.directory_ownership = orig_directory_ownership;
13531373
result
13541374
}
13551375
// Ensure that test functions are accessible from the test harness.
13561376
ast::ItemKind::Fn(..) if self.cx.ecfg.should_test => {
1357-
if item.attrs.iter().any(|attr| is_test_or_bench(attr)) {
1377+
if self.tests_nameable && item.attrs.iter().any(|attr| is_test_or_bench(attr)) {
13581378
let orig_vis = item.vis.clone();
13591379

13601380
// Publicize the item under gensymed name to avoid pollution
@@ -1370,16 +1390,16 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
13701390
item.ident.span,
13711391
orig_vis,
13721392
Some(Ident::from_interned_str(item.ident.as_interned_str())),
1373-
self.cx.path(item.ident.span, vec![item.ident]));
1393+
self.cx.path(item.ident.span, vec![Ident::from_str("self"), item.ident]));
13741394

13751395
SmallVector::many(
1376-
noop_fold_item(item, self).into_iter()
1377-
.chain(noop_fold_item(use_item, self)))
1396+
self.fold_unnameable(item).into_iter()
1397+
.chain(self.fold_unnameable(use_item)))
13781398
} else {
1379-
noop_fold_item(item, self)
1399+
self.fold_unnameable(item)
13801400
}
13811401
}
1382-
_ => noop_fold_item(item, self),
1402+
_ => self.fold_unnameable(item),
13831403
}
13841404
}
13851405

0 commit comments

Comments
 (0)