Auto merge of #74932 - nnethercote:rm-ast-session-globals, r=petrochenkov

Remove `librustc_ast` session globals

By moving the data onto `Session`.

r? @petrochenkov
This commit is contained in:
bors 2020-08-08 05:58:57 +00:00
commit e61621c307
121 changed files with 864 additions and 841 deletions

View File

@ -3195,7 +3195,6 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"scoped-tls",
"smallvec 1.4.0",
"tracing",
]

View File

@ -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" }

View File

@ -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 mark(&mut self, attr: &Attribute) {
self.0.insert(attr.id);
}
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 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 {
@ -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 {
@ -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![];

View File

@ -1,7 +1,3 @@
use crate::ast::{Item, ItemKind};
use crate::attr;
use rustc_span::symbol::sym;
pub enum EntryPointType {
None,
MainNamed,
@ -9,27 +5,3 @@ pub enum EntryPointType {
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,
}
}

View File

@ -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 {
@ -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
}

View File

@ -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))
}

View File

@ -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;

View File

@ -1,5 +1,5 @@
use super::*;
use crate::with_default_session_globals;
use rustc_span::with_default_session_globals;
#[test]
fn line_doc_comments() {

View File

@ -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!(

View File

@ -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};
@ -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 {

View File

@ -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};
@ -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(),
};
@ -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,

View File

@ -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;
@ -897,11 +895,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);
}
@ -1033,7 +1031,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);
}
}

View File

@ -1,11 +1,11 @@
use rustc_ast::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
use rustc_ast::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
use rustc_ast::attr;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_errors::{struct_span_err, Handler};
use rustc_errors::struct_span_err;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use rustc_feature::{Features, GateIssue, UnstableFeatures};
use rustc_session::parse::{feature_err, feature_err_issue, ParseSess};
use rustc_feature::{Features, GateIssue};
use rustc_session::parse::{feature_err, feature_err_issue};
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
@ -13,28 +13,32 @@ use rustc_span::Span;
use tracing::debug;
macro_rules! gate_feature_fn {
($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
let (cx, has_feature, span, name, explain) = (&*$cx, $has_feature, $span, $name, $explain);
let has_feature: bool = has_feature(&$cx.features);
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
let (visitor, has_feature, span, name, explain) =
(&*$visitor, $has_feature, $span, $name, $explain);
let has_feature: bool = has_feature(visitor.features);
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
if !has_feature && !span.allows_unstable($name) {
feature_err_issue(cx.parse_sess, name, span, GateIssue::Language, explain).emit();
feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
.emit();
}
}};
}
macro_rules! gate_feature_post {
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
gate_feature_fn!($cx, |x: &Features| x.$feature, $span, sym::$feature, $explain)
($visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
};
}
pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) {
PostExpansionVisitor { sess, features }.visit_attribute(attr)
}
struct PostExpansionVisitor<'a> {
parse_sess: &'a ParseSess,
sess: &'a Session,
// `sess` contains a `Features`, but this might not be that one.
features: &'a Features,
}
@ -138,6 +142,7 @@ impl<'a> PostExpansionVisitor<'a> {
);
}
abi => self
.sess
.parse_sess
.span_diagnostic
.delay_span_bug(span, &format!("unrecognized ABI not caught in lowering: {}", abi)),
@ -167,7 +172,7 @@ impl<'a> PostExpansionVisitor<'a> {
if !discriminant_spans.is_empty() && has_fields {
let mut err = feature_err(
self.parse_sess,
&self.sess.parse_sess,
sym::arbitrary_enum_discriminant,
discriminant_spans.clone(),
"custom discriminant values are not allowed in enums with tuple or struct variants",
@ -240,7 +245,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_fn!(self, has_feature, attr.span, name, descr);
}
// Check unstable flavors of the `#[doc]` attribute.
if attr.check_name(sym::doc) {
if self.sess.check_name(attr, sym::doc) {
for nested_meta in attr.meta_item_list().unwrap_or_default() {
macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
$(if nested_meta.has_name(sym::$name) {
@ -266,7 +271,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(
&self,
non_ascii_idents,
self.parse_sess.source_map().guess_head_span(sp),
self.sess.parse_sess.source_map().guess_head_span(sp),
"non-ascii idents are not fully supported"
);
}
@ -281,7 +286,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::Fn(..) => {
if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
if self.sess.contains_name(&i.attrs[..], sym::plugin_registrar) {
gate_feature_post!(
&self,
plugin_registrar,
@ -289,7 +294,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
"compiler plugins are experimental and possibly buggy"
);
}
if attr::contains_name(&i.attrs[..], sym::start) {
if self.sess.contains_name(&i.attrs[..], sym::start) {
gate_feature_post!(
&self,
start,
@ -299,7 +304,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
over time"
);
}
if attr::contains_name(&i.attrs[..], sym::main) {
if self.sess.contains_name(&i.attrs[..], sym::main) {
gate_feature_post!(
&self,
main,
@ -312,7 +317,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::Struct(..) => {
for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
for attr in self.sess.filter_by_name(&i.attrs[..], sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
if item.has_name(sym::simd) {
gate_feature_post!(
@ -391,7 +396,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
match i.kind {
ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => {
let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
let link_name = self.sess.first_attr_value_str_by_name(&i.attrs, sym::link_name);
let links_to_llvm = match link_name {
Some(val) => val.as_str().starts_with("llvm."),
_ => false,
@ -450,7 +455,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::ExprKind::Type(..) => {
// To avoid noise about type ascription in common syntax errors, only emit if it
// is the *only* error.
if self.parse_sess.span_diagnostic.err_count() == 0 {
if self.sess.parse_sess.span_diagnostic.err_count() == 0 {
gate_feature_post!(
&self,
type_ascription,
@ -600,16 +605,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
pub fn check_crate(
krate: &ast::Crate,
parse_sess: &ParseSess,
features: &Features,
unstable: UnstableFeatures,
) {
maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
let mut visitor = PostExpansionVisitor { parse_sess, features };
pub fn check_crate(krate: &ast::Crate, sess: &Session) {
maybe_stage_features(sess, krate);
let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() };
let spans = parse_sess.gated_spans.spans.borrow();
let spans = sess.parse_sess.gated_spans.spans.borrow();
macro_rules! gate_all {
($gate:ident, $msg:literal) => {
for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
@ -652,18 +652,18 @@ pub fn check_crate(
gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
// To avoid noise about type ascription in common syntax errors,
// only emit if it is the *only* error. (Also check it last.)
if parse_sess.span_diagnostic.err_count() == 0 {
if sess.parse_sess.span_diagnostic.err_count() == 0 {
gate_all!(type_ascription, "type ascription is experimental");
}
visit::walk_crate(&mut visitor, krate);
}
fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, unstable: UnstableFeatures) {
if !unstable.is_nightly_build() {
for attr in krate.attrs.iter().filter(|attr| attr.check_name(sym::feature)) {
fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
if !sess.opts.unstable_features.is_nightly_build() {
for attr in krate.attrs.iter().filter(|attr| sess.check_name(attr, sym::feature)) {
struct_span_err!(
span_handler,
sess.parse_sess.span_diagnostic,
attr.span,
E0554,
"`#![feature]` may not be used on the {} release channel",

View File

@ -1,9 +1,9 @@
use super::*;
use rustc_ast::ast;
use rustc_ast::with_default_session_globals;
use rustc_span::source_map::respan;
use rustc_span::symbol::Ident;
use rustc_span::with_default_session_globals;
fn fun_to_string(
decl: &ast::FnDecl,

View File

@ -1,13 +1,12 @@
//! Parsing and validation of builtin attributes
use super::{find_by_name, mark_used};
use rustc_ast::ast::{self, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, Handler};
use rustc_errors::{struct_span_err, Applicability};
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
use rustc_macros::HashStable_Generic;
use rustc_session::parse::{feature_err, ParseSess};
use rustc_session::Session;
use rustc_span::hygiene::Transparency;
use rustc_span::{symbol::sym, symbol::Symbol, Span};
use std::num::NonZeroU32;
@ -86,9 +85,9 @@ pub enum UnwindAttr {
}
/// Determine what `#[unwind]` attribute is present in `attrs`, if any.
pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
pub fn find_unwind_attr(sess: &Session, attrs: &[Attribute]) -> Option<UnwindAttr> {
attrs.iter().fold(None, |ia, attr| {
if attr.check_name(sym::unwind) {
if sess.check_name(attr, sym::unwind) {
if let Some(meta) = attr.meta() {
if let MetaItemKind::List(items) = meta.kind {
if items.len() == 1 {
@ -99,19 +98,22 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
}
}
if let Some(d) = diagnostic {
struct_span_err!(d, attr.span, E0633, "malformed `unwind` attribute input")
.span_label(attr.span, "invalid argument")
.span_suggestions(
attr.span,
"the allowed arguments are `allowed` and `aborts`",
(vec!["allowed", "aborts"])
.into_iter()
.map(|s| format!("#[unwind({})]", s)),
Applicability::MachineApplicable,
)
.emit();
};
struct_span_err!(
sess.diagnostic(),
attr.span,
E0633,
"malformed `unwind` attribute input"
)
.span_label(attr.span, "invalid argument")
.span_suggestions(
attr.span,
"the allowed arguments are `allowed` and `aborts`",
(vec!["allowed", "aborts"])
.into_iter()
.map(|s| format!("#[unwind({})]", s)),
Applicability::MachineApplicable,
)
.emit();
}
}
}
@ -161,22 +163,10 @@ impl StabilityLevel {
}
}
/// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`.
/// This will not perform any "sanity checks" on the form of the attributes.
pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
attrs.iter().any(|item| {
item.check_name(sym::feature)
&& item
.meta_item_list()
.map(|list| list.iter().any(|mi| mi.is_word() && mi.has_name(feature_name)))
.unwrap_or(false)
})
}
/// Collects stability info from all stability attributes in `attrs`.
/// Returns `None` if no stability attributes are found.
pub fn find_stability(
sess: &ParseSess,
sess: &Session,
attrs: &[Attribute],
item_sp: Span,
) -> (Option<Stability>, Option<ConstStability>) {
@ -184,7 +174,7 @@ pub fn find_stability(
}
fn find_stability_generic<'a, I>(
sess: &ParseSess,
sess: &Session,
attrs_iter: I,
item_sp: Span,
) -> (Option<Stability>, Option<ConstStability>)
@ -197,7 +187,7 @@ where
let mut const_stab: Option<ConstStability> = None;
let mut promotable = false;
let mut allow_const_fn_ptr = false;
let diagnostic = &sess.span_diagnostic;
let diagnostic = &sess.parse_sess.span_diagnostic;
'outer: for attr in attrs_iter {
if ![
@ -214,7 +204,7 @@ where
continue; // not a stability level
}
mark_used(attr);
sess.mark_attr_used(attr);
let meta = attr.meta();
@ -230,7 +220,7 @@ where
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(
sess,
&sess.parse_sess,
meta.span,
AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
@ -249,10 +239,18 @@ where
match meta_name {
sym::rustc_const_unstable | sym::unstable => {
if meta_name == sym::unstable && stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
handle_errors(
&sess.parse_sess,
attr.span,
AttrError::MultipleStabilityLevels,
);
break;
} else if meta_name == sym::rustc_const_unstable && const_stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
handle_errors(
&sess.parse_sess,
attr.span,
AttrError::MultipleStabilityLevels,
);
break;
}
@ -318,13 +316,13 @@ where
sym::soft => {
if !mi.is_word() {
let msg = "`soft` should not have any arguments";
sess.span_diagnostic.span_err(mi.span, msg);
sess.parse_sess.span_diagnostic.span_err(mi.span, msg);
}
is_soft = true;
}
_ => {
handle_errors(
sess,
&sess.parse_sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
@ -336,7 +334,7 @@ where
}
} else {
handle_errors(
sess,
&sess.parse_sess,
meta.span(),
AttrError::UnsupportedLiteral("unsupported literal", false),
);
@ -359,7 +357,7 @@ where
}
}
(None, _, _) => {
handle_errors(sess, attr.span, AttrError::MissingFeature);
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
continue;
}
_ => {
@ -371,10 +369,18 @@ where
}
sym::rustc_const_stable | sym::stable => {
if meta_name == sym::stable && stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
handle_errors(
&sess.parse_sess,
attr.span,
AttrError::MultipleStabilityLevels,
);
break;
} else if meta_name == sym::rustc_const_stable && const_stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
handle_errors(
&sess.parse_sess,
attr.span,
AttrError::MultipleStabilityLevels,
);
break;
}
@ -395,7 +401,7 @@ where
}
_ => {
handle_errors(
sess,
&sess.parse_sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
@ -407,7 +413,7 @@ where
},
NestedMetaItem::Literal(lit) => {
handle_errors(
sess,
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral("unsupported literal", false),
);
@ -431,11 +437,11 @@ where
}
}
(None, _) => {
handle_errors(sess, attr.span, AttrError::MissingFeature);
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
continue;
}
_ => {
handle_errors(sess, attr.span, AttrError::MissingSince);
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
continue;
}
}
@ -466,8 +472,8 @@ where
(stab, const_stab)
}
pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
super::first_attr_value_str_by_name(attrs, sym::crate_name)
pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option<Symbol> {
sess.first_attr_value_str_by_name(attrs, sym::crate_name)
}
/// Tests if a cfg-pattern matches the cfg set
@ -630,16 +636,12 @@ pub struct Deprecation {
}
/// Finds the deprecation attribute. `None` if none exists.
pub fn find_deprecation(
sess: &ParseSess,
attrs: &[Attribute],
item_sp: Span,
) -> Option<Deprecation> {
pub fn find_deprecation(sess: &Session, attrs: &[Attribute], item_sp: Span) -> Option<Deprecation> {
find_deprecation_generic(sess, attrs.iter(), item_sp)
}
fn find_deprecation_generic<'a, I>(
sess: &ParseSess,
sess: &Session,
attrs_iter: I,
item_sp: Span,
) -> Option<Deprecation>
@ -647,10 +649,11 @@ where
I: Iterator<Item = &'a Attribute>,
{
let mut depr: Option<Deprecation> = None;
let diagnostic = &sess.span_diagnostic;
let diagnostic = &sess.parse_sess.span_diagnostic;
'outer: for attr in attrs_iter {
if !(attr.check_name(sym::deprecated) || attr.check_name(sym::rustc_deprecated)) {
if !(sess.check_name(attr, sym::deprecated) || sess.check_name(attr, sym::rustc_deprecated))
{
continue;
}
@ -673,7 +676,7 @@ where
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(
sess,
&sess.parse_sess,
meta.span,
AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
@ -685,7 +688,7 @@ where
} else {
if let Some(lit) = meta.name_value_literal() {
handle_errors(
sess,
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral(
"literal in `deprecated` \
@ -710,28 +713,28 @@ where
continue 'outer;
}
}
sym::note if attr.check_name(sym::deprecated) => {
sym::note if sess.check_name(attr, sym::deprecated) => {
if !get(mi, &mut note) {
continue 'outer;
}
}
sym::reason if attr.check_name(sym::rustc_deprecated) => {
sym::reason if sess.check_name(attr, sym::rustc_deprecated) => {
if !get(mi, &mut note) {
continue 'outer;
}
}
sym::suggestion if attr.check_name(sym::rustc_deprecated) => {
sym::suggestion if sess.check_name(attr, sym::rustc_deprecated) => {
if !get(mi, &mut suggestion) {
continue 'outer;
}
}
_ => {
handle_errors(
sess,
&sess.parse_sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
if attr.check_name(sym::deprecated) {
if sess.check_name(attr, sym::deprecated) {
&["since", "note"]
} else {
&["since", "reason", "suggestion"]
@ -743,7 +746,7 @@ where
},
NestedMetaItem::Literal(lit) => {
handle_errors(
sess,
&sess.parse_sess,
lit.span,
AttrError::UnsupportedLiteral(
"item in `deprecated` must be a key/value pair",
@ -757,13 +760,13 @@ where
}
}
if suggestion.is_some() && attr.check_name(sym::deprecated) {
if suggestion.is_some() && sess.check_name(attr, sym::deprecated) {
unreachable!("only allowed on rustc_deprecated")
}
if attr.check_name(sym::rustc_deprecated) {
if sess.check_name(attr, sym::rustc_deprecated) {
if since.is_none() {
handle_errors(sess, attr.span, AttrError::MissingSince);
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
continue;
}
@ -773,9 +776,9 @@ where
}
}
mark_used(&attr);
sess.mark_attr_used(&attr);
let is_since_rustc_version = attr.check_name(sym::rustc_deprecated);
let is_since_rustc_version = sess.check_name(attr, sym::rustc_deprecated);
depr = Some(Deprecation { since, note, suggestion, is_since_rustc_version });
}
@ -818,18 +821,18 @@ impl IntType {
/// the same discriminant size that the corresponding C enum would or C
/// structure layout, `packed` to remove padding, and `transparent` to elegate representation
/// concerns to the only non-ZST field.
pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
use ReprAttr::*;
let mut acc = Vec::new();
let diagnostic = &sess.span_diagnostic;
let diagnostic = &sess.parse_sess.span_diagnostic;
if attr.has_name(sym::repr) {
if let Some(items) = attr.meta_item_list() {
mark_used(attr);
sess.mark_attr_used(attr);
for item in items {
if !item.is_meta_item() {
handle_errors(
sess,
&sess.parse_sess,
item.span(),
AttrError::UnsupportedLiteral(
"meta item in `repr` must be an identifier",
@ -973,13 +976,14 @@ pub enum TransparencyError {
}
pub fn find_transparency(
sess: &Session,
attrs: &[Attribute],
macro_rules: bool,
) -> (Transparency, Option<TransparencyError>) {
let mut transparency = None;
let mut error = None;
for attr in attrs {
if attr.check_name(sym::rustc_macro_transparency) {
if sess.check_name(attr, sym::rustc_macro_transparency) {
if let Some((_, old_span)) = transparency {
error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span));
break;
@ -1004,18 +1008,20 @@ pub fn find_transparency(
}
pub fn allow_internal_unstable<'a>(
sess: &'a Session,
attrs: &[Attribute],
diag: &'a rustc_errors::Handler,
) -> Option<impl Iterator<Item = Symbol> + 'a> {
let attr = find_by_name(attrs, sym::allow_internal_unstable)?;
let attr = sess.find_by_name(attrs, sym::allow_internal_unstable)?;
let list = attr.meta_item_list().or_else(|| {
diag.span_err(attr.span, "allow_internal_unstable expects list of feature names");
sess.diagnostic()
.span_err(attr.span, "allow_internal_unstable expects list of feature names");
None
})?;
Some(list.into_iter().filter_map(move |it| {
let name = it.ident().map(|ident| ident.name);
if name.is_none() {
diag.span_err(it.span(), "`allow_internal_unstable` expects feature names");
sess.diagnostic()
.span_err(it.span(), "`allow_internal_unstable` expects feature names");
}
name
}))

View File

@ -19,7 +19,7 @@ pub fn expand_cfg(
match parse_cfg(cx, sp, tts) {
Ok(cfg) => {
let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
let matches_cfg = attr::cfg_matches(&cfg, &cx.sess.parse_sess, cx.ecfg.features);
MacEager::expr(cx.expr_bool(sp, matches_cfg))
}
Err(mut err) => {

View File

@ -37,7 +37,12 @@ impl MultiItemModifier for Expander {
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
let attr = &ecx.attribute(meta_item.clone());
validate_attr::check_builtin_attribute(ecx.parse_sess, attr, sym::cfg_accessible, template);
validate_attr::check_builtin_attribute(
&ecx.sess.parse_sess,
attr,
sym::cfg_accessible,
template,
);
let path = match validate_input(ecx, meta_item) {
Some(path) => path,

View File

@ -72,7 +72,7 @@ fn default_substructure(
},
StaticEnum(..) => {
struct_span_err!(
cx.parse_sess.span_diagnostic,
&cx.sess.parse_sess.span_diagnostic,
trait_span,
E0665,
"`Default` cannot be derived for enums, only structs"

View File

@ -392,7 +392,7 @@ impl<'a> TraitDef<'a> {
match *item {
Annotatable::Item(ref item) => {
let is_packed = item.attrs.iter().any(|attr| {
for r in attr::find_repr_attrs(&cx.parse_sess, attr) {
for r in attr::find_repr_attrs(&cx.sess, attr) {
if let attr::ReprPacked(_) = r {
return true;
}
@ -677,7 +677,7 @@ impl<'a> TraitDef<'a> {
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
// Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr);
cx.sess.mark_attr_used(&attr);
let opt_trait_ref = Some(trait_ref);
let unused_qual = {
let word = rustc_ast::attr::mk_nested_word_item(Ident::new(

View File

@ -23,7 +23,7 @@ pub fn expand_option_env<'cx>(
let sp = cx.with_def_site_ctxt(sp);
let value = env::var(&var.as_str()).ok().as_deref().map(Symbol::intern);
cx.parse_sess.env_depinfo.borrow_mut().insert((Symbol::intern(&var), value));
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((Symbol::intern(&var), value));
let e = match value {
None => {
let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
@ -81,7 +81,7 @@ pub fn expand_env<'cx>(
let sp = cx.with_def_site_ctxt(sp);
let value = env::var(&*var.as_str()).ok().as_deref().map(Symbol::intern);
cx.parse_sess.env_depinfo.borrow_mut().insert((var, value));
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
let e = match value {
None => {
cx.span_err(sp, &msg.as_str());

View File

@ -19,7 +19,7 @@ pub fn expand(
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);
let not_static = |item: Annotatable| {
ecx.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
vec![item]
};
let item = match item {

View File

@ -110,7 +110,7 @@ fn parse_inline_asm<'a>(
// If we already have a string with instructions,
// ending up in Asm state again is an error.
return Err(struct_span_err!(
cx.parse_sess.span_diagnostic,
cx.sess.parse_sess.span_diagnostic,
sp,
E0660,
"malformed inline assembly"
@ -171,7 +171,7 @@ fn parse_inline_asm<'a>(
Some('+') => Some(Symbol::intern(&format!("={}", ch.as_str()))),
_ => {
struct_span_err!(
cx.parse_sess.span_diagnostic,
cx.sess.parse_sess.span_diagnostic,
span,
E0661,
"output operand constraint lacks '=' or '+'"
@ -201,7 +201,7 @@ fn parse_inline_asm<'a>(
if constraint.as_str().starts_with('=') {
struct_span_err!(
cx.parse_sess.span_diagnostic,
cx.sess.parse_sess.span_diagnostic,
p.prev_token.span,
E0662,
"input operand constraint contains '='"
@ -209,7 +209,7 @@ fn parse_inline_asm<'a>(
.emit();
} else if constraint.as_str().starts_with('+') {
struct_span_err!(
cx.parse_sess.span_diagnostic,
cx.sess.parse_sess.span_diagnostic,
p.prev_token.span,
E0663,
"input operand constraint contains '+'"
@ -236,7 +236,7 @@ fn parse_inline_asm<'a>(
cx.span_warn(p.prev_token.span, "expected a clobber, found an option");
} else if s.as_str().starts_with('{') || s.as_str().ends_with('}') {
struct_span_err!(
cx.parse_sess.span_diagnostic,
cx.sess.parse_sess.span_diagnostic,
p.prev_token.span,
E0664,
"clobber should not be surrounded by braces"

View File

@ -2,13 +2,12 @@ use std::mem;
use rustc_ast::ast::{self, NodeId};
use rustc_ast::attr;
use rustc_ast::expand::is_proc_macro_attr;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, Visitor};
use rustc_ast_pretty::pprust;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::hygiene::AstPass;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -42,6 +41,7 @@ enum ProcMacro {
}
struct CollectProcMacros<'a> {
sess: &'a Session,
macros: Vec<ProcMacro>,
in_root: bool,
handler: &'a rustc_errors::Handler,
@ -51,7 +51,7 @@ struct CollectProcMacros<'a> {
}
pub fn inject(
sess: &ParseSess,
sess: &Session,
resolver: &mut dyn ResolverExpand,
mut krate: ast::Crate,
is_proc_macro_crate: bool,
@ -64,6 +64,7 @@ pub fn inject(
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
let mut collect = CollectProcMacros {
sess,
macros: Vec::new(),
in_root: true,
handler,
@ -244,7 +245,7 @@ impl<'a> CollectProcMacros<'a> {
impl<'a> Visitor<'a> for CollectProcMacros<'a> {
fn visit_item(&mut self, item: &'a ast::Item) {
if let ast::ItemKind::MacroDef(..) = item.kind {
if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) {
if self.is_proc_macro_crate && self.sess.contains_name(&item.attrs, sym::macro_export) {
let msg =
"cannot export macro_rules! macros from a `proc-macro` crate type currently";
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
@ -263,7 +264,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
let mut found_attr: Option<&'a ast::Attribute> = None;
for attr in &item.attrs {
if is_proc_macro_attr(&attr) {
if self.sess.is_proc_macro_attr(&attr) {
if let Some(prev_attr) = found_attr {
let prev_item = prev_attr.get_normal_item();
let item = attr.get_normal_item();
@ -331,11 +332,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
return;
}
if attr.check_name(sym::proc_macro_derive) {
if self.sess.check_name(attr, sym::proc_macro_derive) {
self.collect_custom_derive(item, attr);
} else if attr.check_name(sym::proc_macro_attribute) {
} else if self.sess.check_name(attr, sym::proc_macro_attribute) {
self.collect_attr_proc_macro(item);
} else if attr.check_name(sym::proc_macro) {
} else if self.sess.check_name(attr, sym::proc_macro) {
self.collect_bang_proc_macro(item);
};

View File

@ -1,8 +1,8 @@
use rustc_ast::ast;
use rustc_ast::ptr::P;
use rustc_ast::{ast, attr};
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::ExpansionConfig;
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::hygiene::AstPass;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -11,16 +11,16 @@ use rustc_span::DUMMY_SP;
pub fn inject(
mut krate: ast::Crate,
resolver: &mut dyn ResolverExpand,
sess: &ParseSess,
sess: &Session,
alt_std_name: Option<Symbol>,
) -> (ast::Crate, Option<Symbol>) {
let rust_2018 = sess.edition >= Edition::Edition2018;
let rust_2018 = sess.parse_sess.edition >= Edition::Edition2018;
// 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) {
let names: &[Symbol] = if sess.contains_name(&krate.attrs, sym::no_core) {
return (krate, None);
} else if attr::contains_name(&krate.attrs, sym::no_std) {
if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
} else if sess.contains_name(&krate.attrs, sym::no_std) {
if sess.contains_name(&krate.attrs, sym::compiler_builtins) {
&[sym::core]
} else {
&[sym::core, sym::compiler_builtins]

View File

@ -6,6 +6,7 @@ use rustc_ast::ast;
use rustc_ast::attr;
use rustc_ast_pretty::pprust;
use rustc_expand::base::*;
use rustc_session::Session;
use rustc_span::source_map::respan;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@ -87,7 +88,7 @@ pub fn expand_test_or_bench(
};
if let ast::ItemKind::MacCall(_) = item.kind {
cx.parse_sess.span_diagnostic.span_warn(
cx.sess.parse_sess.span_diagnostic.span_warn(
item.span,
"`#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead.",
);
@ -232,9 +233,15 @@ pub fn expand_test_or_bench(
),
),
// ignore: true | false
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
field(
"ignore",
cx.expr_bool(sp, should_ignore(&cx.sess, &item)),
),
// allow_fail: true | false
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
field(
"allow_fail",
cx.expr_bool(sp, should_fail(&cx.sess, &item)),
),
// should_panic: ...
field(
"should_panic",
@ -318,18 +325,18 @@ enum ShouldPanic {
Yes(Option<Symbol>),
}
fn should_ignore(i: &ast::Item) -> bool {
attr::contains_name(&i.attrs, sym::ignore)
fn should_ignore(sess: &Session, i: &ast::Item) -> bool {
sess.contains_name(&i.attrs, sym::ignore)
}
fn should_fail(i: &ast::Item) -> bool {
attr::contains_name(&i.attrs, sym::allow_fail)
fn should_fail(sess: &Session, i: &ast::Item) -> bool {
sess.contains_name(&i.attrs, sym::allow_fail)
}
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
match attr::find_by_name(&i.attrs, sym::should_panic) {
match cx.sess.find_by_name(&i.attrs, sym::should_panic) {
Some(attr) => {
let sd = &cx.parse_sess.span_diagnostic;
let sd = &cx.sess.parse_sess.span_diagnostic;
match attr.meta_item_list() {
// Handle #[should_panic(expected = "foo")]
@ -393,8 +400,8 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
}
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
let sd = &cx.parse_sess.span_diagnostic;
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
let sd = &cx.sess.parse_sess.span_diagnostic;
if let ast::ItemKind::Fn(_, ref sig, ref generics, _) = i.kind {
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
@ -453,7 +460,7 @@ fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
};
if !has_sig {
cx.parse_sess.span_diagnostic.span_err(
cx.sess.parse_sess.span_diagnostic.span_err(
i.span,
"functions used as benches must have \
signature `fn(&mut Bencher) -> impl Termination`",

View File

@ -3,13 +3,13 @@
use log::debug;
use rustc_ast::ast;
use rustc_ast::attr;
use rustc_ast::entry::{self, EntryPointType};
use rustc_ast::entry::EntryPointType;
use rustc_ast::mut_visit::{ExpectOne, *};
use rustc_ast::ptr::P;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency};
use rustc_span::source_map::respan;
use rustc_span::symbol::{sym, Ident, Symbol};
@ -35,41 +35,35 @@ 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: &ParseSess,
resolver: &mut dyn ResolverExpand,
should_test: bool,
krate: &mut ast::Crate,
span_diagnostic: &rustc_errors::Handler,
features: &Features,
panic_strategy: PanicStrategy,
platform_panic_strategy: PanicStrategy,
enable_panic_abort_tests: bool,
) {
pub fn inject(sess: &Session, resolver: &mut dyn ResolverExpand, krate: &mut ast::Crate) {
let span_diagnostic = sess.diagnostic();
let panic_strategy = sess.panic_strategy();
let platform_panic_strategy = sess.target.target.options.panic_strategy;
// Check for #![reexport_test_harness_main = "some_name"] which gives the
// main test function the name `some_name` without hygiene. This needs to be
// unconditional, so that the attribute is still marked as used in
// non-test builds.
let reexport_test_harness_main =
attr::first_attr_value_str_by_name(&krate.attrs, sym::reexport_test_harness_main);
sess.first_attr_value_str_by_name(&krate.attrs, sym::reexport_test_harness_main);
// Do this here so that the test_runner crate attribute gets marked as used
// even in non-test builds
let test_runner = get_test_runner(span_diagnostic, &krate);
let test_runner = get_test_runner(sess, span_diagnostic, &krate);
if should_test {
let panic_strategy = match (panic_strategy, enable_panic_abort_tests) {
if sess.opts.test {
let panic_strategy = match (panic_strategy, sess.opts.debugging_opts.panic_abort_tests) {
(PanicStrategy::Abort, true) => PanicStrategy::Abort,
(PanicStrategy::Abort, false) if panic_strategy == platform_panic_strategy => {
// Silently allow compiling with panic=abort on these platforms,
// but with old behavior (abort if a test fails).
PanicStrategy::Unwind
}
(PanicStrategy::Abort, false) => {
span_diagnostic.err(
"building tests with panic=abort is not supported \
without `-Zpanic_abort_tests`",
);
if panic_strategy == platform_panic_strategy {
// Silently allow compiling with panic=abort on these platforms,
// but with old behavior (abort if a test fails).
} else {
span_diagnostic.err(
"building tests with panic=abort is not supported \
without `-Zpanic_abort_tests`",
);
}
PanicStrategy::Unwind
}
(PanicStrategy::Unwind, _) => PanicStrategy::Unwind,
@ -79,7 +73,7 @@ pub fn inject(
resolver,
reexport_test_harness_main,
krate,
features,
&sess.features_untracked(),
panic_strategy,
test_runner,
)
@ -101,7 +95,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
let mut item = i.into_inner();
if is_test_case(&item) {
if is_test_case(&self.cx.ext_cx.sess, &item) {
debug!("this is a test item");
let test = Test { span: item.span, ident: item.ident };
@ -143,15 +137,39 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
}
}
// Beware, this is duplicated in librustc_passes/entry.rs (with
// `rustc_hir::Item`), so make sure to keep them in sync.
fn entry_point_type(sess: &Session, item: &ast::Item, depth: usize) -> EntryPointType {
match item.kind {
ast::ItemKind::Fn(..) => {
if sess.contains_name(&item.attrs, sym::start) {
EntryPointType::Start
} else if sess.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,
}
}
/// A folder used to remove any entry points (like fn main) because the harness
/// generator will provide its own
struct EntryPointCleaner {
struct EntryPointCleaner<'a> {
// Current depth in the ast
sess: &'a Session,
depth: usize,
def_site: Span,
}
impl MutVisitor for EntryPointCleaner {
impl<'a> MutVisitor for EntryPointCleaner<'a> {
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
self.depth += 1;
let item = noop_flat_map_item(i, self).expect_one("noop did something");
@ -160,7 +178,7 @@ impl MutVisitor for EntryPointCleaner {
// Remove any #[main] or #[start] from the AST so it doesn't
// clash with the one we're going to add, but mark it as
// #[allow(dead_code)] to avoid printing warnings.
let item = match entry::entry_point_type(&item, self.depth) {
let item = match entry_point_type(self.sess, &item, self.depth) {
EntryPointType::MainNamed | EntryPointType::MainAttr | EntryPointType::Start => item
.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| {
let allow_ident = Ident::new(sym::allow, self.def_site);
@ -170,7 +188,10 @@ impl MutVisitor for EntryPointCleaner {
let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
let attrs = attrs
.into_iter()
.filter(|attr| !attr.check_name(sym::main) && !attr.check_name(sym::start))
.filter(|attr| {
!self.sess.check_name(attr, sym::main)
&& !self.sess.check_name(attr, sym::start)
})
.chain(iter::once(allow_dead_code))
.collect();
@ -189,7 +210,7 @@ impl MutVisitor for EntryPointCleaner {
/// Crawl over the crate, inserting test reexports and the test main function
fn generate_test_harness(
sess: &ParseSess,
sess: &Session,
resolver: &mut dyn ResolverExpand,
reexport_test_harness_main: Option<Symbol>,
krate: &mut ast::Crate,
@ -211,7 +232,7 @@ fn generate_test_harness(
let def_site = DUMMY_SP.with_def_site_ctxt(expn_id);
// Remove the entry points
let mut cleaner = EntryPointCleaner { depth: 0, def_site };
let mut cleaner = EntryPointCleaner { sess, depth: 0, def_site };
cleaner.visit_crate(krate);
let cx = TestCtxt {
@ -339,12 +360,16 @@ fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> P<ast::Expr> {
)
}
fn is_test_case(i: &ast::Item) -> bool {
attr::contains_name(&i.attrs, sym::rustc_test_marker)
fn is_test_case(sess: &Session, i: &ast::Item) -> bool {
sess.contains_name(&i.attrs, sym::rustc_test_marker)
}
fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
fn get_test_runner(
sess: &Session,
sd: &rustc_errors::Handler,
krate: &ast::Crate,
) -> Option<ast::Path> {
let test_attr = sess.find_by_name(&krate.attrs, sym::test_runner)?;
let meta_list = test_attr.meta_item_list()?;
let span = test_attr.span;
match &*meta_list {

View File

@ -8,5 +8,5 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na
// All the built-in macro attributes are "words" at the moment.
let template = AttributeTemplate { word: true, ..Default::default() };
let attr = ecx.attribute(meta_item.clone());
validate_attr::check_builtin_attribute(ecx.parse_sess, &attr, name, template);
validate_attr::check_builtin_attribute(&ecx.sess.parse_sess, &attr, name, template);
}

View File

@ -253,7 +253,7 @@ impl CodegenCx<'ll, 'tcx> {
debug!("get_static: sym={} attrs={:?}", sym, attrs);
for attr in attrs {
if attr.check_name(sym::thread_local) {
if self.tcx.sess.check_name(attr, sym::thread_local) {
llvm::set_thread_local_mode(g, self.tls_model);
}
}

View File

@ -9,7 +9,6 @@ use rustc_codegen_ssa::traits::*;
use rustc_middle::bug;
use rustc_session::config::DebugInfo;
use rustc_ast::attr;
use rustc_span::symbol::sym;
/// Inserts a side-effect free instruction sequence that makes sure that the
@ -61,8 +60,10 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>) -
}
pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
let omit_gdb_pretty_printer_section =
attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
let omit_gdb_pretty_printer_section = cx
.tcx
.sess
.contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
!omit_gdb_pretty_printer_section
&& cx.sess().opts.debuginfo != DebugInfo::None

View File

@ -9,7 +9,6 @@ use crate::{
use crate::traits::*;
use jobserver::{Acquired, Client};
use rustc_ast::attr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::profiling::TimingGuard;
@ -416,11 +415,12 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
let crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_hash = tcx.crate_hash(LOCAL_CRATE);
let no_builtins = attr::contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins);
let no_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins);
let is_compiler_builtins =
attr::contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins);
let subsystem =
attr::first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem);
tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins);
let subsystem = tcx
.sess
.first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem);
let windows_subsystem = subsystem.map(|subsystem| {
if subsystem != sym::windows && subsystem != sym::console {
tcx.sess.fatal(&format!(

View File

@ -677,7 +677,7 @@ impl RustcDefaultCalls {
let t_outputs = rustc_interface::util::build_output_filenames(
input, odir, ofile, attrs, sess,
);
let id = rustc_session::output::find_crate_name(Some(sess), attrs, input);
let id = rustc_session::output::find_crate_name(sess, attrs, input);
if *req == PrintRequest::CrateName {
println!("{}", id);
continue;

View File

@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{self, Lrc};
use rustc_errors::{DiagnosticBuilder, ErrorReported};
use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
use rustc_session::{parse::ParseSess, Limit};
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind};
@ -790,7 +790,7 @@ impl SyntaxExtension {
/// Constructs a syntax extension with the given properties
/// and other properties converted from attributes.
pub fn new(
sess: &ParseSess,
sess: &Session,
kind: SyntaxExtensionKind,
span: Span,
helper_attrs: Vec<Symbol>,
@ -798,27 +798,29 @@ impl SyntaxExtension {
name: Symbol,
attrs: &[ast::Attribute],
) -> SyntaxExtension {
let allow_internal_unstable = attr::allow_internal_unstable(&attrs, &sess.span_diagnostic)
let allow_internal_unstable = attr::allow_internal_unstable(sess, &attrs)
.map(|features| features.collect::<Vec<Symbol>>().into());
let mut local_inner_macros = false;
if let Some(macro_export) = attr::find_by_name(attrs, sym::macro_export) {
if let Some(macro_export) = sess.find_by_name(attrs, sym::macro_export) {
if let Some(l) = macro_export.meta_item_list() {
local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
}
}
let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro);
let is_builtin = sess.contains_name(attrs, sym::rustc_builtin_macro);
let (stability, const_stability) = attr::find_stability(&sess, attrs, span);
if const_stability.is_some() {
sess.span_diagnostic.span_err(span, "macros cannot have const stability attributes");
sess.parse_sess
.span_diagnostic
.span_err(span, "macros cannot have const stability attributes");
}
SyntaxExtension {
kind,
span,
allow_internal_unstable,
allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe),
allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe),
local_inner_macros,
stability,
deprecation: attr::find_deprecation(&sess, attrs, span),
@ -941,7 +943,7 @@ pub struct ExpansionData {
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
/// -> expn_data` of their expansion context stored into their span.
pub struct ExtCtxt<'a> {
pub parse_sess: &'a ParseSess,
pub sess: &'a Session,
pub ecfg: expand::ExpansionConfig<'a>,
pub reduced_recursion_limit: Option<Limit>,
pub root_path: PathBuf,
@ -954,13 +956,13 @@ pub struct ExtCtxt<'a> {
impl<'a> ExtCtxt<'a> {
pub fn new(
parse_sess: &'a ParseSess,
sess: &'a Session,
ecfg: expand::ExpansionConfig<'a>,
resolver: &'a mut dyn ResolverExpand,
extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
) -> ExtCtxt<'a> {
ExtCtxt {
parse_sess,
sess,
ecfg,
reduced_recursion_limit: None,
resolver,
@ -988,13 +990,13 @@ impl<'a> ExtCtxt<'a> {
expand::MacroExpander::new(self, true)
}
pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
rustc_parse::stream_to_parser(self.parse_sess, stream, MACRO_ARGUMENTS)
rustc_parse::stream_to_parser(&self.sess.parse_sess, stream, MACRO_ARGUMENTS)
}
pub fn source_map(&self) -> &'a SourceMap {
self.parse_sess.source_map()
self.sess.parse_sess.source_map()
}
pub fn parse_sess(&self) -> &'a ParseSess {
self.parse_sess
&self.sess.parse_sess
}
pub fn call_site(&self) -> Span {
self.current_expansion.id.expn_data().call_site
@ -1026,7 +1028,7 @@ impl<'a> ExtCtxt<'a> {
}
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg)
}
/// Emit `msg` attached to `sp`, without immediately stopping
@ -1035,17 +1037,17 @@ impl<'a> ExtCtxt<'a> {
/// Compilation will be stopped in the near future (at the end of
/// the macro expansion phase).
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.parse_sess.span_diagnostic.span_err(sp, msg);
self.sess.parse_sess.span_diagnostic.span_err(sp, msg);
}
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.parse_sess.span_diagnostic.span_warn(sp, msg);
self.sess.parse_sess.span_diagnostic.span_warn(sp, msg);
}
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
self.parse_sess.span_diagnostic.span_bug(sp, msg);
self.sess.parse_sess.span_diagnostic.span_bug(sp, msg);
}
pub fn trace_macros_diag(&mut self) {
for (sp, notes) in self.expansions.iter() {
let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, "trace_macro");
let mut db = self.sess.parse_sess.span_diagnostic.span_note_diag(*sp, "trace_macro");
for note in notes {
db.note(note);
}
@ -1055,7 +1057,7 @@ impl<'a> ExtCtxt<'a> {
self.expansions.clear();
}
pub fn bug(&self, msg: &str) -> ! {
self.parse_sess.span_diagnostic.bug(msg);
self.sess.parse_sess.span_diagnostic.bug(msg);
}
pub fn trace_macros(&self) -> bool {
self.ecfg.trace_mac

View File

@ -13,7 +13,8 @@ use rustc_feature::{
ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
};
use rustc_parse::{parse_in, validate_attr};
use rustc_session::parse::{feature_err, ParseSess};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edition::{Edition, ALL_EDITIONS};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
@ -22,15 +23,14 @@ use smallvec::SmallVec;
/// A folder that strips out items that do not belong in the current configuration.
pub struct StripUnconfigured<'a> {
pub sess: &'a ParseSess,
pub sess: &'a Session,
pub features: Option<&'a Features>,
}
fn get_features(
sess: &Session,
span_handler: &Handler,
krate_attrs: &[ast::Attribute],
crate_edition: Edition,
allow_features: &Option<Vec<String>>,
) -> Features {
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
@ -53,6 +53,7 @@ fn get_features(
let mut features = Features::default();
let mut edition_enabled_features = FxHashMap::default();
let crate_edition = sess.edition();
for &edition in ALL_EDITIONS {
if edition <= crate_edition {
@ -70,7 +71,7 @@ fn get_features(
// Process the edition umbrella feature-gates first, to ensure
// `edition_enabled_features` is completed before it's queried.
for attr in krate_attrs {
if !attr.check_name(sym::feature) {
if !sess.check_name(attr, sym::feature) {
continue;
}
@ -103,7 +104,7 @@ fn get_features(
}
for attr in krate_attrs {
if !attr.check_name(sym::feature) {
if !sess.check_name(attr, sym::feature) {
continue;
}
@ -165,7 +166,7 @@ fn get_features(
continue;
}
if let Some(allowed) = allow_features.as_ref() {
if let Some(allowed) = sess.opts.debugging_opts.allow_features.as_ref() {
if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
struct_span_err!(
span_handler,
@ -193,16 +194,11 @@ fn get_features(
}
// `cfg_attr`-process the crate's attributes and compute the crate's features.
pub fn features(
mut krate: ast::Crate,
sess: &ParseSess,
edition: Edition,
allow_features: &Option<Vec<String>>,
) -> (ast::Crate, Features) {
pub fn features(sess: &Session, mut krate: ast::Crate) -> (ast::Crate, Features) {
let mut strip_unconfigured = StripUnconfigured { sess, features: None };
let unconfigured_attrs = krate.attrs.clone();
let diag = &sess.span_diagnostic;
let diag = &sess.parse_sess.span_diagnostic;
let err_count = diag.err_count();
let features = match strip_unconfigured.configure(krate.attrs) {
None => {
@ -213,7 +209,7 @@ pub fn features(
}
Some(attrs) => {
krate.attrs = attrs;
let features = get_features(diag, &krate.attrs, edition, allow_features);
let features = get_features(sess, diag, &krate.attrs);
if err_count == diag.err_count() {
// Avoid reconfiguring malformed `cfg_attr`s.
strip_unconfigured.features = Some(&features);
@ -281,9 +277,9 @@ impl<'a> StripUnconfigured<'a> {
}
// At this point we know the attribute is considered used.
attr::mark_used(&attr);
self.sess.mark_attr_used(&attr);
if !attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
if !attr::cfg_matches(&cfg_predicate, &self.sess.parse_sess, self.features) {
return vec![];
}
@ -303,8 +299,10 @@ impl<'a> StripUnconfigured<'a> {
match attr.get_normal_item().args {
ast::MacArgs::Delimited(dspan, delim, ref tts) if !tts.is_empty() => {
let msg = "wrong `cfg_attr` delimiters";
validate_attr::check_meta_bad_delim(self.sess, dspan, delim, msg);
match parse_in(self.sess, tts.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
validate_attr::check_meta_bad_delim(&self.sess.parse_sess, dspan, delim, msg);
match parse_in(&self.sess.parse_sess, tts.clone(), "`cfg_attr` input", |p| {
p.parse_cfg_attr()
}) {
Ok(r) => return Some(r),
Err(mut e) => {
e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP))
@ -320,6 +318,7 @@ impl<'a> StripUnconfigured<'a> {
fn error_malformed_cfg_attr_missing(&self, span: Span) {
self.sess
.parse_sess
.span_diagnostic
.struct_span_err(span, "malformed `cfg_attr` attribute input")
.span_suggestion(
@ -335,10 +334,10 @@ impl<'a> StripUnconfigured<'a> {
/// Determines if a node with the given attributes should be included in this configuration.
pub fn in_cfg(&self, attrs: &[Attribute]) -> bool {
attrs.iter().all(|attr| {
if !is_cfg(attr) {
if !is_cfg(self.sess, attr) {
return true;
}
let meta_item = match validate_attr::parse_meta(self.sess, attr) {
let meta_item = match validate_attr::parse_meta(&self.sess.parse_sess, attr) {
Ok(meta_item) => meta_item,
Err(mut err) => {
err.emit();
@ -346,7 +345,7 @@ impl<'a> StripUnconfigured<'a> {
}
};
let error = |span, msg, suggestion: &str| {
let mut err = self.sess.span_diagnostic.struct_span_err(span, msg);
let mut err = self.sess.parse_sess.span_diagnostic.struct_span_err(span, msg);
if !suggestion.is_empty() {
err.span_suggestion(
span,
@ -364,7 +363,9 @@ impl<'a> StripUnconfigured<'a> {
Some([]) => error(span, "`cfg` predicate is not specified", ""),
Some([_, .., l]) => error(l.span(), "multiple `cfg` predicates are specified", ""),
Some([single]) => match single.meta_item() {
Some(meta_item) => attr::cfg_matches(meta_item, self.sess, self.features),
Some(meta_item) => {
attr::cfg_matches(meta_item, &self.sess.parse_sess, self.features)
}
None => error(single.span(), "`cfg` predicate key cannot be a literal", ""),
},
}
@ -383,7 +384,7 @@ impl<'a> StripUnconfigured<'a> {
pub fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) {
let mut err = feature_err(
self.sess,
&self.sess.parse_sess,
sym::stmt_expr_attributes,
attr.span,
"attributes on expressions are experimental",
@ -452,9 +453,9 @@ impl<'a> StripUnconfigured<'a> {
//
// N.B., this is intentionally not part of the visit_expr() function
// in order for filter_map_expr() to be able to avoid this check
if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(self.sess, a)) {
let msg = "removing an expression is not supported in this position";
self.sess.span_diagnostic.span_err(attr.span, msg);
self.sess.parse_sess.span_diagnostic.span_err(attr.span, msg);
}
self.process_cfg_attrs(expr)
@ -527,6 +528,6 @@ impl<'a> MutVisitor for StripUnconfigured<'a> {
}
}
fn is_cfg(attr: &Attribute) -> bool {
attr.check_name(sym::cfg)
fn is_cfg(sess: &Session, attr: &Attribute) -> bool {
sess.check_name(attr, sym::cfg)
}

View File

@ -527,7 +527,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) {
let attr = attr::find_by_name(item.attrs(), sym::derive);
let attr = self.cx.sess.find_by_name(item.attrs(), sym::derive);
let span = attr.map_or(item.span(), |attr| attr.span);
let mut err = self
.cx
@ -566,10 +566,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let invocations = {
let mut collector = InvocationCollector {
cfg: StripUnconfigured {
sess: self.cx.parse_sess,
features: self.cx.ecfg.features,
},
cfg: StripUnconfigured { sess: &self.cx.sess, features: self.cx.ecfg.features },
cx: self.cx,
invocations: Vec::new(),
monotonic: self.monotonic,
@ -589,8 +586,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
let mut cfg =
StripUnconfigured { sess: self.cx.parse_sess, features: self.cx.ecfg.features };
let mut cfg = StripUnconfigured { sess: &self.cx.sess, features: self.cx.ecfg.features };
// Since the item itself has already been configured by the InvocationCollector,
// we know that fold result vector will contain exactly one element
match item {
@ -706,7 +702,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
SyntaxExtensionKind::Attr(expander) => {
self.gate_proc_macro_input(&item);
self.gate_proc_macro_attr_item(span, &item);
let tokens = item.into_tokens(self.cx.parse_sess);
let tokens = item.into_tokens(&self.cx.sess.parse_sess);
let attr_item = attr.unwrap_normal_item();
if let MacArgs::Eq(..) = attr_item.args {
self.cx.span_err(span, "key-value macro attributes are not supported");
@ -719,7 +715,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
}
SyntaxExtensionKind::LegacyAttr(expander) => {
match validate_attr::parse_meta(self.cx.parse_sess, &attr) {
match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) {
Ok(meta) => {
let items = match expander.expand(self.cx, span, &meta, item) {
ExpandResult::Ready(items) => items,
@ -748,9 +744,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
}
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
attr::mark_known(&attr);
self.cx.sess.mark_attr_known(&attr);
if *mark_used {
attr::mark_used(&attr);
self.cx.sess.mark_attr_used(&attr);
}
item.visit_attrs(|attrs| attrs.push(attr));
fragment_kind.expect_from_annotatables(iter::once(item))
@ -808,7 +804,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
return;
}
feature_err(
self.cx.parse_sess,
&self.cx.sess.parse_sess,
sym::proc_macro_hygiene,
span,
&format!("custom attributes cannot be applied to {}", kind),
@ -843,7 +839,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
if !self.cx.ecfg.proc_macro_hygiene() {
annotatable.visit_with(&mut GateProcMacroInput { parse_sess: self.cx.parse_sess });
annotatable
.visit_with(&mut GateProcMacroInput { parse_sess: &self.cx.sess.parse_sess });
}
}
@ -989,7 +986,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
..ExpnData::default(
ExpnKind::Macro(MacroKind::Attr, sym::derive),
item.span(),
self.cx.parse_sess.edition,
self.cx.sess.parse_sess.edition,
None,
)
}),
@ -1049,7 +1046,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
if a.has_name(sym::derive) {
*after_derive = true;
}
!attr::is_known(a) && !is_builtin_attr(a)
!self.cx.sess.is_attr_known(a) && !is_builtin_attr(a)
})
.map(|i| attrs.remove(i));
if let Some(attr) = &attr {
@ -1058,7 +1055,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
&& !attr.has_name(sym::test)
{
feature_err(
&self.cx.parse_sess,
&self.cx.sess.parse_sess,
sym::custom_inner_attributes,
attr.span,
"non-builtin inner attributes are unstable",
@ -1109,8 +1106,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
let features = self.cx.ecfg.features.unwrap();
for attr in attrs.iter() {
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.parse_sess, features);
validate_attr::check_meta(self.cx.parse_sess, attr);
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
validate_attr::check_meta(&self.cx.sess.parse_sess, attr);
// macros are expanded before any lint passes so this warning has to be hardcoded
if attr.has_name(sym::derive) {
@ -1123,7 +1120,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
}
if attr.doc_str().is_some() {
self.cx.parse_sess.buffer_lint_with_diagnostic(
self.cx.sess.parse_sess.buffer_lint_with_diagnostic(
&UNUSED_DOC_COMMENTS,
attr.span,
ast::CRATE_NODE_ID,
@ -1429,7 +1426,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
})
}
ast::ItemKind::Mod(ref mut old_mod @ ast::Mod { .. }) if ident != Ident::invalid() => {
let sess = self.cx.parse_sess;
let sess = &self.cx.sess.parse_sess;
let orig_ownership = self.cx.current_expansion.directory_ownership;
let mut module = (*self.cx.current_expansion.module).clone();
@ -1438,11 +1435,11 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
let Directory { ownership, path } = if old_mod.inline {
// Inline `mod foo { ... }`, but we still need to push directories.
item.attrs = attrs;
push_directory(ident, &item.attrs, dir)
push_directory(&self.cx.sess, ident, &item.attrs, dir)
} else {
// We have an outline `mod foo;` so we need to parse the file.
let (new_mod, dir) =
parse_external_mod(sess, ident, span, dir, &mut attrs, pushed);
parse_external_mod(&self.cx.sess, ident, span, dir, &mut attrs, pushed);
let krate = ast::Crate {
span: new_mod.inner,
@ -1639,7 +1636,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
fn visit_attribute(&mut self, at: &mut ast::Attribute) {
// turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename",
// contents="file contents")]` attributes
if !at.check_name(sym::doc) {
if !self.cx.sess.check_name(at, sym::doc) {
return noop_visit_attribute(at, self);
}
@ -1660,9 +1657,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
}
if let Some(file) = it.value_str() {
let err_count = self.cx.parse_sess.span_diagnostic.err_count();
let err_count = self.cx.sess.parse_sess.span_diagnostic.err_count();
self.check_attributes(slice::from_ref(at));
if self.cx.parse_sess.span_diagnostic.err_count() > err_count {
if self.cx.sess.parse_sess.span_diagnostic.err_count() > err_count {
// avoid loading the file if they haven't enabled the feature
return noop_visit_attribute(at, self);
}

View File

@ -19,6 +19,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_feature::Features;
use rustc_parse::parser::Parser;
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::hygiene::Transparency;
use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent};
@ -217,7 +218,7 @@ fn generic_extension<'cx>(
lhses: &[mbe::TokenTree],
rhses: &[mbe::TokenTree],
) -> Box<dyn MacResult + 'cx> {
let sess = cx.parse_sess;
let sess = &cx.sess.parse_sess;
if cx.trace_macros() {
let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(&arg));
@ -378,7 +379,7 @@ fn generic_extension<'cx>(
/// Converts a macro item into a syntax extension.
pub fn compile_declarative_macro(
sess: &ParseSess,
sess: &Session,
features: &Features,
def: &ast::Item,
edition: Edition,
@ -396,7 +397,7 @@ pub fn compile_declarative_macro(
)
};
let diag = &sess.span_diagnostic;
let diag = &sess.parse_sess.span_diagnostic;
let lhs_nm = Ident::new(sym::lhs, def.span);
let rhs_nm = Ident::new(sym::rhs, def.span);
let tt_spec = Some(NonterminalKind::TT);
@ -444,17 +445,20 @@ pub fn compile_declarative_macro(
),
];
let parser = Parser::new(sess, body, true, rustc_parse::MACRO_ARGUMENTS);
let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
let argument_map = match parse_tt(&mut Cow::Borrowed(&parser), &argument_gram) {
Success(m) => m,
Failure(token, msg) => {
let s = parse_failure_msg(&token);
let sp = token.span.substitute_dummy(def.span);
sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
sess.parse_sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
return mk_syn_ext(Box::new(macro_rules_dummy_expander));
}
Error(sp, msg) => {
sess.span_diagnostic.struct_span_err(sp.substitute_dummy(def.span), &msg).emit();
sess.parse_sess
.span_diagnostic
.struct_span_err(sp.substitute_dummy(def.span), &msg)
.emit();
return mk_syn_ext(Box::new(macro_rules_dummy_expander));
}
ErrorReported => {
@ -471,17 +475,18 @@ pub fn compile_declarative_macro(
.map(|m| {
if let MatchedNonterminal(ref nt) = *m {
if let NtTT(ref tt) = **nt {
let tt = mbe::quoted::parse(tt.clone().into(), true, sess, def.id)
.pop()
.unwrap();
valid &= check_lhs_nt_follows(sess, features, &def.attrs, &tt);
let tt =
mbe::quoted::parse(tt.clone().into(), true, &sess.parse_sess, def.id)
.pop()
.unwrap();
valid &= check_lhs_nt_follows(&sess.parse_sess, features, &def.attrs, &tt);
return tt;
}
}
sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
})
.collect::<Vec<mbe::TokenTree>>(),
_ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
_ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
};
let rhses = match argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] {
@ -490,29 +495,34 @@ pub fn compile_declarative_macro(
.map(|m| {
if let MatchedNonterminal(ref nt) = *m {
if let NtTT(ref tt) = **nt {
return mbe::quoted::parse(tt.clone().into(), false, sess, def.id)
.pop()
.unwrap();
return mbe::quoted::parse(
tt.clone().into(),
false,
&sess.parse_sess,
def.id,
)
.pop()
.unwrap();
}
}
sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
})
.collect::<Vec<mbe::TokenTree>>(),
_ => sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"),
_ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"),
};
for rhs in &rhses {
valid &= check_rhs(sess, rhs);
valid &= check_rhs(&sess.parse_sess, rhs);
}
// don't abort iteration early, so that errors for multiple lhses can be reported
for lhs in &lhses {
valid &= check_lhs_no_empty_seq(sess, slice::from_ref(lhs));
valid &= check_lhs_no_empty_seq(&sess.parse_sess, slice::from_ref(lhs));
}
valid &= macro_check::check_meta_variables(sess, def.id, def.span, &lhses, &rhses);
valid &= macro_check::check_meta_variables(&sess.parse_sess, def.id, def.span, &lhses, &rhses);
let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules);
let (transparency, transparency_error) = attr::find_transparency(sess, &def.attrs, macro_rules);
match transparency_error {
Some(TransparencyError::UnknownTransparency(value, span)) => {
diag.span_err(span, &format!("unknown macro transparency: `{}`", value))

View File

@ -1,8 +1,9 @@
use rustc_ast::ast::{Attribute, Mod};
use rustc_ast::{attr, token};
use rustc_ast::token;
use rustc_errors::{struct_span_err, PResult};
use rustc_parse::new_parser_from_file;
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::source_map::{FileName, Span};
use rustc_span::symbol::{sym, Ident};
@ -39,7 +40,7 @@ pub struct ModulePathSuccess {
}
crate fn parse_external_mod(
sess: &ParseSess,
sess: &Session,
id: Ident,
span: Span, // The span to blame on errors.
Directory { mut ownership, path }: Directory,
@ -53,14 +54,15 @@ crate fn parse_external_mod(
ownership = mp.ownership;
// Ensure file paths are acyclic.
let mut included_mod_stack = sess.included_mod_stack.borrow_mut();
error_on_circular_module(sess, span, &mp.path, &included_mod_stack)?;
let mut included_mod_stack = sess.parse_sess.included_mod_stack.borrow_mut();
error_on_circular_module(&sess.parse_sess, span, &mp.path, &included_mod_stack)?;
included_mod_stack.push(mp.path.clone());
*pop_mod_stack = true; // We have pushed, so notify caller.
drop(included_mod_stack);
// Actually parse the external file as a module.
let mut module = new_parser_from_file(sess, &mp.path, Some(span)).parse_mod(&token::Eof)?;
let mut module =
new_parser_from_file(&sess.parse_sess, &mp.path, Some(span)).parse_mod(&token::Eof)?;
module.0.inline = false;
module
};
@ -98,11 +100,12 @@ fn error_on_circular_module<'a>(
}
crate fn push_directory(
sess: &Session,
id: Ident,
attrs: &[Attribute],
Directory { mut ownership, mut path }: Directory,
) -> Directory {
if let Some(filename) = attr::first_attr_value_str_by_name(attrs, sym::path) {
if let Some(filename) = sess.first_attr_value_str_by_name(attrs, sym::path) {
path.push(&*filename.as_str());
ownership = DirectoryOwnership::Owned { relative: None };
} else {
@ -124,14 +127,14 @@ crate fn push_directory(
}
fn submod_path<'a>(
sess: &'a ParseSess,
sess: &'a Session,
id: Ident,
span: Span,
attrs: &[Attribute],
ownership: DirectoryOwnership,
dir_path: &Path,
) -> PResult<'a, ModulePathSuccess> {
if let Some(path) = submod_path_from_attr(attrs, dir_path) {
if let Some(path) = submod_path_from_attr(sess, attrs, dir_path) {
let ownership = match path.file_name().and_then(|s| s.to_str()) {
// All `#[path]` files are treated as though they are a `mod.rs` file.
// This means that `mod foo;` declarations inside `#[path]`-included
@ -151,16 +154,16 @@ fn submod_path<'a>(
DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None,
};
let ModulePath { path_exists, name, result } =
default_submod_path(sess, id, span, relative, dir_path);
default_submod_path(&sess.parse_sess, id, span, relative, dir_path);
match ownership {
DirectoryOwnership::Owned { .. } => Ok(result?),
DirectoryOwnership::UnownedViaBlock => {
let _ = result.map_err(|mut err| err.cancel());
error_decl_mod_in_block(sess, span, path_exists, &name)
error_decl_mod_in_block(&sess.parse_sess, span, path_exists, &name)
}
DirectoryOwnership::UnownedViaMod => {
let _ = result.map_err(|mut err| err.cancel());
error_cannot_declare_mod_here(sess, span, path_exists, &name)
error_cannot_declare_mod_here(&sess.parse_sess, span, path_exists, &name)
}
}
}
@ -218,9 +221,13 @@ fn error_cannot_declare_mod_here<'a, T>(
/// Derive a submodule path from the first found `#[path = "path_string"]`.
/// The provided `dir_path` is joined with the `path_string`.
// Public for rustfmt usage.
pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
pub fn submod_path_from_attr(
sess: &Session,
attrs: &[Attribute],
dir_path: &Path,
) -> Option<PathBuf> {
// Extract path string from first `#[path = "path_string"]` attribute.
let path_string = attr::first_attr_value_str_by_name(attrs, sym::path)?;
let path_string = sess.first_attr_value_str_by_name(attrs, sym::path)?;
let path_string = path_string.as_str();
// On windows, the base path might have the form

View File

@ -2,9 +2,9 @@ use crate::tests::{matches_codepattern, string_to_crate};
use rustc_ast::ast;
use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::with_default_session_globals;
use rustc_ast_pretty::pprust;
use rustc_span::symbol::Ident;
use rustc_span::with_default_session_globals;
// This version doesn't care about getting comments or doc-strings in.
fn fake_print_crate(s: &mut pprust::State<'_>, krate: &ast::Crate) {

View File

@ -1,12 +1,12 @@
use rustc_ast::ast::AttrStyle;
use rustc_ast::token::{self, CommentKind, Token, TokenKind};
use rustc_ast::with_default_session_globals;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{emitter::EmitterWriter, Handler};
use rustc_parse::lexer::StringReader;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::{FilePathMapping, SourceMap};
use rustc_span::symbol::Symbol;
use rustc_span::with_default_session_globals;
use rustc_span::{BytePos, Span};
use std::io;

View File

@ -5,13 +5,13 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::visit;
use rustc_ast::with_default_session_globals;
use rustc_ast_pretty::pprust::item_to_string;
use rustc_errors::PResult;
use rustc_parse::new_parser_from_source_str;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::with_default_session_globals;
use rustc_span::{BytePos, FileName, Pos, Span};
use std::path::PathBuf;

View File

@ -107,7 +107,7 @@ impl MultiItemModifier for ProcMacroDerive {
let input = if item.pretty_printing_compatibility_hack() {
TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into()
} else {
nt_to_tokenstream(&item, ecx.parse_sess, DUMMY_SP)
nt_to_tokenstream(&item, &ecx.sess.parse_sess, DUMMY_SP)
};
let server = proc_macro_server::Rustc::new(ecx);
@ -123,9 +123,9 @@ impl MultiItemModifier for ProcMacroDerive {
}
};
let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count();
let mut parser =
rustc_parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
rustc_parse::stream_to_parser(&ecx.sess.parse_sess, stream, Some("proc-macro derive"));
let mut items = vec![];
loop {
@ -140,7 +140,7 @@ impl MultiItemModifier for ProcMacroDerive {
}
// fail if there have been errors emitted
if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
if ecx.sess.parse_sess.span_diagnostic.err_count() > error_count_before {
ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit();
}

View File

@ -364,7 +364,7 @@ impl<'a> Rustc<'a> {
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
let expn_data = cx.current_expansion.id.expn_data();
Rustc {
sess: cx.parse_sess,
sess: &cx.sess.parse_sess,
def_site: cx.with_def_site_ctxt(expn_data.def_site),
call_site: cx.with_call_site_ctxt(expn_data.call_site),
mixed_site: cx.with_mixed_site_ctxt(expn_data.call_site),

View File

@ -1,9 +1,9 @@
use rustc_ast::ast;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::with_default_session_globals;
use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream};
use rustc_session::parse::ParseSess;
use rustc_span::source_map::{FilePathMapping, SourceMap};
use rustc_span::with_default_session_globals;
use rustc_span::{BytePos, MultiSpan, Span};
use rustc_data_structures::sync::Lrc;

View File

@ -2,7 +2,7 @@ use crate::tests::string_to_stream;
use rustc_ast::token;
use rustc_ast::tokenstream::{TokenStream, TokenStreamBuilder, TokenTree};
use rustc_ast::with_default_session_globals;
use rustc_span::with_default_session_globals;
use rustc_span::{BytePos, Span, Symbol};
use smallvec::smallvec;

View File

@ -141,12 +141,20 @@ impl<CTX> HashStable<CTX> for LangItem {
/// Extracts the first `lang = "$name"` out of a list of attributes.
/// The attributes `#[panic_handler]` and `#[alloc_error_handler]`
/// are also extracted out when found.
pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
///
/// About the `check_name` argument: passing in a `Session` would be simpler,
/// because then we could call `Session::check_name` directly. But we want to
/// avoid the need for `librustc_hir` to depend on `librustc_session`, so we
/// use a closure instead.
pub fn extract<'a, F>(check_name: F, attrs: &'a [ast::Attribute]) -> Option<(Symbol, Span)>
where
F: Fn(&'a ast::Attribute, Symbol) -> bool,
{
attrs.iter().find_map(|attr| {
Some(match attr {
_ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span),
_ if attr.check_name(sym::panic_handler) => (sym::panic_impl, attr.span),
_ if attr.check_name(sym::alloc_error_handler) => (sym::oom, attr.span),
_ if check_name(attr, sym::lang) => (attr.value_str()?, attr.span),
_ if check_name(attr, sym::panic_handler) => (sym::panic_impl, attr.span),
_ if check_name(attr, sym::alloc_error_handler) => (sym::oom, attr.span),
_ => return None,
})
})

View File

@ -20,8 +20,13 @@ lazy_static! {
};
}
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
lang_items::extract(attrs).and_then(|(name, _)| {
/// The `check_name` argument avoids the need for `librustc_hir` to depend on
/// `librustc_session`.
pub fn link_name<'a, F>(check_name: F, attrs: &'a [ast::Attribute]) -> Option<Symbol>
where
F: Fn(&'a ast::Attribute, Symbol) -> bool
{
lang_items::extract(check_name, attrs).and_then(|(name, _)| {
$(if name == sym::$name {
Some(sym::$sym)
} else)* {

View File

@ -117,7 +117,7 @@ impl IfThisChanged<'tcx> {
let def_id = self.tcx.hir().local_def_id(hir_id);
let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id());
for attr in attrs {
if attr.check_name(sym::rustc_if_this_changed) {
if self.tcx.sess.check_name(attr, sym::rustc_if_this_changed) {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
None => DepNode::from_def_path_hash(def_path_hash, DepKind::hir_owner),
@ -132,7 +132,7 @@ impl IfThisChanged<'tcx> {
},
};
self.if_this_changed.push((attr.span, def_id.to_def_id(), dep_node));
} else if attr.check_name(sym::rustc_then_this_would_need) {
} else if self.tcx.sess.check_name(attr, sym::rustc_then_this_would_need) {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
Some(n) => match DepNode::from_label_string(&n.as_str(), def_path_hash) {

View File

@ -57,26 +57,27 @@ struct AssertModuleSource<'tcx> {
impl AssertModuleSource<'tcx> {
fn check_attr(&self, attr: &ast::Attribute) {
let (expected_reuse, comp_kind) = if attr.check_name(sym::rustc_partition_reused) {
(CguReuse::PreLto, ComparisonKind::AtLeast)
} else if attr.check_name(sym::rustc_partition_codegened) {
(CguReuse::No, ComparisonKind::Exact)
} else if attr.check_name(sym::rustc_expected_cgu_reuse) {
match self.field(attr, sym::kind) {
sym::no => (CguReuse::No, ComparisonKind::Exact),
sym::pre_dash_lto => (CguReuse::PreLto, ComparisonKind::Exact),
sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact),
sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast),
other => {
self.tcx.sess.span_fatal(
attr.span,
&format!("unknown cgu-reuse-kind `{}` specified", other),
);
let (expected_reuse, comp_kind) =
if self.tcx.sess.check_name(attr, sym::rustc_partition_reused) {
(CguReuse::PreLto, ComparisonKind::AtLeast)
} else if self.tcx.sess.check_name(attr, sym::rustc_partition_codegened) {
(CguReuse::No, ComparisonKind::Exact)
} else if self.tcx.sess.check_name(attr, sym::rustc_expected_cgu_reuse) {
match self.field(attr, sym::kind) {
sym::no => (CguReuse::No, ComparisonKind::Exact),
sym::pre_dash_lto => (CguReuse::PreLto, ComparisonKind::Exact),
sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact),
sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast),
other => {
self.tcx.sess.span_fatal(
attr.span,
&format!("unknown cgu-reuse-kind `{}` specified", other),
);
}
}
}
} else {
return;
};
} else {
return;
};
if !self.tcx.sess.opts.debugging_opts.query_dep_graph {
self.tcx.sess.span_fatal(

View File

@ -180,9 +180,9 @@ pub struct DirtyCleanVisitor<'tcx> {
impl DirtyCleanVisitor<'tcx> {
/// Possibly "deserialize" the attribute into a clean/dirty assertion
fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute) -> Option<Assertion> {
let is_clean = if attr.check_name(sym::rustc_dirty) {
let is_clean = if self.tcx.sess.check_name(attr, sym::rustc_dirty) {
false
} else if attr.check_name(sym::rustc_clean) {
} else if self.tcx.sess.check_name(attr, sym::rustc_clean) {
true
} else {
// skip: not rustc_clean/dirty
@ -523,7 +523,7 @@ pub struct FindAllAttrs<'tcx> {
impl FindAllAttrs<'tcx> {
fn is_active_attr(&mut self, attr: &Attribute) -> bool {
for attr_name in &self.attr_names {
if attr.check_name(*attr_name) && check_config(self.tcx, attr) {
if self.tcx.sess.check_name(attr, *attr_name) && check_config(self.tcx, attr) {
return true;
}
}

View File

@ -73,7 +73,7 @@ impl Compiler {
/// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
rustc_ast::with_default_session_globals(move || {
rustc_span::with_default_session_globals(move || {
let cfg = cfgspecs
.into_iter()
.map(|s| {

View File

@ -162,12 +162,7 @@ pub fn register_plugins<'a>(
)
});
let (krate, features) = rustc_expand::config::features(
krate,
&sess.parse_sess,
sess.edition(),
&sess.opts.debugging_opts.allow_features,
);
let (krate, features) = rustc_expand::config::features(sess, krate);
// these need to be set "early" so that expansion sees `quote` if enabled.
sess.init_features(features);
@ -244,7 +239,7 @@ fn configure_and_expand_inner<'a>(
let (krate, name) = rustc_builtin_macros::standard_library_imports::inject(
krate,
&mut resolver,
&sess.parse_sess,
&sess,
alt_std_name,
);
if let Some(name) = name {
@ -253,7 +248,7 @@ fn configure_and_expand_inner<'a>(
krate
});
util::check_attr_crate_type(&krate.attrs, &mut resolver.lint_buffer());
util::check_attr_crate_type(&sess, &krate.attrs, &mut resolver.lint_buffer());
// Expand all macros
krate = sess.time("macro_expand_crate", || {
@ -300,7 +295,7 @@ fn configure_and_expand_inner<'a>(
};
let extern_mod_loaded = |k: &ast::Crate| pre_expansion_lint(sess, lint_store, k);
let mut ecx = ExtCtxt::new(&sess.parse_sess, cfg, &mut resolver, Some(&extern_mod_loaded));
let mut ecx = ExtCtxt::new(&sess, cfg, &mut resolver, Some(&extern_mod_loaded));
// Expand macros now!
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
@ -312,6 +307,7 @@ fn configure_and_expand_inner<'a>(
});
let mut missing_fragment_specifiers: Vec<_> = ecx
.sess
.parse_sess
.missing_fragment_specifiers
.borrow()
@ -341,17 +337,7 @@ fn configure_and_expand_inner<'a>(
})?;
sess.time("maybe_building_test_harness", || {
rustc_builtin_macros::test_harness::inject(
&sess.parse_sess,
&mut resolver,
sess.opts.test,
&mut krate,
sess.diagnostic(),
&sess.features_untracked(),
sess.panic_strategy(),
sess.target.target.options.panic_strategy,
sess.opts.debugging_opts.panic_abort_tests,
)
rustc_builtin_macros::test_harness::inject(&sess, &mut resolver, &mut krate)
});
if let Some(PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops)) = sess.opts.pretty {
@ -385,7 +371,7 @@ fn configure_and_expand_inner<'a>(
let num_crate_types = crate_types.len();
let is_test_crate = sess.opts.test;
rustc_builtin_macros::proc_macro_harness::inject(
&sess.parse_sess,
&sess,
&mut resolver,
krate,
is_proc_macro_crate,
@ -415,12 +401,7 @@ fn configure_and_expand_inner<'a>(
// Needs to go *after* expansion to be able to check the results of macro expansion.
sess.time("complete_gated_feature_checking", || {
rustc_ast_passes::feature_gate::check_crate(
&krate,
&sess.parse_sess,
&sess.features_untracked(),
sess.opts.unstable_features,
);
rustc_ast_passes::feature_gate::check_crate(&krate, sess);
});
// Add all buffered lints from the `ParseSess` to the `Session`.

View File

@ -1,4 +1,3 @@
use rustc_ast::attr;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
@ -13,19 +12,20 @@ pub fn find(tcx: TyCtxt<'_>) -> Option<DefId> {
fn proc_macro_decls_static(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
assert_eq!(cnum, LOCAL_CRATE);
let mut finder = Finder { decls: None };
let mut finder = Finder { tcx, decls: None };
tcx.hir().krate().visit_all_item_likes(&mut finder);
finder.decls.map(|id| tcx.hir().local_def_id(id).to_def_id())
}
struct Finder {
struct Finder<'tcx> {
tcx: TyCtxt<'tcx>,
decls: Option<hir::HirId>,
}
impl<'v> ItemLikeVisitor<'v> for Finder {
impl<'v> ItemLikeVisitor<'v> for Finder<'_> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
if attr::contains_name(&item.attrs, sym::rustc_proc_macro_decls) {
if self.tcx.sess.contains_name(&item.attrs, sym::rustc_proc_macro_decls) {
self.decls = Some(item.hir_id);
}
}

View File

@ -159,7 +159,7 @@ impl<'tcx> Queries<'tcx> {
None => {
let parse_result = self.parse()?;
let krate = parse_result.peek();
find_crate_name(Some(self.session()), &krate.attrs, &self.compiler.input)
find_crate_name(self.session(), &krate.attrs, &self.compiler.input)
}
})
})
@ -294,7 +294,7 @@ impl<'tcx> Queries<'tcx> {
};
let attrs = &*tcx.get_attrs(def_id.to_def_id());
let attrs = attrs.iter().filter(|attr| attr.check_name(sym::rustc_error));
let attrs = attrs.iter().filter(|attr| tcx.sess.check_name(attr, sym::rustc_error));
for attr in attrs {
match attr.meta_item_list() {
// Check if there is a `#[rustc_error(delay_span_bug_from_inside_query)]`.

View File

@ -73,7 +73,7 @@ fn mk_map<K: Ord, V>(entries: Vec<(K, V)>) -> BTreeMap<K, V> {
// When the user supplies --test we should implicitly supply --cfg test
#[test]
fn test_switch_implies_cfg_test() {
rustc_ast::with_default_session_globals(|| {
rustc_span::with_default_session_globals(|| {
let matches = optgroups().parse(&["--test".to_string()]).unwrap();
let (sess, cfg) = mk_session(matches);
let cfg = build_configuration(&sess, to_crate_config(cfg));
@ -84,7 +84,7 @@ fn test_switch_implies_cfg_test() {
// When the user supplies --test and --cfg test, don't implicitly add another --cfg test
#[test]
fn test_switch_implies_cfg_test_unless_cfg_test() {
rustc_ast::with_default_session_globals(|| {
rustc_span::with_default_session_globals(|| {
let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
let (sess, cfg) = mk_session(matches);
let cfg = build_configuration(&sess, to_crate_config(cfg));
@ -96,20 +96,20 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
#[test]
fn test_can_print_warnings() {
rustc_ast::with_default_session_globals(|| {
rustc_span::with_default_session_globals(|| {
let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
let (sess, _) = mk_session(matches);
assert!(!sess.diagnostic().can_emit_warnings());
});
rustc_ast::with_default_session_globals(|| {
rustc_span::with_default_session_globals(|| {
let matches =
optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
let (sess, _) = mk_session(matches);
assert!(sess.diagnostic().can_emit_warnings());
});
rustc_ast::with_default_session_globals(|| {
rustc_span::with_default_session_globals(|| {
let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
let (sess, _) = mk_session(matches);
assert!(sess.diagnostic().can_emit_warnings());

View File

@ -142,7 +142,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
crate::callbacks::setup_callbacks();
let main_handler = move || {
rustc_ast::with_session_globals(edition, || {
rustc_span::with_session_globals(edition, || {
if let Some(stderr) = stderr {
io::set_panic(Some(box Sink(stderr.clone())));
}
@ -176,27 +176,21 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
let with_pool = move |pool: &rayon::ThreadPool| pool.install(move || f());
rustc_ast::with_session_globals(edition, || {
rustc_ast::SESSION_GLOBALS.with(|ast_session_globals| {
rustc_span::SESSION_GLOBALS.with(|span_session_globals| {
// The main handler runs for each Rayon worker thread and sets
// up the thread local rustc uses. ast_session_globals and
// span_session_globals are captured and set on the new
// threads. ty::tls::with_thread_locals sets up thread local
// callbacks from librustc_ast.
let main_handler = move |thread: rayon::ThreadBuilder| {
rustc_ast::SESSION_GLOBALS.set(ast_session_globals, || {
rustc_span::SESSION_GLOBALS.set(span_session_globals, || {
if let Some(stderr) = stderr {
io::set_panic(Some(box Sink(stderr.clone())));
}
thread.run()
})
})
};
rustc_span::with_session_globals(edition, || {
rustc_span::SESSION_GLOBALS.with(|session_globals| {
// The main handler runs for each Rayon worker thread and sets up
// the thread local rustc uses. `session_globals` is captured and set
// on the new threads.
let main_handler = move |thread: rayon::ThreadBuilder| {
rustc_span::SESSION_GLOBALS.set(session_globals, || {
if let Some(stderr) = stderr {
io::set_panic(Some(box Sink(stderr.clone())));
}
thread.run()
})
};
config.build_scoped(main_handler, with_pool).unwrap()
})
config.build_scoped(main_handler, with_pool).unwrap()
})
})
}
@ -407,10 +401,14 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat
CrateDisambiguator::from(hasher.finish::<Fingerprint>())
}
pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut LintBuffer) {
pub(crate) fn check_attr_crate_type(
sess: &Session,
attrs: &[ast::Attribute],
lint_buffer: &mut LintBuffer,
) {
// Unconditionally collect crate types from attributes to make them used
for a in attrs.iter() {
if a.check_name(sym::crate_type) {
if sess.check_name(a, sym::crate_type) {
if let Some(n) = a.value_str() {
if categorize_crate_type(n).is_some() {
return;
@ -465,7 +463,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
let attr_types: Vec<CrateType> = attrs
.iter()
.filter_map(|a| {
if a.check_name(sym::crate_type) {
if session.check_name(a, sym::crate_type) {
match a.value_str() {
Some(s) => categorize_crate_type(s),
_ => None,
@ -531,7 +529,7 @@ pub fn build_output_filenames(
.opts
.crate_name
.clone()
.or_else(|| rustc_attr::find_crate_name(attrs).map(|n| n.to_string()))
.or_else(|| rustc_attr::find_crate_name(&sess, attrs).map(|n| n.to_string()))
.unwrap_or_else(|| input.filestem().to_owned());
OutputFilenames::new(

View File

@ -41,6 +41,7 @@ use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::lint::FutureIncompatibleInfo;
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -237,7 +238,7 @@ impl UnsafeCode {
impl EarlyLintPass for UnsafeCode {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
if attr.check_name(sym::allow_internal_unsafe) {
if cx.sess().check_name(attr, sym::allow_internal_unsafe) {
self.report_unsafe(cx, attr.span, |lint| {
lint.build(
"`allow_internal_unsafe` allows defining \
@ -315,12 +316,12 @@ pub struct MissingDoc {
impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
fn has_doc(attr: &ast::Attribute) -> bool {
fn has_doc(sess: &Session, attr: &ast::Attribute) -> bool {
if attr.is_doc_comment() {
return true;
}
if !attr.check_name(sym::doc) {
if !sess.check_name(attr, sym::doc) {
return false;
}
@ -377,7 +378,7 @@ impl MissingDoc {
}
}
let has_doc = attrs.iter().any(|a| has_doc(a));
let has_doc = attrs.iter().any(|a| has_doc(cx.sess(), a));
if !has_doc {
cx.struct_span_lint(
MISSING_DOCS,
@ -391,10 +392,10 @@ impl MissingDoc {
}
impl<'tcx> LateLintPass<'tcx> for MissingDoc {
fn enter_lint_attrs(&mut self, _: &LateContext<'_>, attrs: &[ast::Attribute]) {
fn enter_lint_attrs(&mut self, cx: &LateContext<'_>, attrs: &[ast::Attribute]) {
let doc_hidden = self.doc_hidden()
|| attrs.iter().any(|attr| {
attr.check_name(sym::doc)
cx.sess().check_name(attr, sym::doc)
&& match attr.meta_item_list() {
None => false,
Some(l) => attr::list_contains_name(&l, sym::hidden),
@ -411,7 +412,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
self.check_missing_docs_attrs(cx, None, &krate.item.attrs, krate.item.span, "the", "crate");
for macro_def in krate.exported_macros {
let has_doc = macro_def.attrs.iter().any(|a| has_doc(a));
let has_doc = macro_def.attrs.iter().any(|a| has_doc(cx.sess(), a));
if !has_doc {
cx.struct_span_lint(
MISSING_DOCS,
@ -737,7 +738,7 @@ impl EarlyLintPass for DeprecatedAttr {
return;
}
}
if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) {
if cx.sess().check_name(attr, sym::no_start) || cx.sess().check_name(attr, sym::crate_id) {
let path_str = pprust::path_to_string(&attr.get_normal_item().path);
let msg = format!("use of deprecated attribute `{}`: no longer used.", path_str);
lint_deprecated_attr(cx, attr, &msg, None);
@ -763,7 +764,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
let span = sugared_span.take().unwrap_or_else(|| attr.span);
if attr.is_doc_comment() || attr.check_name(sym::doc) {
if attr.is_doc_comment() || cx.sess().check_name(attr, sym::doc) {
cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| {
let mut err = lint.build("unused doc comment");
err.span_label(
@ -819,7 +820,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
match it.kind {
hir::ItemKind::Fn(.., ref generics, _) => {
if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
if let Some(no_mangle_attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
for param in generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
@ -845,7 +846,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
}
}
hir::ItemKind::Const(..) => {
if attr::contains_name(&it.attrs, sym::no_mangle) {
if cx.sess().contains_name(&it.attrs, sym::no_mangle) {
// Const items do not refer to a particular location in memory, and therefore
// don't have anything to attach a symbol to
cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, |lint| {
@ -938,11 +939,11 @@ declare_lint_pass!(
);
impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
fn check_attribute(&mut self, ctx: &LateContext<'_>, attr: &ast::Attribute) {
if attr.check_name(sym::feature) {
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
if cx.sess().check_name(attr, sym::feature) {
if let Some(items) = attr.meta_item_list() {
for item in items {
ctx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| {
cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| {
lint.build("unstable feature").emit()
});
}
@ -1381,7 +1382,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
return;
}
if let Some(attr) = attr::find_by_name(&it.attrs, sym::rustc_test_marker) {
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::rustc_test_marker) {
cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| {
lint.build("cannot test inner items").emit()
});
@ -2131,7 +2132,7 @@ impl ClashingExternDeclarations {
overridden_link_name,
tcx.get_attrs(did.to_def_id())
.iter()
.find(|at| at.check_name(sym::link_name))
.find(|at| tcx.sess.check_name(at, sym::link_name))
.unwrap()
.span,
)

View File

@ -125,7 +125,7 @@ impl<'s> LintLevelsBuilder<'s> {
};
let meta = unwrap_or!(attr.meta(), continue);
attr::mark_used(attr);
self.sess.mark_attr_used(attr);
let mut metas = unwrap_or!(meta.meta_item_list(), continue);

View File

@ -127,7 +127,7 @@ impl EarlyLintPass for NonCamelCaseTypes {
let has_repr_c = it
.attrs
.iter()
.any(|attr| attr::find_repr_attrs(&cx.sess.parse_sess, attr).contains(&attr::ReprC));
.any(|attr| attr::find_repr_attrs(&cx.sess, attr).contains(&attr::ReprC));
if has_repr_c {
return;
@ -263,7 +263,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
Some(Ident::from_str(name))
} else {
attr::find_by_name(&cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name)
cx.sess()
.find_by_name(&cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name)
.and_then(|attr| attr.meta())
.and_then(|meta| {
meta.name_value_literal().and_then(|lit| {
@ -327,7 +328,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
},
FnKind::ItemFn(ident, _, header, _, attrs) => {
// Skip foreign-ABI #[no_mangle] functions (Issue #31924)
if header.abi != Abi::Rust && attr::contains_name(attrs, sym::no_mangle) {
if header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle) {
return;
}
self.check_snake_case(cx, "function", ident);
@ -407,7 +408,7 @@ impl NonUpperCaseGlobals {
impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
match it.kind {
hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, sym::no_mangle) => {
hir::ItemKind::Static(..) if !cx.sess().contains_name(&it.attrs, sym::no_mangle) => {
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
}
hir::ItemKind::Const(..) => {

View File

@ -538,7 +538,7 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
let guaranteed_nonnull_optimization = tcx
.get_attrs(def.did)
.iter()
.any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed));
.any(|a| tcx.sess.check_name(a, sym::rustc_nonnull_optimization_guaranteed));
if guaranteed_nonnull_optimization {
return true;
@ -556,6 +556,7 @@ fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKi
_ => false,
}
}
/// Given a non-null scalar (or transparent) type `ty`, return the nullable version of that type.
/// If the type passed in was not scalar, returns None.
fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {

View File

@ -2,7 +2,6 @@ use crate::Lint;
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc_ast::ast;
use rustc_ast::ast::{ExprKind, StmtKind};
use rustc_ast::attr;
use rustc_ast::util::parser;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
@ -242,7 +241,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
descr_post_path: &str,
) -> bool {
for attr in cx.tcx.get_attrs(def_id).iter() {
if attr.check_name(sym::must_use) {
if cx.sess().check_name(attr, sym::must_use) {
cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
let msg = format!(
"unused {}`{}`{} that must be used",
@ -331,7 +330,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAttributes {
}
}
if !attr::is_used(attr) {
if !cx.sess().is_attr_used(attr) {
debug!("emitting warning for: {:?}", attr);
cx.struct_span_lint(UNUSED_ATTRIBUTES, attr.span, |lint| {
lint.build("unused attribute").emit()

View File

@ -4,8 +4,8 @@ use crate::dynamic_lib::DynamicLibrary;
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind};
use rustc_ast::{ast, attr};
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::{ast, visit};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
@ -636,7 +636,8 @@ impl<'a> CrateLoader<'a> {
// compilation mode also comes into play.
let desired_strategy = self.sess.panic_strategy();
let mut runtime_found = false;
let mut needs_panic_runtime = attr::contains_name(&krate.attrs, sym::needs_panic_runtime);
let mut needs_panic_runtime =
self.sess.contains_name(&krate.attrs, sym::needs_panic_runtime);
self.cstore.iter_crate_data(|cnum, data| {
needs_panic_runtime = needs_panic_runtime || data.needs_panic_runtime();
@ -716,7 +717,7 @@ impl<'a> CrateLoader<'a> {
}
fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
self.cstore.has_global_allocator = match &*global_allocator_spans(krate) {
self.cstore.has_global_allocator = match &*global_allocator_spans(&self.sess, krate) {
[span1, span2, ..] => {
self.sess
.struct_span_err(*span2, "cannot define multiple global allocators")
@ -731,7 +732,7 @@ impl<'a> CrateLoader<'a> {
// Check to see if we actually need an allocator. This desire comes
// about through the `#![needs_allocator]` attribute and is typically
// written down in liballoc.
let mut needs_allocator = attr::contains_name(&krate.attrs, sym::needs_allocator);
let mut needs_allocator = self.sess.contains_name(&krate.attrs, sym::needs_allocator);
self.cstore.iter_crate_data(|_, data| {
needs_allocator = needs_allocator || data.needs_allocator();
});
@ -785,7 +786,7 @@ impl<'a> CrateLoader<'a> {
// allocator. At this point our allocator request is typically fulfilled
// by the standard library, denoted by the `#![default_lib_allocator]`
// attribute.
let mut has_default = attr::contains_name(&krate.attrs, sym::default_lib_allocator);
let mut has_default = self.sess.contains_name(&krate.attrs, sym::default_lib_allocator);
self.cstore.iter_crate_data(|_, data| {
if data.has_default_lib_allocator() {
has_default = true;
@ -895,12 +896,12 @@ impl<'a> CrateLoader<'a> {
);
let name = match orig_name {
Some(orig_name) => {
validate_crate_name(Some(self.sess), &orig_name.as_str(), Some(item.span));
validate_crate_name(self.sess, &orig_name.as_str(), Some(item.span));
orig_name
}
None => item.ident.name,
};
let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
let dep_kind = if self.sess.contains_name(&item.attrs, sym::no_link) {
CrateDepKind::MacrosOnly
} else {
CrateDepKind::Explicit
@ -945,3 +946,26 @@ impl<'a> CrateLoader<'a> {
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
}
}
fn global_allocator_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> {
struct Finder<'a> {
sess: &'a Session,
name: Symbol,
spans: Vec<Span>,
}
impl<'ast, 'a> visit::Visitor<'ast> for Finder<'a> {
fn visit_item(&mut self, item: &'ast ast::Item) {
if item.ident.name == self.name
&& self.sess.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 { sess, name, spans: Vec::new() };
visit::walk_crate(&mut f, krate);
f.spans
}

View File

@ -5,7 +5,7 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_target::spec::abi::Abi;
crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
let mut collector = Collector { args: Vec::new() };
let mut collector = Collector { tcx, args: Vec::new() };
tcx.hir().krate().visit_all_item_likes(&mut collector);
for attr in tcx.hir().krate().item.attrs.iter() {
@ -19,11 +19,12 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
collector.args
}
struct Collector {
struct Collector<'tcx> {
tcx: TyCtxt<'tcx>,
args: Vec<String>,
}
impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
let fm = match it.kind {
hir::ItemKind::ForeignMod(ref fm) => fm,
@ -34,7 +35,8 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
}
// First, add all of the custom #[link_args] attributes
for m in it.attrs.iter().filter(|a| a.check_name(sym::link_args)) {
let sess = &self.tcx.sess;
for m in it.attrs.iter().filter(|a| sess.check_name(a, sym::link_args)) {
if let Some(linkarg) = m.value_str() {
self.add_link_args(linkarg);
}
@ -45,7 +47,7 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {}
}
impl Collector {
impl<'tcx> Collector<'tcx> {
fn add_link_args(&mut self, args: Symbol) {
self.args.extend(args.as_str().split(' ').filter(|s| !s.is_empty()).map(|s| s.to_string()))
}

View File

@ -43,7 +43,8 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
}
// Process all of the #[link(..)]-style arguments
for m in it.attrs.iter().filter(|a| a.check_name(sym::link)) {
let sess = &self.tcx.sess;
for m in it.attrs.iter().filter(|a| sess.check_name(a, sym::link)) {
let items = match m.meta_item_list() {
Some(item) => item,
None => continue,
@ -71,16 +72,10 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
"framework" => NativeLibKind::Framework,
"raw-dylib" => NativeLibKind::RawDylib,
k => {
struct_span_err!(
self.tcx.sess,
item.span(),
E0458,
"unknown kind: `{}`",
k
)
.span_label(item.span(), "unknown kind")
.span_label(m.span, "")
.emit();
struct_span_err!(sess, item.span(), E0458, "unknown kind: `{}`", k)
.span_label(item.span(), "unknown kind")
.span_label(m.span, "")
.emit();
NativeLibKind::Unspecified
}
};
@ -92,18 +87,18 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
None => continue, // skip like historical compilers
};
if cfg.is_empty() {
self.tcx.sess.span_err(item.span(), "`cfg()` must have an argument");
sess.span_err(item.span(), "`cfg()` must have an argument");
} else if let cfg @ Some(..) = cfg[0].meta_item() {
lib.cfg = cfg.cloned();
} else {
self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
}
} else if item.has_name(sym::wasm_import_module) {
match item.value_str() {
Some(s) => lib.wasm_import_module = Some(s),
None => {
let msg = "must be of the form `#[link(wasm_import_module = \"...\")]`";
self.tcx.sess.span_err(item.span(), msg);
sess.span_err(item.span(), msg);
}
}
} else {
@ -117,7 +112,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
let requires_name = kind_specified || lib.wasm_import_module.is_none();
if lib.name.is_none() && requires_name {
struct_span_err!(
self.tcx.sess,
sess,
m.span,
E0459,
"`#[link(...)]` specified without \

View File

@ -742,7 +742,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
};
SyntaxExtension::new(
&sess.parse_sess,
sess,
kind,
self.get_span(id, sess),
helper_attrs,
@ -1102,7 +1102,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
// for other constructors correct visibilities
// were already encoded in metadata.
let attrs = self.get_item_attrs(def_id.index, sess);
if attr::contains_name(&attrs, sym::non_exhaustive) {
if sess.contains_name(&attrs, sym::non_exhaustive) {
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
vis = ty::Visibility::Restricted(crate_def_id);
}

View File

@ -5,7 +5,6 @@ use crate::native_libs;
use crate::rmeta::{self, encoder};
use rustc_ast::ast;
use rustc_ast::attr;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::svh::Svh;
use rustc_hir as hir;
@ -415,7 +414,7 @@ impl CStore {
// Mark the attrs as used
let attrs = data.get_item_attrs(id.index, sess);
for attr in attrs.iter() {
attr::mark_used(attr);
sess.mark_attr_used(attr);
}
let ident = data.item_ident(id.index, sess);

View File

@ -3,7 +3,6 @@ use crate::rmeta::*;
use log::{debug, trace};
use rustc_ast::ast;
use rustc_ast::attr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::StableHasher;
@ -633,7 +632,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let source_map_bytes = self.position() - i;
let attrs = tcx.hir().krate_attrs();
let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator);
let root = self.lazy(CrateRoot {
name: tcx.crate_name(LOCAL_CRATE),
@ -659,12 +658,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} else {
None
},
compiler_builtins: attr::contains_name(&attrs, sym::compiler_builtins),
needs_allocator: attr::contains_name(&attrs, sym::needs_allocator),
needs_panic_runtime: attr::contains_name(&attrs, sym::needs_panic_runtime),
no_builtins: attr::contains_name(&attrs, sym::no_builtins),
panic_runtime: attr::contains_name(&attrs, sym::panic_runtime),
profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime),
compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
symbol_mangling_version: tcx.sess.opts.debugging_opts.symbol_mangling_version,
crate_deps,

View File

@ -27,7 +27,7 @@ fn update_limit(
default: usize,
) {
for attr in &krate.attrs {
if !attr.check_name(name) {
if !sess.check_name(attr, name) {
continue;
}

View File

@ -1040,7 +1040,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
let attrs = self.get_attrs(def_id);
let get = |name| {
let attr = match attrs.iter().find(|a| a.check_name(name)) {
let attr = match attrs.iter().find(|a| self.sess.check_name(a, name)) {
Some(attr) => attr,
None => return Bound::Unbounded,
};
@ -2738,11 +2738,11 @@ pub fn provide(providers: &mut ty::query::Providers) {
};
providers.is_panic_runtime = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::panic_runtime)
};
providers.is_compiler_builtins = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
tcx.sess.contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
};
providers.has_panic_handler = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);

View File

@ -2265,7 +2265,7 @@ impl ReprOptions {
let mut max_align: Option<Align> = None;
let mut min_pack: Option<Align> = None;
for attr in tcx.get_attrs(did).iter() {
for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
for r in attr::find_repr_attrs(&tcx.sess, attr) {
flags.insert(match r {
attr::ReprC => ReprFlags::IS_C,
attr::ReprPacked(pack) => {
@ -2382,7 +2382,7 @@ impl<'tcx> AdtDef {
}
let attrs = tcx.get_attrs(did);
if attr::contains_name(&attrs, sym::fundamental) {
if tcx.sess.contains_name(&attrs, sym::fundamental) {
flags |= AdtFlags::IS_FUNDAMENTAL;
}
if Some(did) == tcx.lang_items().phantom_data() {
@ -3021,7 +3021,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Determines whether an item is annotated with an attribute.
pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
attr::contains_name(&self.get_attrs(did), attr)
self.sess.contains_name(&self.get_attrs(did), attr)
}
/// Returns `true` if this is an `auto trait`.

View File

@ -15,16 +15,12 @@ pub unsafe fn handle_deadlock() {
rustc_data_structures::sync::assert_sync::<tls::ImplicitCtxt<'_, '_>>();
let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>);
let span_session_globals = rustc_span::SESSION_GLOBALS.with(|ssg| ssg as *const _);
let span_session_globals = &*span_session_globals;
let ast_session_globals = rustc_ast::attr::SESSION_GLOBALS.with(|asg| asg as *const _);
let ast_session_globals = &*ast_session_globals;
let session_globals = rustc_span::SESSION_GLOBALS.with(|sg| sg as *const _);
let session_globals = &*session_globals;
thread::spawn(move || {
tls::enter_context(icx, |_| {
rustc_ast::attr::SESSION_GLOBALS.set(ast_session_globals, || {
rustc_span::SESSION_GLOBALS
.set(span_session_globals, || tls::with(|tcx| deadlock(tcx, &registry)))
});
rustc_span::SESSION_GLOBALS
.set(session_globals, || tls::with(|tcx| deadlock(tcx, &registry)))
})
});
}

View File

@ -335,7 +335,7 @@ impl RustcMirAttrs {
let rustc_mir_attrs = attrs
.iter()
.filter(|attr| attr.check_name(sym::rustc_mir))
.filter(|attr| tcx.sess.check_name(attr, sym::rustc_mir))
.flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter()));
for attr in rustc_mir_attrs {

View File

@ -1,5 +1,6 @@
use rustc_ast::ast::{self, MetaItem};
use rustc_middle::ty;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
pub(crate) use self::drop_flag_effects::*;
@ -28,9 +29,13 @@ pub struct MoveDataParamEnv<'tcx> {
pub(crate) param_env: ty::ParamEnv<'tcx>,
}
pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option<MetaItem> {
pub(crate) fn has_rustc_mir_with(
sess: &Session,
attrs: &[ast::Attribute],
name: Symbol,
) -> Option<MetaItem> {
for attr in attrs {
if attr.check_name(sym::rustc_mir) {
if sess.check_name(attr, sym::rustc_mir) {
let items = attr.meta_item_list();
for item in items.iter().flat_map(|l| l.iter()) {
match item.meta_item() {

View File

@ -170,7 +170,11 @@ fn emit_unused_generic_params_error<'tcx>(
) {
debug!("emit_unused_generic_params_error: def_id={:?}", def_id);
let base_def_id = tcx.closure_base_def_id(def_id);
if !tcx.get_attrs(base_def_id).iter().any(|a| a.check_name(sym::rustc_polymorphize_error)) {
if !tcx
.get_attrs(base_def_id)
.iter()
.any(|a| tcx.sess.check_name(a, sym::rustc_polymorphize_error))
{
return;
}

View File

@ -130,7 +130,7 @@ impl Candidate {
fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Vec<usize>> {
let attrs = tcx.get_attrs(def_id);
let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
let attr = attrs.iter().find(|a| tcx.sess.check_name(a, sym::rustc_args_required_const))?;
let mut ret = vec![];
for meta in attr.meta_item_list()? {
match meta.literal()?.kind {

View File

@ -342,7 +342,7 @@ fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bo
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
// opt-in via `allow_internal_unstable`.
attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
attr::allow_internal_unstable(&tcx.sess, &tcx.get_attrs(def_id))
.map_or(false, |mut features| features.any(|name| name == feature_gate))
}
@ -362,7 +362,7 @@ pub fn lib_feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbo
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
// opt-in via `allow_internal_unstable`.
attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
attr::allow_internal_unstable(&tcx.sess, &tcx.get_attrs(def_id))
.map_or(false, |mut features| features.any(|name| name == feature_gate))
}

View File

@ -35,8 +35,9 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
let param_env = tcx.param_env(def_id);
let move_data = MoveData::gather_moves(body, tcx, param_env).unwrap();
let mdpe = MoveDataParamEnv { move_data, param_env };
let sess = &tcx.sess;
if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() {
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_maybe_init).is_some() {
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
@ -44,7 +45,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_inits);
}
if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() {
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_maybe_uninit).is_some() {
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &mdpe)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
@ -52,7 +53,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_uninits);
}
if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_definite_init).is_some() {
let flow_def_inits = DefinitelyInitializedPlaces::new(tcx, body, &mdpe)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
@ -60,7 +61,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits);
}
if has_rustc_mir_with(&attributes, sym::rustc_peek_indirectly_mutable).is_some() {
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_indirectly_mutable).is_some() {
let flow_mut_borrowed = MaybeMutBorrowedLocals::mut_borrows_only(tcx, body, param_env)
.into_engine(tcx, body, def_id)
.iterate_to_fixpoint();
@ -68,14 +69,14 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_mut_borrowed);
}
if has_rustc_mir_with(&attributes, sym::rustc_peek_liveness).is_some() {
if has_rustc_mir_with(sess, &attributes, sym::rustc_peek_liveness).is_some() {
let flow_liveness =
MaybeLiveLocals.into_engine(tcx, body, def_id).iterate_to_fixpoint();
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_liveness);
}
if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
if has_rustc_mir_with(sess, &attributes, sym::stop_after_dataflow).is_some() {
tcx.sess.fatal("stop_after_dataflow ended compilation");
}
}

View File

@ -537,7 +537,7 @@ macro_rules! unpack {
fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, _abi: Abi) -> bool {
// Validate `#[unwind]` syntax regardless of platform-specific panic strategy.
let attrs = &tcx.get_attrs(fn_def_id.to_def_id());
let unwind_attr = attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs);
let unwind_attr = attr::find_unwind_attr(&tcx.sess, attrs);
// We never unwind, so it's not relevant to stop an unwind.
if tcx.sess.panic_strategy() != PanicStrategy::Unwind {

View File

@ -6,7 +6,6 @@ use crate::thir::util::UserAnnotatedTyHelpers;
use crate::thir::*;
use rustc_ast::ast;
use rustc_ast::attr;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::Node;
@ -69,7 +68,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
// Some functions always have overflow checks enabled,
// however, they may not get codegen'd, depending on
// the settings for the crate they are codegened in.
let mut check_overflow = attr::contains_name(attrs, sym::rustc_inherit_overflow_checks);
let mut check_overflow = tcx.sess.contains_name(attrs, sym::rustc_inherit_overflow_checks);
// Respect -C overflow-checks.
check_overflow |= tcx.sess.overflow_checks();

View File

@ -9,7 +9,6 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_ast::ast::{Attribute, NestedMetaItem};
use rustc_ast::attr;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
@ -60,17 +59,17 @@ impl CheckAttrVisitor<'tcx> {
) {
let mut is_valid = true;
for attr in attrs {
is_valid &= if attr.check_name(sym::inline) {
is_valid &= if self.tcx.sess.check_name(attr, sym::inline) {
self.check_inline(hir_id, attr, span, target)
} else if attr.check_name(sym::non_exhaustive) {
} else if self.tcx.sess.check_name(attr, sym::non_exhaustive) {
self.check_non_exhaustive(attr, span, target)
} else if attr.check_name(sym::marker) {
} else if self.tcx.sess.check_name(attr, sym::marker) {
self.check_marker(attr, span, target)
} else if attr.check_name(sym::target_feature) {
} else if self.tcx.sess.check_name(attr, sym::target_feature) {
self.check_target_feature(attr, span, target)
} else if attr.check_name(sym::track_caller) {
} else if self.tcx.sess.check_name(attr, sym::track_caller) {
self.check_track_caller(&attr.span, attrs, span, target)
} else if attr.check_name(sym::doc) {
} else if self.tcx.sess.check_name(attr, sym::doc) {
self.check_doc_alias(attr)
} else {
true
@ -144,7 +143,7 @@ impl CheckAttrVisitor<'tcx> {
target: Target,
) -> bool {
match target {
_ if attr::contains_name(attrs, sym::naked) => {
_ if self.tcx.sess.contains_name(attrs, sym::naked) => {
struct_span_err!(
self.tcx.sess,
*attr_span,
@ -262,7 +261,7 @@ impl CheckAttrVisitor<'tcx> {
// ```
let hints: Vec<_> = attrs
.iter()
.filter(|attr| attr.check_name(sym::repr))
.filter(|attr| self.tcx.sess.check_name(attr, sym::repr))
.filter_map(|attr| attr.meta_item_list())
.flatten()
.collect();
@ -391,10 +390,10 @@ impl CheckAttrVisitor<'tcx> {
// When checking statements ignore expressions, they will be checked later
if let hir::StmtKind::Local(ref l) = stmt.kind {
for attr in l.attrs.iter() {
if attr.check_name(sym::inline) {
if self.tcx.sess.check_name(attr, sym::inline) {
self.check_inline(l.hir_id, attr, &stmt.span, Target::Statement);
}
if attr.check_name(sym::repr) {
if self.tcx.sess.check_name(attr, sym::repr) {
self.emit_repr_error(
attr.span,
stmt.span,
@ -412,10 +411,10 @@ impl CheckAttrVisitor<'tcx> {
_ => Target::Expression,
};
for attr in expr.attrs.iter() {
if attr.check_name(sym::inline) {
if self.tcx.sess.check_name(attr, sym::inline) {
self.check_inline(expr.hir_id, attr, &expr.span, target);
}
if attr.check_name(sym::repr) {
if self.tcx.sess.check_name(attr, sym::repr) {
self.emit_repr_error(
attr.span,
expr.span,
@ -431,7 +430,7 @@ impl CheckAttrVisitor<'tcx> {
fn check_used(&self, attrs: &'hir [Attribute], target: Target) {
for attr in attrs {
if attr.check_name(sym::used) && target != Target::Static {
if self.tcx.sess.check_name(attr, sym::used) && target != Target::Static {
self.tcx
.sess
.span_err(attr.span, "attribute must be applied to a `static` variable");

View File

@ -106,7 +106,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
// opt-in via `allow_internal_unstable`.
attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
attr::allow_internal_unstable(&tcx.sess, &tcx.get_attrs(def_id))
.map_or(false, |mut features| features.any(|name| name == feature_gate))
};

View File

@ -15,7 +15,7 @@ use rustc_middle::middle::privacy;
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::lint;
use rustc_ast::{ast, attr};
use rustc_ast::ast;
use rustc_span::symbol::{sym, Symbol};
// Any local node that may call something in its body block should be
@ -331,17 +331,17 @@ fn has_allow_dead_code_or_lang_attr(
id: hir::HirId,
attrs: &[ast::Attribute],
) -> bool {
if attr::contains_name(attrs, sym::lang) {
if tcx.sess.contains_name(attrs, sym::lang) {
return true;
}
// Stable attribute for #[lang = "panic_impl"]
if attr::contains_name(attrs, sym::panic_handler) {
if tcx.sess.contains_name(attrs, sym::panic_handler) {
return true;
}
// (To be) stable attribute for #[lang = "oom"]
if attr::contains_name(attrs, sym::alloc_error_handler) {
if tcx.sess.contains_name(attrs, sym::alloc_error_handler) {
return true;
}

View File

@ -16,6 +16,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
struct DiagnosticItemCollector<'tcx> {
@ -44,7 +45,7 @@ impl<'tcx> DiagnosticItemCollector<'tcx> {
}
fn observe_item(&mut self, attrs: &[ast::Attribute], hir_id: hir::HirId) {
if let Some(name) = extract(attrs) {
if let Some(name) = extract(&self.tcx.sess, attrs) {
let def_id = self.tcx.hir().local_def_id(hir_id);
// insert into our table
collect_item(self.tcx, &mut self.items, name, def_id.to_def_id());
@ -86,9 +87,9 @@ fn collect_item(
}
/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
fn extract(sess: &Session, attrs: &[ast::Attribute]) -> Option<Symbol> {
attrs.iter().find_map(|attr| {
if attr.check_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None }
if sess.check_name(attr, sym::rustc_diagnostic_item) { attr.value_str() } else { None }
})
}

View File

@ -1,4 +1,3 @@
use rustc_ast::attr;
use rustc_ast::entry::EntryPointType;
use rustc_errors::struct_span_err;
use rustc_hir::def_id::{CrateNum, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@ -58,7 +57,7 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
}
// If the user wants no main function at all, then stop here.
if attr::contains_name(&tcx.hir().krate().item.attrs, sym::no_main) {
if tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_main) {
return None;
}
@ -76,14 +75,14 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
configure_main(tcx, &ctxt)
}
// Beware, this is duplicated in `librustc_ast/entry.rs`, so make sure to keep
// them in sync.
fn entry_point_type(item: &Item<'_>, at_root: bool) -> EntryPointType {
// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
// (with `ast::Item`), so make sure to keep them in sync.
fn entry_point_type(sess: &Session, item: &Item<'_>, at_root: bool) -> EntryPointType {
match item.kind {
ItemKind::Fn(..) => {
if attr::contains_name(&item.attrs, sym::start) {
if sess.contains_name(&item.attrs, sym::start) {
EntryPointType::Start
} else if attr::contains_name(&item.attrs, sym::main) {
} else if sess.contains_name(&item.attrs, sym::main) {
EntryPointType::MainAttr
} else if item.ident.name == sym::main {
if at_root {
@ -101,7 +100,7 @@ fn entry_point_type(item: &Item<'_>, at_root: bool) -> EntryPointType {
}
fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
match entry_point_type(item, at_root) {
match entry_point_type(&ctxt.session, item, at_root) {
EntryPointType::MainNamed => {
if ctxt.main_fn.is_none() {
ctxt.main_fn = Some((item.hir_id, item.span));

View File

@ -56,7 +56,8 @@ impl LanguageItemCollector<'tcx> {
}
fn check_for_lang(&mut self, actual_target: Target, hir_id: HirId, attrs: &[Attribute]) {
if let Some((value, span)) = extract(&attrs) {
let check_name = |attr, sym| self.tcx.sess.check_name(attr, sym);
if let Some((value, span)) = extract(check_name, &attrs) {
match ITEM_REFS.get(&value).cloned() {
// Known lang item with attribute on correct target.
Some((item_index, expected_target)) if actual_target == expected_target => {

View File

@ -29,7 +29,7 @@ impl ItemLikeVisitor<'tcx> for LayoutTest<'tcx> {
| ItemKind::Struct(..)
| ItemKind::Union(..) => {
for attr in self.tcx.get_attrs(item_def_id.to_def_id()).iter() {
if attr.check_name(sym::rustc_layout) {
if self.tcx.sess.check_name(attr, sym::rustc_layout) {
self.dump_layout_of(item_def_id, item, attr);
}
}

View File

@ -34,7 +34,9 @@ impl LibFeatureCollector<'tcx> {
// Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
// `#[rustc_const_unstable (..)]`).
if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.check_name(**stab_attr)) {
if let Some(stab_attr) =
stab_attrs.iter().find(|stab_attr| self.tcx.sess.check_name(attr, **stab_attr))
{
let meta_item = attr.meta();
if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta_item {
let mut feature = None;

View File

@ -355,7 +355,7 @@ fn visit_fn<'tcx>(
if let FnKind::Method(..) = fk {
let parent = ir.tcx.hir().get_parent_item(id);
if let Some(Node::Item(i)) = ir.tcx.hir().find(parent) {
if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) {
if i.attrs.iter().any(|a| ir.tcx.sess.check_name(a, sym::automatically_derived)) {
return;
}
}

View File

@ -65,11 +65,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
did_error = self.forbid_staged_api_attrs(hir_id, attrs);
}
let depr = if did_error {
None
} else {
attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp)
};
let depr =
if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs, item_sp) };
let mut is_deprecated = false;
if let Some(depr) = &depr {
is_deprecated = true;
@ -88,7 +85,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
}
if self.tcx.features().staged_api {
if let Some(..) = attrs.iter().find(|a| a.check_name(sym::deprecated)) {
if let Some(..) = attrs.iter().find(|a| self.tcx.sess.check_name(a, sym::deprecated)) {
self.tcx.sess.span_err(
item_sp,
"`#[deprecated]` cannot be used in staged API; \
@ -105,7 +102,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
return;
}
let (stab, const_stab) = attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp);
let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
let const_stab = const_stab.map(|const_stab| {
let const_stab = self.tcx.intern_const_stability(const_stab);
@ -252,7 +249,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
for attr in attrs {
let name = attr.name_or_empty();
if unstable_attrs.contains(&name) {
attr::mark_used(attr);
self.tcx.sess.mark_attr_used(attr);
struct_span_err!(
self.tcx.sess,
attr.span,

View File

@ -100,7 +100,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
}
fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) {
if let Some((lang_item, _)) = hir::lang_items::extract(&i.attrs) {
let check_name = |attr, sym| self.tcx.sess.check_name(attr, sym);
if let Some((lang_item, _)) = hir::lang_items::extract(check_name, &i.attrs) {
self.register(lang_item, i.span, i.hir_id);
}
intravisit::walk_foreign_item(self, i)

View File

@ -1,6 +1,5 @@
//! Used by `rustc` when compiling a plugin crate.
use rustc_ast::attr;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
@ -9,14 +8,15 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
use rustc_span::Span;
struct RegistrarFinder {
struct RegistrarFinder<'tcx> {
tcx: TyCtxt<'tcx>,
registrars: Vec<(hir::HirId, Span)>,
}
impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
impl<'v, 'tcx> ItemLikeVisitor<'v> for RegistrarFinder<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
if let hir::ItemKind::Fn(..) = item.kind {
if attr::contains_name(&item.attrs, sym::plugin_registrar) {
if self.tcx.sess.contains_name(&item.attrs, sym::plugin_registrar) {
self.registrars.push((item.hir_id, item.span));
}
}
@ -35,7 +35,7 @@ pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option<DefId> {
fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
assert_eq!(cnum, LOCAL_CRATE);
let mut finder = RegistrarFinder { registrars: Vec::new() };
let mut finder = RegistrarFinder { tcx, registrars: Vec::new() };
tcx.hir().krate().visit_all_item_likes(&mut finder);
match finder.registrars.len() {

View File

@ -8,6 +8,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(nll)]
#![recursion_limit = "256"]
use rustc_lint::LintStore;

View File

@ -32,7 +32,7 @@ pub fn load_plugins(
let mut plugins = Vec::new();
for attr in &krate.attrs {
if !attr.check_name(sym::plugin) {
if !sess.check_name(attr, sym::plugin) {
continue;
}

View File

@ -232,7 +232,7 @@ fn def_id_visibility<'tcx>(
Node::Item(item) => &item.vis,
Node::ForeignItem(foreign_item) => &foreign_item.vis,
Node::MacroDef(macro_def) => {
if attr::contains_name(&macro_def.attrs, sym::macro_export) {
if tcx.sess.contains_name(&macro_def.attrs, sym::macro_export) {
return (ty::Visibility::Public, macro_def.span, "public");
} else {
&macro_def.vis
@ -271,8 +271,11 @@ fn def_id_visibility<'tcx>(
ctor_vis =
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
let attrs = tcx.get_attrs(variant.def_id);
span =
attr::find_by_name(&attrs, sym::non_exhaustive).unwrap().span;
span = tcx
.sess
.find_by_name(&attrs, sym::non_exhaustive)
.unwrap()
.span;
descr = "crate-visible";
}
@ -305,7 +308,9 @@ fn def_id_visibility<'tcx>(
if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
ctor_vis =
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
span = attr::find_by_name(&item.attrs, sym::non_exhaustive)
span = tcx
.sess
.find_by_name(&item.attrs, sym::non_exhaustive)
.unwrap()
.span;
descr = "crate-visible";
@ -914,7 +919,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
}
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
if attr::find_transparency(&md.attrs, md.ast.macro_rules).0 != Transparency::Opaque {
if attr::find_transparency(&self.tcx.sess, &md.attrs, md.ast.macro_rules).0
!= Transparency::Opaque
{
self.update(md.hir_id, Some(AccessLevel::Public));
return;
}

View File

@ -541,7 +541,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
ast::UseTreeKind::Glob => {
let kind = ImportKind::Glob {
is_prelude: attr::contains_name(&item.attrs, sym::prelude_import),
is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import),
max_vis: Cell::new(ty::Visibility::Invisible),
};
self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis);
@ -712,7 +712,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let module_kind = ModuleKind::Def(DefKind::Mod, def_id.to_def_id(), ident.name);
let module = self.r.arenas.alloc_module(ModuleData {
no_implicit_prelude: parent.no_implicit_prelude || {
attr::contains_name(&item.attrs, sym::no_implicit_prelude)
self.r.session.contains_name(&item.attrs, sym::no_implicit_prelude)
},
..ModuleData::new(
Some(parent),
@ -789,7 +789,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
let mut ctor_vis = if vis == ty::Visibility::Public
&& attr::contains_name(&item.attrs, sym::non_exhaustive)
&& self.r.session.contains_name(&item.attrs, sym::non_exhaustive)
{
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
} else {
@ -991,7 +991,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let mut import_all = None;
let mut single_imports = Vec::new();
for attr in &item.attrs {
if attr.check_name(sym::macro_use) {
if self.r.session.check_name(attr, sym::macro_use) {
if self.parent_scope.module.parent.is_some() {
struct_span_err!(
self.r.session,
@ -1097,7 +1097,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
/// Returns `true` if this attribute list contains `macro_use`.
fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool {
for attr in attrs {
if attr.check_name(sym::macro_escape) {
if self.r.session.check_name(attr, sym::macro_escape) {
let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`";
let mut err = self.r.session.struct_span_warn(attr.span, msg);
if let ast::AttrStyle::Inner = attr.style {
@ -1105,7 +1105,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
} else {
err.emit();
}
} else if !attr.check_name(sym::macro_use) {
} else if !self.r.session.check_name(attr, sym::macro_use) {
continue;
}
@ -1129,12 +1129,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
MacroRulesScope::Invocation(invoc_id)
}
fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
if attr::contains_name(&item.attrs, sym::proc_macro) {
fn proc_macro_stub(&self, item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
if self.r.session.contains_name(&item.attrs, sym::proc_macro) {
return Some((MacroKind::Bang, item.ident, item.span));
} else if attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
} else if self.r.session.contains_name(&item.attrs, sym::proc_macro_attribute) {
return Some((MacroKind::Attr, item.ident, item.span));
} else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
} else if let Some(attr) = self.r.session.find_by_name(&item.attrs, sym::proc_macro_derive)
{
if let Some(nested_meta) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
if let Some(ident) = nested_meta.ident() {
return Some((MacroKind::Derive, ident, ident.span));
@ -1168,7 +1169,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let ext = Lrc::new(self.r.compile_macro(item, self.r.session.edition()));
(ext, item.ident, item.span, def.macro_rules)
}
ItemKind::Fn(..) => match Self::proc_macro_stub(item) {
ItemKind::Fn(..) => match self.proc_macro_stub(item) {
Some((macro_kind, ident, span)) => {
self.r.proc_macro_stubs.insert(def_id);
(self.r.dummy_ext(macro_kind), ident, span, false)
@ -1185,7 +1186,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
if macro_rules {
let ident = ident.normalize_to_macros_2_0();
self.r.macro_names.insert(ident);
let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export);
let vis = if is_macro_export {
ty::Visibility::Public
} else {
@ -1416,7 +1417,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
// If the variant is marked as non_exhaustive then lower the visibility to within the
// crate.
let mut ctor_vis = vis;
let has_non_exhaustive = attr::contains_name(&variant.attrs, sym::non_exhaustive);
let has_non_exhaustive = self.r.session.contains_name(&variant.attrs, sym::non_exhaustive);
if has_non_exhaustive && vis == ty::Visibility::Public {
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
}

View File

@ -6,7 +6,6 @@
//! way. Therefore, we break lifetime name resolution into a separate pass.
use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
use rustc_ast::attr;
use rustc_ast::walk_list;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
@ -1179,7 +1178,7 @@ fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap<Vec<ObjectLifet
let result = object_lifetime_defaults_for_item(tcx, generics);
// Debugging aid.
if attr::contains_name(&item.attrs, sym::rustc_object_lifetime_default) {
if tcx.sess.contains_name(&item.attrs, sym::rustc_object_lifetime_default) {
let object_lifetime_default_reprs: String = result
.iter()
.map(|set| match *set {
@ -1540,13 +1539,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
if let Some(def_id) = parent_def_id.as_local() {
let parent_hir_id = self.tcx.hir().as_local_hir_id(def_id);
// lifetimes in `derive` expansions don't count (Issue #53738)
if self
.tcx
.hir()
.attrs(parent_hir_id)
.iter()
.any(|attr| attr.check_name(sym::automatically_derived))
{
if self.tcx.hir().attrs(parent_hir_id).iter().any(|attr| {
self.tcx.sess.check_name(attr, sym::automatically_derived)
}) {
continue;
}
}

View File

@ -23,7 +23,6 @@ use rustc_arena::TypedArena;
use rustc_ast::ast::{self, FloatTy, IntTy, NodeId, UintTy};
use rustc_ast::ast::{Crate, CRATE_NODE_ID};
use rustc_ast::ast::{ItemKind, Path};
use rustc_ast::attr;
use rustc_ast::node_id::NodeMap;
use rustc_ast::unwrap_or;
use rustc_ast::visit::{self, Visitor};
@ -1198,7 +1197,7 @@ impl<'a> Resolver<'a> {
let root_def_id = DefId::local(CRATE_DEF_INDEX);
let root_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Invalid);
let graph_root = arenas.alloc_module(ModuleData {
no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
no_implicit_prelude: session.contains_name(&krate.attrs, sym::no_implicit_prelude),
..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
});
let empty_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Invalid);
@ -1236,9 +1235,9 @@ impl<'a> Resolver<'a> {
.map(|(name, _)| (Ident::from_str(name), Default::default()))
.collect();
if !attr::contains_name(&krate.attrs, sym::no_core) {
if !session.contains_name(&krate.attrs, sym::no_core) {
extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
if !attr::contains_name(&krate.attrs, sym::no_std) {
if !session.contains_name(&krate.attrs, sym::no_std) {
extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default());
if session.rust_2018() {
extern_prelude.insert(Ident::with_dummy_span(sym::meta), Default::default());

View File

@ -9,7 +9,7 @@ use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, T
use rustc_ast::ast::{self, NodeId};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, StabilityLevel};
use rustc_attr::StabilityLevel;
use rustc_data_structures::fx::FxHashSet;
use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
use rustc_expand::compile_declarative_macro;
@ -105,7 +105,7 @@ fn registered_idents(
descr: &str,
) -> FxHashSet<Ident> {
let mut registered = FxHashSet::default();
for attr in attr::filter_by_name(attrs, attr_name) {
for attr in sess.filter_by_name(attrs, attr_name) {
for nested_meta in attr.meta_item_list().unwrap_or_default() {
match nested_meta.ident() {
Some(ident) => {
@ -1068,7 +1068,7 @@ impl<'a> Resolver<'a> {
/// its expander to a pre-defined one for built-in macros.
crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension {
let mut result = compile_declarative_macro(
&self.session.parse_sess,
&self.session,
self.session.features_untracked(),
item,
edition,

View File

@ -825,7 +825,7 @@ impl<'tcx> SaveContext<'tcx> {
// FIXME: Should save-analysis beautify doc strings itself or leave it to users?
result.push_str(&beautify_doc_string(val));
result.push('\n');
} else if attr.check_name(sym::doc) {
} else if self.tcx.sess.check_name(attr, sym::doc) {
if let Some(meta_list) = attr.meta_item_list() {
meta_list
.into_iter()

View File

@ -1,7 +1,7 @@
//! Related to out filenames of compilation (e.g. save analysis, binaries).
use crate::config::{CrateType, Input, OutputFilenames, OutputType};
use crate::Session;
use rustc_ast::{ast, attr};
use rustc_ast::ast;
use rustc_span::symbol::sym;
use rustc_span::Span;
use std::path::{Path, PathBuf};
@ -45,7 +45,7 @@ fn is_writeable(p: &Path) -> bool {
}
}
pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String {
pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) -> String {
let validate = |s: String, span: Option<Span>| {
validate_crate_name(sess, &s, span);
s
@ -56,22 +56,20 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input:
// the command line over one found in the #[crate_name] attribute. If we
// find both we ensure that they're the same later on as well.
let attr_crate_name =
attr::find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s)));
sess.find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(sess) = sess {
if let Some(ref s) = sess.opts.crate_name {
if let Some((attr, name)) = attr_crate_name {
if name.as_str() != *s {
let msg = format!(
"`--crate-name` and `#[crate_name]` are \
required to match, but `{}` != `{}`",
s, name
);
sess.span_err(attr.span, &msg);
}
if let Some(ref s) = sess.opts.crate_name {
if let Some((attr, name)) = attr_crate_name {
if name.as_str() != *s {
let msg = format!(
"`--crate-name` and `#[crate_name]` are \
required to match, but `{}` != `{}`",
s, name
);
sess.span_err(attr.span, &msg);
}
return validate(s.clone(), None);
}
return validate(s.clone(), None);
}
if let Some((attr, s)) = attr_crate_name {
@ -85,9 +83,7 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input:
`{}` has a leading hyphen",
s
);
if let Some(sess) = sess {
sess.err(&msg);
}
sess.err(&msg);
} else {
return validate(s.replace("-", "_"), None);
}
@ -97,14 +93,13 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input:
"rust_out".to_string()
}
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
pub fn validate_crate_name(sess: &Session, s: &str, sp: Option<Span>) {
let mut err_count = 0;
{
let mut say = |s: &str| {
match (sp, sess) {
(_, None) => panic!("{}", s),
(Some(sp), Some(sess)) => sess.span_err(sp, s),
(None, Some(sess)) => sess.err(s),
match sp {
Some(sp) => sess.span_err(sp, s),
None => sess.err(s),
}
err_count += 1;
};
@ -123,7 +118,7 @@ pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
}
if err_count > 0 {
sess.unwrap().abort_if_errors();
sess.abort_if_errors();
}
}

View File

@ -7,6 +7,8 @@ use crate::lint;
use crate::parse::ParseSess;
use crate::search_paths::{PathKind, SearchPath};
pub use rustc_ast::ast::Attribute;
pub use rustc_ast::attr::MarkedAttrs;
pub use rustc_ast::crate_disambiguator::CrateDisambiguator;
use rustc_data_structures::flock;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -22,7 +24,7 @@ use rustc_errors::registry::Registry;
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_span::edition::Edition;
use rustc_span::source_map::{FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
use rustc_span::{SourceFileHashAlgorithm, Symbol};
use rustc_span::{sym, SourceFileHashAlgorithm, Symbol};
use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
use rustc_target::spec::{Target, TargetTriple, TlsModel};
@ -208,6 +210,9 @@ pub struct Session {
/// Set of enabled features for the current target.
pub target_features: FxHashSet<Symbol>,
known_attrs: Lock<MarkedAttrs>,
used_attrs: Lock<MarkedAttrs>,
}
pub struct PerfStats {
@ -1020,6 +1025,76 @@ impl Session {
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
|| self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY)
}
pub fn mark_attr_known(&self, attr: &Attribute) {
self.known_attrs.lock().mark(attr)
}
pub fn is_attr_known(&self, attr: &Attribute) -> bool {
self.known_attrs.lock().is_marked(attr)
}
pub fn mark_attr_used(&self, attr: &Attribute) {
self.used_attrs.lock().mark(attr)
}
pub fn is_attr_used(&self, attr: &Attribute) -> bool {
self.used_attrs.lock().is_marked(attr)
}
/// Returns `true` if the attribute's path matches the argument. If it matches, then the
/// attribute is marked as used.
/// Returns `true` if the attribute's path matches the argument. If it
/// matches, then the attribute is marked as used.
///
/// This method should only be used by rustc, other tools can use
/// `Attribute::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 have the `has_name` method, and you need to mark the original
/// `Attribute` as used when necessary.)
pub fn check_name(&self, attr: &Attribute, name: Symbol) -> bool {
let matches = attr.has_name(name);
if matches {
self.mark_attr_used(attr);
}
matches
}
pub fn is_proc_macro_attr(&self, attr: &Attribute) -> bool {
[sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
.iter()
.any(|kind| self.check_name(attr, *kind))
}
pub fn contains_name(&self, attrs: &[Attribute], name: Symbol) -> bool {
attrs.iter().any(|item| self.check_name(item, name))
}
pub fn find_by_name<'a>(
&'a self,
attrs: &'a [Attribute],
name: Symbol,
) -> Option<&'a Attribute> {
attrs.iter().find(|attr| self.check_name(attr, name))
}
pub fn filter_by_name<'a>(
&'a self,
attrs: &'a [Attribute],
name: Symbol,
) -> impl Iterator<Item = &'a Attribute> {
attrs.iter().filter(move |attr| self.check_name(attr, name))
}
pub fn first_attr_value_str_by_name(
&self,
attrs: &[Attribute],
name: Symbol,
) -> Option<Symbol> {
attrs.iter().find(|at| self.check_name(at, name)).and_then(|at| at.value_str())
}
}
fn default_emitter(
@ -1283,6 +1358,8 @@ pub fn build_session(
real_rust_source_base_dir,
asm_arch,
target_features: FxHashSet::default(),
known_attrs: Lock::new(MarkedAttrs::new()),
used_attrs: Lock::new(MarkedAttrs::new()),
};
validate_commandline_args_with_session_available(&sess);

View File

@ -87,6 +87,15 @@ impl SessionGlobals {
}
}
pub fn with_session_globals<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
let session_globals = SessionGlobals::new(edition);
SESSION_GLOBALS.set(&session_globals, f)
}
pub fn with_default_session_globals<R>(f: impl FnOnce() -> R) -> R {
with_session_globals(edition::DEFAULT_EDITION, f)
}
// If this ever becomes non thread-local, `decode_syntax_context`
// and `decode_expn_id` will need to be updated to handle concurrent
// deserialization.

Some files were not shown because too many files have changed in this diff Show More