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:
commit
e61621c307
@ -3195,7 +3195,6 @@ dependencies = [
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
"rustc_span",
|
||||
"scoped-tls",
|
||||
"smallvec 1.4.0",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -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" }
|
||||
|
@ -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![];
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::*;
|
||||
use crate::with_default_session_globals;
|
||||
use rustc_span::with_default_session_globals;
|
||||
|
||||
#[test]
|
||||
fn line_doc_comments() {
|
||||
|
@ -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!(
|
||||
|
@ -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 {
|
||||
|
@ -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(¶m.attrs, sym::may_dangle),
|
||||
pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle),
|
||||
attrs: self.lower_attrs(¶m.attrs),
|
||||
bounds: self.arena.alloc_from_iter(bounds),
|
||||
kind,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}))
|
||||
|
@ -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) => {
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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(
|
||||
|
@ -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());
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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`",
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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!(
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
})
|
||||
})
|
||||
|
@ -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)* {
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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| {
|
||||
|
@ -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`.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)]`.
|
||||
|
@ -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());
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(..) => {
|
||||
|
@ -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>> {
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()))
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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`.
|
||||
|
@ -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, ®istry)))
|
||||
});
|
||||
rustc_span::SESSION_GLOBALS
|
||||
.set(session_globals, || tls::with(|tcx| deadlock(tcx, ®istry)))
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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))
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 }
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 => {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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() {
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
#![feature(nll)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
use rustc_lint::LintStore;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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(¯o_def.attrs, sym::macro_export) {
|
||||
if tcx.sess.contains_name(¯o_def.attrs, sym::macro_export) {
|
||||
return (ty::Visibility::Public, macro_def.span, "public");
|
||||
} else {
|
||||
¯o_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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user