Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_interface: Add a new query pre_configure #108221

Merged
merged 3 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions compiler/rustc_builtin_macros/src/cmdline_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_ast::{self as ast, AttrItem, AttrStyle};
use rustc_session::parse::ParseSess;
use rustc_span::FileName;

pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
pub fn inject(krate: &mut ast::Crate, parse_sess: &ParseSess, attrs: &[String]) {
for raw_attr in attrs {
let mut parser = rustc_parse::new_parser_from_source_str(
parse_sess,
Expand Down Expand Up @@ -36,6 +36,4 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
start_span.to(end_span),
));
}

krate
}
12 changes: 5 additions & 7 deletions compiler/rustc_builtin_macros/src/proc_macro_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ struct CollectProcMacros<'a> {
}

pub fn inject(
krate: &mut ast::Crate,
sess: &Session,
resolver: &mut dyn ResolverExpand,
mut krate: ast::Crate,
is_proc_macro_crate: bool,
has_proc_macro_decls: bool,
is_test_crate: bool,
handler: &rustc_errors::Handler,
) -> ast::Crate {
) {
let ecfg = ExpansionConfig::default("proc_macro".to_string());
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);

Expand All @@ -64,22 +64,20 @@ pub fn inject(
};

if has_proc_macro_decls || is_proc_macro_crate {
visit::walk_crate(&mut collect, &krate);
visit::walk_crate(&mut collect, krate);
}
let macros = collect.macros;

if !is_proc_macro_crate {
return krate;
return;
}

if is_test_crate {
return krate;
return;
}

let decls = mk_decls(&mut cx, &macros);
krate.items.push(decls);

krate
}

impl<'a> CollectProcMacros<'a> {
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_builtin_macros/src/standard_library_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ use rustc_span::DUMMY_SP;
use thin_vec::thin_vec;

pub fn inject(
mut krate: ast::Crate,
krate: &mut ast::Crate,
pre_configured_attrs: &[ast::Attribute],
resolver: &mut dyn ResolverExpand,
sess: &Session,
) -> ast::Crate {
) -> usize {
let orig_num_items = krate.items.len();
let edition = sess.parse_sess.edition;

// the first name in this list is the crate name of the crate with the prelude
let names: &[Symbol] = if attr::contains_name(&krate.attrs, sym::no_core) {
return krate;
} else if attr::contains_name(&krate.attrs, sym::no_std) {
if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
let names: &[Symbol] = if attr::contains_name(pre_configured_attrs, sym::no_core) {
return 0;
} else if attr::contains_name(pre_configured_attrs, sym::no_std) {
if attr::contains_name(pre_configured_attrs, sym::compiler_builtins) {
&[sym::core]
} else {
&[sym::core, sym::compiler_builtins]
Expand Down Expand Up @@ -88,6 +90,5 @@ pub fn inject(
);

krate.items.insert(0, use_item);

krate
krate.items.len() - orig_num_items
}
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct TestCtxt<'a> {

/// Traverse the crate, collecting all the test functions, eliding any
/// existing main functions, and synthesizing a main test harness
pub fn inject(sess: &Session, resolver: &mut dyn ResolverExpand, krate: &mut ast::Crate) {
pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn ResolverExpand) {
let span_diagnostic = sess.diagnostic();
let panic_strategy = sess.panic_strategy();
let platform_panic_strategy = sess.target.panic_strategy;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ fn run_compiler(

{
let plugins = queries.register_plugins()?;
let (_, lint_store) = &*plugins.borrow();
let (.., lint_store) = &*plugins.borrow();

// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,7 @@ pub struct ExpansionData {
pub struct ExtCtxt<'a> {
pub sess: &'a Session,
pub ecfg: expand::ExpansionConfig<'a>,
pub num_standard_library_imports: usize,
pub reduced_recursion_limit: Option<Limit>,
pub root_path: PathBuf,
pub resolver: &'a mut dyn ResolverExpand,
Expand Down Expand Up @@ -1030,6 +1031,7 @@ impl<'a> ExtCtxt<'a> {
ExtCtxt {
sess,
ecfg,
num_standard_library_imports: 0,
reduced_recursion_limit: None,
resolver,
lint_store,
Expand Down
69 changes: 22 additions & 47 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use rustc_session::Session;
use rustc_span::edition::{Edition, ALL_EDITIONS};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
use thin_vec::ThinVec;

/// A folder that strips out items that do not belong in the current configuration.
pub struct StripUnconfigured<'a> {
Expand All @@ -37,7 +36,7 @@ pub struct StripUnconfigured<'a> {
pub lint_node_id: NodeId,
}

fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
fn feature_removed(sess: &Session, span: Span, reason: Option<&str>) {
sess.emit_err(FeatureRemoved {
span,
Expand Down Expand Up @@ -191,39 +190,16 @@ fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
features
}

/// `cfg_attr`-process the crate's attributes and compute the crate's features.
pub fn features(
sess: &Session,
mut krate: ast::Crate,
lint_node_id: NodeId,
) -> (ast::Crate, Features) {
let mut strip_unconfigured =
StripUnconfigured { sess, features: None, config_tokens: false, lint_node_id };

let unconfigured_attrs = krate.attrs.clone();
let diag = &sess.parse_sess.span_diagnostic;
let err_count = diag.err_count();
let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) {
None => {
// The entire crate is unconfigured.
krate.attrs = ast::AttrVec::new();
krate.items = ThinVec::new();
Features::default()
}
Some(attrs) => {
krate.attrs = attrs;
let features = get_features(sess, &krate.attrs);
if err_count == diag.err_count() {
// Avoid reconfiguring malformed `cfg_attr`s.
strip_unconfigured.features = Some(&features);
// Run configuration again, this time with features available
// so that we can perform feature-gating.
strip_unconfigured.configure_krate_attrs(unconfigured_attrs);
}
features
}
pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec {
let strip_unconfigured = StripUnconfigured {
sess,
features: None,
config_tokens: false,
lint_node_id: ast::CRATE_NODE_ID,
};
(krate, features)
let attrs: ast::AttrVec =
attrs.iter().flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)).collect();
if strip_unconfigured.in_cfg(&attrs) { attrs } else { ast::AttrVec::new() }
}

#[macro_export]
Expand Down Expand Up @@ -254,11 +230,6 @@ impl<'a> StripUnconfigured<'a> {
}
}

fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
self.in_cfg(&attrs).then_some(attrs)
}

/// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
/// This is only used during the invocation of `derive` proc-macros,
/// which require that we cfg-expand their entire input.
Expand All @@ -281,7 +252,7 @@ impl<'a> StripUnconfigured<'a> {
.iter()
.flat_map(|tree| match tree.clone() {
AttrTokenTree::Attributes(mut data) => {
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));

if self.in_cfg(&data.attrs) {
data.tokens = LazyAttrTokenStream::new(
Expand Down Expand Up @@ -319,12 +290,16 @@ impl<'a> StripUnconfigured<'a> {
/// the syntax of any `cfg_attr` is incorrect.
fn process_cfg_attrs<T: HasAttrs>(&self, node: &mut T) {
node.visit_attrs(|attrs| {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
});
}

fn process_cfg_attr(&self, attr: Attribute) -> Vec<Attribute> {
if attr.has_name(sym::cfg_attr) { self.expand_cfg_attr(attr, true) } else { vec![attr] }
fn process_cfg_attr(&self, attr: &Attribute) -> Vec<Attribute> {
if attr.has_name(sym::cfg_attr) {
self.expand_cfg_attr(attr, true)
} else {
vec![attr.clone()]
}
}

/// Parse and expand a single `cfg_attr` attribute into a list of attributes
Expand All @@ -334,9 +309,9 @@ impl<'a> StripUnconfigured<'a> {
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
/// is in the original source file. Gives a compiler error if the syntax of
/// the attribute is incorrect.
pub(crate) fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec<Attribute> {
let Some((cfg_predicate, expanded_attrs)) =
rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else {
rustc_parse::parse_cfg_attr(attr, &self.sess.parse_sess) else {
return vec![];
};

Expand Down Expand Up @@ -365,10 +340,10 @@ impl<'a> StripUnconfigured<'a> {
// `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
expanded_attrs
.into_iter()
.flat_map(|item| self.process_cfg_attr(self.expand_cfg_attr_item(&attr, item)))
.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(attr, item)))
.collect()
} else {
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(&attr, item)).collect()
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(attr, item)).collect()
}
}

Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,9 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
) -> Result<Self::OutputTy, Self> {
Ok(noop_flat_map(node, collector))
}
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, span: Span) {
collector.cx.emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
}
}

impl InvocationCollectorNode for P<ast::Item> {
Expand Down Expand Up @@ -1378,6 +1381,11 @@ impl InvocationCollectorNode for ast::Crate {
fn noop_visit<V: MutVisitor>(&mut self, visitor: &mut V) {
noop_visit_crate(self, visitor)
}
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, _span: Span) {
self.attrs.clear();
// Standard prelude imports are left in the crate for backward compatibility.
self.items.truncate(collector.cx.num_standard_library_imports);
}
}

impl InvocationCollectorNode for P<ast::Ty> {
Expand Down Expand Up @@ -1688,7 +1696,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
res
}

fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) {
fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: &ast::Attribute, pos: usize) {
node.visit_attrs(|attrs| {
// Repeated `insert` calls is inefficient, but the number of
// insertions is almost always 0 or 1 in practice.
Expand All @@ -1712,7 +1720,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
Default::default()
}
sym::cfg_attr => {
self.expand_cfg_attr(&mut node, attr, pos);
self.expand_cfg_attr(&mut node, &attr, pos);
continue;
}
_ => {
Expand Down Expand Up @@ -1756,11 +1764,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
continue;
}

self.cx.emit_err(RemoveNodeNotSupported { span, descr: Node::descr() });
node.expand_cfg_false(self, span);
continue;
}
sym::cfg_attr => {
self.expand_cfg_attr(node, attr, pos);
self.expand_cfg_attr(node, &attr, pos);
continue;
}
_ => visit_clobber(node, |node| {
Expand Down
Loading