Navigation Menu

Skip to content

Commit

Permalink
Eliminate the SessionGlobals from librustc_ast.
Browse files Browse the repository at this point in the history
By moving `{known,used}_attrs` from `SessionGlobals` to `Session`. This
means they are accessed via the `Session`, rather than via TLS. A few
`Attr` methods and `librustc_ast` functions are now methods of
`Session`.

All of this required passing a `Session` to lots of functions that didn't
already have one. Some of these functions also had arguments removed, because
those arguments could be accessed directly via the `Session` argument.

`contains_feature_attr()` was dead, and is removed.

Some functions were moved from `librustc_ast` elsewhere because they now need
to access `Session`, which isn't available in that crate.
- `entry_point_type()` --> `librustc_builtin_macros`
- `global_allocator_spans()` --> `librustc_metadata`
- `is_proc_macro_attr()` --> `Session`
  • Loading branch information
nnethercote committed Aug 8, 2020
1 parent d6fa011 commit e539dd6
Show file tree
Hide file tree
Showing 120 changed files with 816 additions and 805 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock
Expand Up @@ -3195,7 +3195,6 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"scoped-tls",
"smallvec 1.4.0",
"tracing",
]
Expand Down Expand Up @@ -3467,6 +3466,7 @@ dependencies = [
"rustc_index",
"rustc_macros",
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec 1.4.0",
Expand Down
1 change: 0 additions & 1 deletion src/librustc_ast/Cargo.toml
Expand Up @@ -12,7 +12,6 @@ doctest = false
[dependencies]
rustc_serialize = { path = "../librustc_serialize" }
log = { package = "tracing", version = "0.1" }
scoped-tls = "1.0"
rustc_span = { path = "../librustc_span" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_index = { path = "../librustc_index" }
Expand Down
97 changes: 12 additions & 85 deletions src/librustc_ast/attr/mod.rs
Expand Up @@ -10,72 +10,30 @@ use crate::ptr::P;
use crate::token::{self, CommentKind, Token};
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};

use rustc_data_structures::sync::Lock;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::source_map::{BytePos, Spanned};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;

use log::debug;
use std::iter;
use std::ops::DerefMut;

// Per-session global variables: this struct is stored in thread-local storage
// in such a way that it is accessible without any kind of handle to all
// threads within the compilation session, but is not accessible outside the
// session.
pub struct SessionGlobals {
used_attrs: Lock<GrowableBitSet<AttrId>>,
known_attrs: Lock<GrowableBitSet<AttrId>>,
span_session_globals: rustc_span::SessionGlobals,
}
pub struct MarkedAttrs(GrowableBitSet<AttrId>);

impl SessionGlobals {
fn new(edition: Edition) -> SessionGlobals {
SessionGlobals {
// We have no idea how many attributes there will be, so just
// initiate the vectors with 0 bits. We'll grow them as necessary.
used_attrs: Lock::new(GrowableBitSet::new_empty()),
known_attrs: Lock::new(GrowableBitSet::new_empty()),
span_session_globals: rustc_span::SessionGlobals::new(edition),
}
impl MarkedAttrs {
// We have no idea how many attributes there will be, so just
// initiate the vectors with 0 bits. We'll grow them as necessary.
pub fn new() -> Self {
MarkedAttrs(GrowableBitSet::new_empty())
}
}

pub fn with_session_globals<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
let ast_session_globals = SessionGlobals::new(edition);
SESSION_GLOBALS.set(&ast_session_globals, || {
rustc_span::SESSION_GLOBALS.set(&ast_session_globals.span_session_globals, f)
})
}

pub fn with_default_session_globals<R>(f: impl FnOnce() -> R) -> R {
with_session_globals(DEFAULT_EDITION, f)
}

scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);

pub fn mark_used(attr: &Attribute) {
debug!("marking {:?} as used", attr);
SESSION_GLOBALS.with(|session_globals| {
session_globals.used_attrs.lock().insert(attr.id);
});
}

pub fn is_used(attr: &Attribute) -> bool {
SESSION_GLOBALS.with(|session_globals| session_globals.used_attrs.lock().contains(attr.id))
}

pub fn mark_known(attr: &Attribute) {
debug!("marking {:?} as known", attr);
SESSION_GLOBALS.with(|session_globals| {
session_globals.known_attrs.lock().insert(attr.id);
});
}
pub fn mark(&mut self, attr: &Attribute) {
self.0.insert(attr.id);
}

pub fn is_known(attr: &Attribute) -> bool {
SESSION_GLOBALS.with(|session_globals| session_globals.known_attrs.lock().contains(attr.id))
pub fn is_marked(&self, attr: &Attribute) -> bool {
self.0.contains(attr.id)
}
}

pub fn is_known_lint_tool(m_item: Ident) -> bool {
Expand Down Expand Up @@ -173,21 +131,6 @@ impl Attribute {
}
}

/// Returns `true` if the attribute's path matches the argument.
/// If it matches, then the attribute is marked as used.
/// Should only be used by rustc, other tools can use `has_name` instead,
/// because only rustc is supposed to report the `unused_attributes` lint.
/// `MetaItem` and `NestedMetaItem` are produced by "lowering" an `Attribute`
/// and don't have identity, so they only has the `has_name` method,
/// and you need to mark the original `Attribute` as used when necessary.
pub fn check_name(&self, name: Symbol) -> bool {
let matches = self.has_name(name);
if matches {
mark_used(self);
}
matches
}

/// For a single-segment attribute, returns its name; otherwise, returns `None`.
pub fn ident(&self) -> Option<Ident> {
match self.kind {
Expand Down Expand Up @@ -418,22 +361,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
items.iter().any(|item| item.has_name(name))
}

pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
attrs.iter().any(|item| item.check_name(name))
}

pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> {
attrs.iter().find(|attr| attr.check_name(name))
}

pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator<Item = &Attribute> {
attrs.iter().filter(move |attr| attr.check_name(name))
}

pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option<Symbol> {
attrs.iter().find(|at| at.check_name(name)).and_then(|at| at.value_str())
}

impl MetaItem {
fn token_trees_and_joints(&self) -> Vec<TreeAndJoint> {
let mut idents = vec![];
Expand Down
28 changes: 0 additions & 28 deletions src/librustc_ast/entry.rs
@@ -1,35 +1,7 @@
use crate::ast::{Item, ItemKind};
use crate::attr;
use rustc_span::symbol::sym;

pub enum EntryPointType {
None,
MainNamed,
MainAttr,
Start,
OtherMain, // Not an entry point, but some other function named main
}

// Beware, this is duplicated in librustc_middle/middle/entry.rs, make sure to keep
// them in sync.
pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
match item.kind {
ItemKind::Fn(..) => {
if attr::contains_name(&item.attrs, sym::start) {
EntryPointType::Start
} else if attr::contains_name(&item.attrs, sym::main) {
EntryPointType::MainAttr
} else if item.ident.name == sym::main {
if depth == 1 {
// This is a top-level function so can be 'main'
EntryPointType::MainNamed
} else {
EntryPointType::OtherMain
}
} else {
EntryPointType::None
}
}
_ => EntryPointType::None,
}
}
24 changes: 0 additions & 24 deletions src/librustc_ast/expand/allocator.rs
@@ -1,6 +1,4 @@
use crate::{ast, attr, visit};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;

#[derive(Clone, Copy)]
pub enum AllocatorKind {
Expand Down Expand Up @@ -53,25 +51,3 @@ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[
output: AllocatorTy::ResultPtr,
},
];

pub fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
struct Finder {
name: Symbol,
spans: Vec<Span>,
}
impl<'ast> visit::Visitor<'ast> for Finder {
fn visit_item(&mut self, item: &'ast ast::Item) {
if item.ident.name == self.name
&& attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
{
self.spans.push(item.span);
}
visit::walk_item(self, item)
}
}

let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::alloc));
let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate);
f.spans
}
9 changes: 0 additions & 9 deletions src/librustc_ast/expand/mod.rs
@@ -1,12 +1,3 @@
//! Definitions shared by macros / syntax extensions and e.g. librustc_middle.

use crate::ast::Attribute;
use rustc_span::symbol::sym;

pub mod allocator;

pub fn is_proc_macro_attr(attr: &Attribute) -> bool {
[sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
.iter()
.any(|kind| attr.check_name(*kind))
}
1 change: 0 additions & 1 deletion src/librustc_ast/lib.rs
Expand Up @@ -42,7 +42,6 @@ pub mod util {

pub mod ast;
pub mod attr;
pub use attr::{with_default_session_globals, with_session_globals, SESSION_GLOBALS};
pub mod crate_disambiguator;
pub mod entry;
pub mod expand;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast/util/comments/tests.rs
@@ -1,5 +1,5 @@
use super::*;
use crate::with_default_session_globals;
use rustc_span::with_default_session_globals;

#[test]
fn line_doc_comments() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast/util/lev_distance/tests.rs
Expand Up @@ -21,7 +21,7 @@ fn test_lev_distance() {

#[test]
fn test_find_best_match_for_name() {
use crate::with_default_session_globals;
use rustc_span::with_default_session_globals;
with_default_session_globals(|| {
let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")];
assert_eq!(
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_ast_lowering/item.rs
Expand Up @@ -3,7 +3,6 @@ use super::{ImplTraitContext, ImplTraitPosition};
use crate::Arena;

use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::node_id::NodeMap;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
Expand Down Expand Up @@ -205,7 +204,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let attrs = self.lower_attrs(&i.attrs);

if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
if !macro_rules || attr::contains_name(&i.attrs, sym::macro_export) {
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
let hir_id = self.lower_node_id(i.id);
let body = P(self.lower_mac_args(body));
self.exported_macros.push(hir::MacroDef {
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_ast_lowering/lib.rs
Expand Up @@ -37,7 +37,6 @@

use rustc_ast::ast;
use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::node_id::NodeMap;
use rustc_ast::token::{self, DelimToken, Nonterminal, Token};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
Expand Down Expand Up @@ -2215,7 +2214,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
synthetic: param
.attrs
.iter()
.filter(|attr| attr.check_name(sym::rustc_synthetic))
.filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic))
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
.next(),
};
Expand All @@ -2236,7 +2235,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir_id: self.lower_node_id(param.id),
name,
span: param.ident.span,
pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
attrs: self.lower_attrs(&param.attrs),
bounds: self.arena.alloc_from_iter(bounds),
kind,
Expand Down
8 changes: 3 additions & 5 deletions src/librustc_ast_passes/ast_validation.rs
Expand Up @@ -8,8 +8,6 @@

use itertools::{Either, Itertools};
use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::expand::is_proc_macro_attr;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::walk_list;
Expand Down Expand Up @@ -891,11 +889,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

fn visit_item(&mut self, item: &'a Item) {
if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
if item.attrs.iter().any(|attr| self.session.is_proc_macro_attr(attr)) {
self.has_proc_macro_decls = true;
}

if attr::contains_name(&item.attrs, sym::no_mangle) {
if self.session.contains_name(&item.attrs, sym::no_mangle) {
self.check_nomangle_item_asciionly(item.ident, item.span);
}

Expand Down Expand Up @@ -1027,7 +1025,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Mod(Mod { inline, .. }) => {
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
if !inline && !attr::contains_name(&item.attrs, sym::path) {
if !inline && !self.session.contains_name(&item.attrs, sym::path) {
self.check_mod_file_item_asciionly(item.ident);
}
}
Expand Down

0 comments on commit e539dd6

Please sign in to comment.