From 99c7432896bbfdab1f7f70f8d763cab5f3efe64a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Jul 2019 21:02:45 +0300 Subject: hygiene: Introduce a helper method for creating new expansions Creating a fresh expansion and immediately generating a span from it is the most common scenario. Also avoid allocating `allow_internal_unstable` lists for derive markers repeatedly. And rename `ExpnInfo::with_unstable` to `ExpnInfo::allow_unstable`, seems to be a better fitting name. --- src/libsyntax/ext/base.rs | 2 ++ src/libsyntax/ext/derive.rs | 7 ++----- src/libsyntax/ext/expand.rs | 4 ++-- src/libsyntax/std_inject.rs | 22 +++++++--------------- src/libsyntax/test.rs | 23 +++++------------------ 5 files changed, 18 insertions(+), 40 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cb4edee30cd..37d5885db60 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -721,6 +721,7 @@ pub struct ExtCtxt<'a> { pub resolver: &'a mut dyn Resolver, pub current_expansion: ExpansionData, pub expansions: FxHashMap>, + pub allow_derive_markers: Lrc<[Symbol]>, } impl<'a> ExtCtxt<'a> { @@ -740,6 +741,7 @@ impl<'a> ExtCtxt<'a> { directory_ownership: DirectoryOwnership::Owned { relative: None }, }, expansions: FxHashMap::default(), + allow_derive_markers: [sym::rustc_attrs, sym::structural_match][..].into(), } } diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs index 11c1fceb7e7..1c15deab373 100644 --- a/src/libsyntax/ext/derive.rs +++ b/src/libsyntax/ext/derive.rs @@ -8,7 +8,6 @@ use crate::symbol::{Symbol, sym}; use crate::errors::Applicability; use syntax_pos::Span; -use syntax_pos::hygiene::{Mark, SyntaxContext}; use rustc_data_structures::fx::FxHashSet; pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec { @@ -55,13 +54,11 @@ pub fn add_derived_markers(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P names.insert(unwrap_or!(path.segments.get(0), continue).ident.name); } - let mark = Mark::fresh(cx.current_expansion.mark); - mark.set_expn_info(ExpnInfo::with_unstable( + let span = span.fresh_expansion(cx.current_expansion.mark, ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span, - cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match], + cx.parse_sess.edition, cx.allow_derive_markers.clone(), )); - let span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark)); item.visit_attrs(|attrs| { if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { let meta = cx.meta_word(span, sym::structural_match); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2349382eb5e..39a8a7af2a3 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -362,7 +362,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derives.reserve(traits.len()); invocations.reserve(traits.len()); for path in traits { - let mark = Mark::fresh(self.cx.current_expansion.mark); + let mark = Mark::fresh(self.cx.current_expansion.mark, None); derives.push(mark); invocations.push(Invocation { kind: InvocationKind::Derive { @@ -847,7 +847,7 @@ struct InvocationCollector<'a, 'b> { impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment { - let mark = Mark::fresh(self.cx.current_expansion.mark); + let mark = Mark::fresh(self.cx.current_expansion.mark, None); self.invocations.push(Invocation { kind, fragment_kind, diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 81f9ff9b661..d86b76f71ec 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -1,7 +1,7 @@ use crate::ast; use crate::attr; use crate::edition::Edition; -use crate::ext::hygiene::{Mark, SyntaxContext, MacroKind}; +use crate::ext::hygiene::{Mark, MacroKind}; use crate::symbol::{Ident, Symbol, kw, sym}; use crate::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use crate::ptr::P; @@ -9,19 +9,7 @@ use crate::tokenstream::TokenStream; use std::cell::Cell; use std::iter; -use syntax_pos::{DUMMY_SP, Span}; - -/// Craft a span that will be ignored by the stability lint's -/// call to source_map's `is_internal` check. -/// The expanded code uses the unstable `#[prelude_import]` attribute. -fn ignored_span(sp: Span, edition: Edition) -> Span { - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::Macro(MacroKind::Attr, Symbol::intern("std_inject")), sp, edition, - &[sym::prelude_import], - )); - sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) -} +use syntax_pos::DUMMY_SP; pub fn injected_crate_name() -> Option<&'static str> { INJECTED_CRATE_NAME.with(|name| name.get()) @@ -87,7 +75,11 @@ pub fn maybe_inject_crates_ref( INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name))); - let span = ignored_span(DUMMY_SP, edition); + let span = DUMMY_SP.fresh_expansion(Mark::root(), ExpnInfo::allow_unstable( + ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition, + [sym::prelude_import][..].into(), + )); + krate.module.items.insert(0, P(ast::Item { attrs: vec![ast::Attribute { style: ast::AttrStyle::Outer, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 7ec7bb6ff45..799d64a9962 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -43,7 +43,6 @@ struct TestCtxt<'a> { test_cases: Vec, reexport_test_harness_main: Option, is_libtest: bool, - ctxt: SyntaxContext, features: &'a Features, test_runner: Option, @@ -259,8 +258,6 @@ fn generate_test_harness(sess: &ParseSess, let mut cleaner = EntryPointCleaner { depth: 0 }; cleaner.visit_crate(krate); - let mark = Mark::fresh(Mark::root()); - let mut econfig = ExpansionConfig::default("test".to_string()); econfig.features = Some(features); @@ -274,16 +271,10 @@ fn generate_test_harness(sess: &ParseSess, is_libtest: attr::find_crate_name(&krate.attrs) .map(|s| s == sym::test).unwrap_or(false), toplevel_reexport: None, - ctxt: SyntaxContext::empty().apply_mark(mark), features, test_runner }; - mark.set_expn_info(ExpnInfo::with_unstable( - ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, sess.edition, - &[sym::main, sym::test, sym::rustc_attrs], - )); - TestHarnessGenerator { cx, tests: Vec::new(), @@ -291,13 +282,6 @@ fn generate_test_harness(sess: &ParseSess, }.visit_crate(krate); } -/// Craft a span that will be ignored by the stability lint's -/// call to source_map's `is_internal` check. -/// The expanded code calls some unstable functions in the test crate. -fn ignored_span(cx: &TestCtxt<'_>, sp: Span) -> Span { - sp.with_ctxt(cx.ctxt) -} - enum HasTestSignature { Yes, No(BadTestSignature), @@ -314,12 +298,15 @@ enum BadTestSignature { /// Creates a function item for use as the main function of a test build. /// This function will call the `test_runner` as specified by the crate attribute fn mk_main(cx: &mut TestCtxt<'_>) -> P { - // Writing this out by hand with 'ignored_span': + // Writing this out by hand: // pub fn main() { // #![main] // test::test_main_static(&[..tests]); // } - let sp = ignored_span(cx, DUMMY_SP); + let sp = DUMMY_SP.fresh_expansion(Mark::root(), ExpnInfo::allow_unstable( + ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition, + [sym::main, sym::test, sym::rustc_attrs][..].into(), + )); let ecx = &cx.ext_cx; let test_id = Ident::with_empty_ctxt(sym::test); -- cgit 1.4.1-3-g733a5