use crate::hir::def_id::DefId;
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use std::fmt::{self, Display};
+use syntax::symbol::sym;
use syntax_pos::Span;
#[derive(Copy, Clone, PartialEq)]
fn check_attributes(&self, item: &hir::Item, target: Target) {
if target == Target::Fn || target == Target::Const {
self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
- } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) {
+ } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) {
self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
.span_label(item.span, "not a function")
.emit();
}
for attr in &item.attrs {
- if attr.check_name("inline") {
+ if attr.check_name(sym::inline) {
self.check_inline(attr, &item.span, target)
- } else if attr.check_name("non_exhaustive") {
+ } else if attr.check_name(sym::non_exhaustive) {
self.check_non_exhaustive(attr, item, target)
- } else if attr.check_name("marker") {
+ } else if attr.check_name(sym::marker) {
self.check_marker(attr, item, target)
}
}
// ```
let hints: Vec<_> = item.attrs
.iter()
- .filter(|attr| attr.check_name("repr"))
+ .filter(|attr| attr.check_name(sym::repr))
.filter_map(|attr| attr.meta_item_list())
.flatten()
.collect();
let mut is_transparent = false;
for hint in &hints {
- let (article, allowed_targets) = match hint.name_or_empty().get() {
- name @ "C" | name @ "align" => {
- is_c |= name == "C";
+ let (article, allowed_targets) = match hint.name_or_empty() {
+ name @ sym::C | name @ sym::align => {
+ is_c |= name == sym::C;
if target != Target::Struct &&
target != Target::Union &&
target != Target::Enum {
continue
}
}
- "packed" => {
+ sym::packed => {
if target != Target::Struct &&
target != Target::Union {
("a", "struct or union")
continue
}
}
- "simd" => {
+ sym::simd => {
is_simd = true;
if target != Target::Struct {
("a", "struct")
continue
}
}
- "transparent" => {
+ sym::transparent => {
is_transparent = true;
if target != Target::Struct {
("a", "struct")
continue
}
}
- "i8" | "u8" | "i16" | "u16" |
- "i32" | "u32" | "i64" | "u64" |
- "isize" | "usize" => {
+ sym::i8 | sym::u8 | sym::i16 | sym::u16 |
+ sym::i32 | sym::u32 | sym::i64 | sym::u64 |
+ sym::isize | sym::usize => {
int_reprs += 1;
if target != Target::Enum {
("an", "enum")
// When checking statements ignore expressions, they will be checked later
if let hir::StmtKind::Local(ref l) = stmt.node {
for attr in l.attrs.iter() {
- if attr.check_name("inline") {
+ if attr.check_name(sym::inline) {
self.check_inline(attr, &stmt.span, Target::Statement);
}
- if attr.check_name("repr") {
+ if attr.check_name(sym::repr) {
self.emit_repr_error(
attr.span,
stmt.span,
_ => Target::Expression,
};
for attr in expr.attrs.iter() {
- if attr.check_name("inline") {
+ if attr.check_name(sym::inline) {
self.check_inline(attr, &expr.span, target);
}
- if attr.check_name("repr") {
+ if attr.check_name(sym::repr) {
self.emit_repr_error(
attr.span,
expr.span,
fn check_used(&self, item: &hir::Item, target: Target) {
for attr in &item.attrs {
- if attr.check_name("used") && target != Target::Static {
+ if attr.check_name(sym::used) && target != Target::Static {
self.tcx.sess
.span_err(attr.span, "attribute must be applied to a `static` variable");
}
use syntax::source_map::{respan, CompilerDesugaringKind, Spanned};
use syntax::source_map::CompilerDesugaringKind::IfTemporary;
use syntax::std_inject;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
use syntax::tokenstream::{TokenStream, TokenTree};
use syntax::parse::token::Token;
use syntax::visit::{self, Visitor};
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
pub struct LoweringContext<'a> {
- crate_root: Option<&'static str>,
+ crate_root: Option<Symbol>,
/// Used to assign ids to HIR nodes that do not directly correspond to an AST node.
sess: &'a Session,
fn resolve_str_path(
&mut self,
span: Span,
- crate_root: Option<&str>,
- components: &[&str],
+ crate_root: Option<Symbol>,
+ components: &[Symbol],
is_value: bool,
) -> hir::Path;
}
dep_graph.assert_ignored();
LoweringContext {
- crate_root: std_inject::injected_crate_name(),
+ crate_root: std_inject::injected_crate_name().map(Symbol::intern),
sess,
cstore,
resolver,
].into()),
);
let gen_future = self.expr_std_path(
- unstable_span, &["future", "from_generator"], None, ThinVec::new());
+ unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new());
hir::ExprKind::Call(P(gen_future), hir_vec![generator])
}
// ::std::future::Future<future_params>
let future_path =
- self.std_path(span, &["future", "Future"], Some(future_params), false);
+ self.std_path(span, &[sym::future, sym::Future], Some(future_params), false);
hir::GenericBound::Trait(
hir::PolyTraitRef {
self.lower_ty(x, ImplTraitContext::disallowed())
}),
synthetic: param.attrs.iter()
- .filter(|attr| attr.check_name("rustc_synthetic"))
+ .filter(|attr| attr.check_name(sym::rustc_synthetic))
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
.next(),
};
hir_id: self.lower_node_id(param.id),
name,
span: param.ident.span,
- pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
+ pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
attrs: self.lower_attrs(¶m.attrs),
bounds,
kind,
let mut vis = self.lower_visibility(&i.vis, None);
let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(ref def) = i.node {
- if !def.legacy || attr::contains_name(&i.attrs, "macro_export") ||
- attr::contains_name(&i.attrs, "rustc_doc_only_macro") {
+ if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) ||
+ attr::contains_name(&i.attrs, sym::rustc_doc_only_macro) {
let body = self.lower_token_stream(def.stream());
let hir_id = self.lower_node_id(i.id);
self.exported_macros.push(hir::MacroDef {
|x: P<hir::Expr>| x.into_inner(),
);
block.expr = Some(this.wrap_in_try_constructor(
- "from_ok", tail, unstable_span));
+ sym::from_ok, tail, unstable_span));
hir::ExprKind::Block(P(block), None)
})
}
self.expr_call_std_assoc_fn(
id,
e.span,
- &["ops", "RangeInclusive"],
+ &[sym::ops, sym::RangeInclusive],
"new",
hir_vec![e1, e2],
)
use syntax::ast::RangeLimits::*;
let path = match (e1, e2, lims) {
- (&None, &None, HalfOpen) => "RangeFull",
- (&Some(..), &None, HalfOpen) => "RangeFrom",
- (&None, &Some(..), HalfOpen) => "RangeTo",
- (&Some(..), &Some(..), HalfOpen) => "Range",
- (&None, &Some(..), Closed) => "RangeToInclusive",
+ (&None, &None, HalfOpen) => sym::RangeFull,
+ (&Some(..), &None, HalfOpen) => sym::RangeFrom,
+ (&None, &Some(..), HalfOpen) => sym::RangeTo,
+ (&Some(..), &Some(..), HalfOpen) => sym::Range,
+ (&None, &Some(..), Closed) => sym::RangeToInclusive,
(&Some(..), &Some(..), Closed) => unreachable!(),
(_, &None, Closed) => self.diagnostic()
.span_fatal(e.span, "inclusive range with no end")
.collect::<P<[hir::Field]>>();
let is_unit = fields.is_empty();
- let struct_path = ["ops", path];
+ let struct_path = [sym::ops, path];
let struct_path = self.std_path(e.span, &struct_path, None, is_unit);
let struct_path = hir::QPath::Resolved(None, P(struct_path));
let match_expr = {
let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
- let next_path = &["iter", "Iterator", "next"];
+ let next_path = &[sym::iter, sym::Iterator, sym::next];
let next_expr = P(self.expr_call_std_path(
head_sp,
next_path,
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
let into_iter_expr = {
- let into_iter_path = &["iter", "IntoIterator", "into_iter"];
+ let into_iter_path =
+ &[sym::iter, sym::IntoIterator, sym::into_iter];
P(self.expr_call_std_path(
head_sp,
into_iter_path,
// expand <expr>
let sub_expr = self.lower_expr(sub_expr);
- let path = &["ops", "Try", "into_result"];
+ let path = &[sym::ops, sym::Try, sym::into_result];
P(self.expr_call_std_path(
unstable_span,
path,
let err_ident = self.str_to_ident("err");
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
let from_expr = {
- let from_path = &["convert", "From", "from"];
+ let from_path = &[sym::convert, sym::From, sym::from];
let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
};
let from_err_expr =
- self.wrap_in_try_constructor("from_error", from_expr, unstable_span);
+ self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span);
let thin_attrs = ThinVec::from(attrs);
let catch_scope = self.catch_scopes.last().map(|x| *x);
let ret_expr = if let Some(catch_node) = catch_scope {
fn expr_call_std_path(
&mut self,
span: Span,
- path_components: &[&str],
+ path_components: &[Symbol],
args: hir::HirVec<hir::Expr>,
) -> hir::Expr {
let path = P(self.expr_std_path(span, path_components, None, ThinVec::new()));
&mut self,
ty_path_id: hir::HirId,
span: Span,
- ty_path_components: &[&str],
+ ty_path_components: &[Symbol],
assoc_fn_name: &str,
args: hir::HirVec<hir::Expr>,
) -> hir::ExprKind {
fn expr_std_path(
&mut self,
span: Span,
- components: &[&str],
+ components: &[Symbol],
params: Option<P<hir::GenericArgs>>,
attrs: ThinVec<Attribute>,
) -> hir::Expr {
}
fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
- self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat])
+ self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat])
}
fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
- self.pat_std_enum(span, &["result", "Result", "Err"], hir_vec![pat])
+ self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat])
}
fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
- self.pat_std_enum(span, &["option", "Option", "Some"], hir_vec![pat])
+ self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat])
}
fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
- self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![])
+ self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![])
}
fn pat_std_enum(
&mut self,
span: Span,
- components: &[&str],
+ components: &[Symbol],
subpats: hir::HirVec<P<hir::Pat>>,
) -> P<hir::Pat> {
let path = self.std_path(span, components, None, true);
fn std_path(
&mut self,
span: Span,
- components: &[&str],
+ components: &[Symbol],
params: Option<P<hir::GenericArgs>>,
is_value: bool,
) -> hir::Path {
fn wrap_in_try_constructor(
&mut self,
- method: &'static str,
+ method: Symbol,
e: hir::Expr,
unstable_span: Span,
) -> P<hir::Expr> {
- let path = &["ops", "Try", method];
+ let path = &[sym::ops, sym::Try, method];
let from_err = P(self.expr_std_path(unstable_span, path, None,
ThinVec::new()));
P(self.expr_call(e.span, from_err, hir_vec![e]))
let new_unchecked_expr_kind = self.expr_call_std_assoc_fn(
pin_ty_id,
span,
- &["pin", "Pin"],
+ &[sym::pin, sym::Pin],
"new_unchecked",
hir_vec![ref_mut_pinned],
);
let unsafe_expr = self.expr_unsafe(new_unchecked);
P(self.expr_call_std_path(
gen_future_span,
- &["future", "poll_with_tls_context"],
+ &[sym::future, sym::poll_with_tls_context],
hir_vec![unsafe_expr],
))
};
let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
let ready_pat = self.pat_std_enum(
span,
- &["task", "Poll", "Ready"],
+ &[sym::task, sym::Poll, sym::Ready],
hir_vec![x_pat],
);
let break_x = self.with_loop_scope(loop_node_id, |this| {
let pending_arm = {
let pending_pat = self.pat_std_enum(
span,
- &["task", "Poll", "Pending"],
+ &[sym::task, sym::Poll, sym::Pending],
hir_vec![],
);
let empty_block = P(self.expr_block_empty(span));
None => return false,
Some((node_id, name)) => (node_id, name),
};
- if mod_name != &**part {
+ if mod_name.as_str() != *part {
return false;
}
cursor = self.map.get_parent_item(mod_id);
// We are looking at some node `n` with a given name and parent
// id; do their names match what I am seeking?
fn matches_names(&self, parent_of_n: HirId, name: Name) -> bool {
- name == &**self.item_name && self.suffix_matches(parent_of_n)
+ name.as_str() == *self.item_name && self.suffix_matches(parent_of_n)
}
fn matches_suffix(&self, hir: HirId) -> bool {
fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0);
- ich::IGNORED_ATTRIBUTES.iter().map(|&s| Symbol::intern(s)).collect()
+ ich::IGNORED_ATTRIBUTES.iter().map(|&s| s).collect()
}
/// This is the context state available during incr. comp. hashing. It contains
pub use self::caching_source_map_view::CachingSourceMapView;
pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode,
hash_stable_trait_impls};
+use syntax::symbol::{Symbol, sym};
+
mod caching_source_map_view;
mod hcx;
mod impls_ty;
mod impls_syntax;
-pub const ATTR_DIRTY: &str = "rustc_dirty";
-pub const ATTR_CLEAN: &str = "rustc_clean";
-pub const ATTR_IF_THIS_CHANGED: &str = "rustc_if_this_changed";
-pub const ATTR_THEN_THIS_WOULD_NEED: &str = "rustc_then_this_would_need";
-pub const ATTR_PARTITION_REUSED: &str = "rustc_partition_reused";
-pub const ATTR_PARTITION_CODEGENED: &str = "rustc_partition_codegened";
-pub const ATTR_EXPECTED_CGU_REUSE: &str = "rustc_expected_cgu_reuse";
+pub const ATTR_DIRTY: Symbol = sym::rustc_dirty;
+pub const ATTR_CLEAN: Symbol = sym::rustc_clean;
+pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed;
+pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need;
+pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused;
+pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened;
+pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse;
-pub const IGNORED_ATTRIBUTES: &[&str] = &[
- "cfg",
+pub const IGNORED_ATTRIBUTES: &[Symbol] = &[
+ sym::cfg,
ATTR_IF_THIS_CHANGED,
ATTR_THEN_THIS_WOULD_NEED,
ATTR_DIRTY,
use syntax::attr;
use syntax::feature_gate;
use syntax::source_map::MultiSpan;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
pub struct LintLevelSets {
list: Vec<LintSet>,
struct_span_err!(sess, span, E0452, "malformed lint attribute")
};
for attr in attrs {
- let level = match Level::from_str(&attr.name_or_empty()) {
+ let level = match Level::from_symbol(attr.name_or_empty()) {
None => continue,
Some(lvl) => lvl,
};
match item.node {
ast::MetaItemKind::Word => {} // actual lint names handled later
ast::MetaItemKind::NameValue(ref name_value) => {
- if item.path == "reason" {
+ if item.path == sym::reason {
// found reason, reslice meta list to exclude it
metas = &metas[0..metas.len()-1];
// FIXME (#55112): issue unused-attributes lint if we thereby
if !self.sess.features_untracked().lint_reasons {
feature_gate::emit_feature_err(
&self.sess.parse_sess,
- "lint_reasons",
+ sym::lint_reasons,
item.span,
feature_gate::GateIssue::Language,
"lint reasons are experimental"
let mut err = bad_attr(li.span());
if let Some(item) = li.meta_item() {
if let ast::MetaItemKind::NameValue(_) = item.node {
- if item.path == "reason" {
+ if item.path == sym::reason {
err.help("reason in lint attribute must come last");
}
}
use syntax::source_map::{MultiSpan, ExpnFormat};
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::edition::Edition;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore,
_ => None,
}
}
+
+ /// Converts a symbol to a level.
+ pub fn from_symbol(x: Symbol) -> Option<Level> {
+ match x {
+ sym::allow => Some(Allow),
+ sym::warn => Some(Warn),
+ sym::deny => Some(Deny),
+ sym::forbid => Some(Forbid),
+ _ => None,
+ }
+ }
}
/// How a lint level was set.
pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool {
let attrs = tcx.hir().attrs_by_hir_id(id);
- attrs.iter().any(|attr| Level::from_str(&attr.name_or_empty()).is_some())
+ attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some())
}
fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
use syntax::{ast, source_map};
use syntax::attr;
+use syntax::symbol::sym;
use syntax_pos;
// Any local node that may call something in its body block should be
fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
id: hir::HirId,
attrs: &[ast::Attribute]) -> bool {
- if attr::contains_name(attrs, "lang") {
+ if attr::contains_name(attrs, sym::lang) {
return true;
}
// Stable attribute for #[lang = "panic_impl"]
- if attr::contains_name(attrs, "panic_handler") {
+ if attr::contains_name(attrs, sym::panic_handler) {
return true;
}
// (To be) stable attribute for #[lang = "oom"]
- if attr::contains_name(attrs, "alloc_error_handler") {
+ if attr::contains_name(attrs, sym::alloc_error_handler) {
return true;
}
// Don't lint about global allocators
- if attr::contains_name(attrs, "global_allocator") {
+ if attr::contains_name(attrs, sym::global_allocator) {
return true;
}
use crate::session::config::EntryFnType;
use syntax::attr;
use syntax::entry::EntryPointType;
+use syntax::symbol::sym;
use syntax_pos::Span;
use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
use crate::hir::itemlikevisit::ItemLikeVisitor;
}
// If the user wants no main function at all, then stop here.
- if attr::contains_name(&tcx.hir().krate().attrs, "no_main") {
+ if attr::contains_name(&tcx.hir().krate().attrs, sym::no_main) {
return None;
}
fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
match item.node {
ItemKind::Fn(..) => {
- if attr::contains_name(&item.attrs, "start") {
+ if attr::contains_name(&item.attrs, sym::start) {
EntryPointType::Start
- } else if attr::contains_name(&item.attrs, "main") {
+ } else if attr::contains_name(&item.attrs, sym::main) {
EntryPointType::MainAttr
- } else if item.ident.name == "main" {
+ } else if item.ident.name == sym::main {
if at_root {
// This is a top-level function so can be 'main'.
EntryPointType::MainNamed
use crate::util::nodemap::FxHashMap;
use syntax::ast;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
use rustc_macros::HashStable;
use crate::hir::itemlikevisit::ItemLikeVisitor;
/// are also extracted out when found.
pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
attrs.iter().find_map(|attr| Some(match attr {
- _ if attr.check_name("lang") => (attr.value_str()?, attr.span),
- _ if attr.check_name("panic_handler") => (Symbol::intern("panic_impl"), attr.span),
- _ if attr.check_name("alloc_error_handler") => (Symbol::intern("oom"), attr.span),
+ _ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span),
+ _ if attr.check_name(sym::panic_handler) => (Symbol::intern("panic_impl"), attr.span),
+ _ if attr.check_name(sym::alloc_error_handler) => (Symbol::intern("oom"), attr.span),
_ => return None,
}))
}
use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
use syntax::symbol::Symbol;
use syntax::ast::{Attribute, MetaItem, MetaItemKind};
-use syntax_pos::{Span, symbols};
+use syntax_pos::{Span, sym};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_macros::HashStable;
use errors::DiagnosticId;
}
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
- let stab_attrs = [symbols::stable, symbols::unstable, symbols::rustc_const_unstable];
+ let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable];
// Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
// `#[rustc_const_unstable (..)]`).
for meta in metas {
if let Some(mi) = meta.meta_item() {
// Find the `feature = ".."` meta-item.
- match (mi.name_or_empty().get(), mi.value_str()) {
- ("feature", val) => feature = val,
- ("since", val) => since = val,
+ match (mi.name_or_empty(), mi.value_str()) {
+ (sym::feature, val) => feature = val,
+ (sym::since, val) => since = val,
_ => {}
}
}
// This additional check for stability is to make sure we
// don't emit additional, irrelevant errors for malformed
// attributes.
- if *stab_attr != "stable" || since.is_some() {
+ if *stab_attr != sym::stable || since.is_some() {
return Some((feature, since, attr.span));
}
}
use std::rc::Rc;
use syntax::ast::{self, NodeId};
use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax_pos::Span;
use crate::hir;
if let FnKind::Method(..) = fk {
let parent = ir.tcx.hir().get_parent_item(id);
if let Some(Node::Item(i)) = ir.tcx.hir().find_by_hir_id(parent) {
- if i.attrs.iter().any(|a| a.check_name("automatically_derived")) {
+ if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) {
return;
}
}
use crate::hir::pat_util::EnumerateAndAdjustIterator;
use crate::hir;
use syntax::ast::{self, Name};
+use syntax::symbol::sym;
use syntax_pos::Span;
use std::borrow::Cow;
// they also cannot be moved out of.
let is_thread_local = self.tcx.get_attrs(def_id)[..]
.iter()
- .any(|attr| attr.check_name("thread_local"));
+ .any(|attr| attr.check_name(sym::thread_local));
let cat = if is_thread_local {
let re = self.temporary_scope(hir_id.local_id);
use crate::session::Session;
use syntax::ast;
+use syntax::symbol::{Symbol, sym};
use rustc_data_structures::sync::Once;
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
- update_limit(krate, &sess.recursion_limit, "recursion_limit", 64);
- update_limit(krate, &sess.type_length_limit, "type_length_limit", 1048576);
+ update_limit(krate, &sess.recursion_limit, sym::recursion_limit, 64);
+ update_limit(krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
}
-fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: &str, default: usize) {
+fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: Symbol, default: usize) {
for attr in &krate.attrs {
if !attr.check_name(name) {
continue;
use syntax::ast;
use syntax::attr;
use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax_pos::Span;
use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
let result = object_lifetime_defaults_for_item(tcx, generics);
// Debugging aid.
- if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") {
+ if attr::contains_name(&item.attrs, sym::rustc_object_lifetime_default) {
let object_lifetime_default_reprs: String = result
.iter()
.map(|set| match *set {
use crate::ty::query::Providers;
use crate::middle::privacy::AccessLevels;
use crate::session::{DiagnosticMessageId, Session};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::{Span, MultiSpan};
use syntax::ast::Attribute;
use syntax::errors::Applicability;
// Emit errors for non-staged-api crates.
for attr in attrs {
let name = attr.name_or_empty();
- if ["unstable", "stable", "rustc_deprecated"].contains(&name.get()) {
+ if [sym::unstable, sym::stable, sym::rustc_deprecated].contains(&name) {
attr::mark_used(attr);
self.tcx.sess.span_err(attr.span, "stability attributes may not be used \
outside of the standard library");
match stability {
Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
- if span.allows_unstable(&feature.as_str()) {
+ if span.allows_unstable(feature) {
debug!("stability: skipping span={:?} since it is internal", span);
return EvalResult::Allow;
}
// the `-Z force-unstable-if-unmarked` flag present (we're
// compiling a compiler crate), then let this missing feature
// annotation slide.
- if feature == "rustc_private" && issue == 27812 {
+ if feature == sym::rustc_private && issue == 27812 {
if self.sess.opts.debugging_opts.force_unstable_if_unmarked {
return EvalResult::Allow;
}
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id);
if fresh {
- emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span,
+ emit_feature_err(&self.sess.parse_sess, feature, span,
GateIssue::Library(Some(issue)), &msg);
}
}
if adt_def.has_dtor(self.tcx) {
emit_feature_err(&self.tcx.sess.parse_sess,
- "untagged_unions", item.span, GateIssue::Language,
+ sym::untagged_unions, item.span, GateIssue::Language,
"unions with `Drop` implementations are unstable");
} else {
let param_env = self.tcx.param_env(def_id);
if !param_env.can_type_implement_copy(self.tcx, ty).is_ok() {
emit_feature_err(&self.tcx.sess.parse_sess,
- "untagged_unions", item.span, GateIssue::Language,
+ sym::untagged_unions, item.span, GateIssue::Language,
"unions with non-`Copy` fields are unstable");
}
}
use rustc_data_structures::fx::FxHashSet;
use rustc_target::spec::PanicStrategy;
use syntax::ast;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
use crate::hir::def_id::DefId;
use crate::hir::intravisit::{Visitor, NestedVisitorMap};
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
lang_items::extract(attrs).and_then(|(name, _)| {
- $(if name == stringify!($name) {
- Some(Symbol::intern(stringify!($sym)))
+ $(if name == sym::$name {
+ Some(sym::$sym)
} else)* {
None
}
}
Other {
- query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<String>>> {
+ query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<Symbol>>> {
eval_always
desc { "looking up the whitelist of target features" }
}
// another --cfg test
#[test]
fn test_switch_implies_cfg_test_unless_cfg_test() {
+ use syntax::symbol::sym;
syntax::with_globals(|| {
let matches = &match optgroups().parse(&["--test".to_string(),
"--cfg=test".to_string()]) {
let (sessopts, cfg) = build_session_options_and_crate_config(matches);
let sess = build_session(sessopts, None, registry);
let cfg = build_configuration(&sess, to_crate_config(cfg));
- let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test");
+ let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
assert!(test_items.next().is_some());
assert!(test_items.next().is_none());
});
use syntax::json::JsonEmitter;
use syntax::source_map;
use syntax::parse::{self, ParseSess};
+use syntax::symbol::Symbol;
use syntax_pos::{MultiSpan, Span};
use crate::util::profiling::SelfProfiler;
/// in order to avoid redundantly verbose output (Issue #24690, #44953).
pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
- pub plugin_attributes: Lock<Vec<(String, AttributeType)>>,
+ pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
pub crate_types: Once<Vec<config::CrateType>>,
pub dependency_formats: Once<dependency_format::Dependencies>,
/// The crate_disambiguator is constructed out of all the `-C metadata`
//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
-use crate::infer::CombinedSnapshot;
+use crate::infer::{CombinedSnapshot, InferOk};
use crate::hir::def_id::{DefId, LOCAL_CRATE};
-use syntax_pos::DUMMY_SP;
use crate::traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
use crate::traits::IntercrateMode;
use crate::traits::select::IntercrateAmbiguityCause;
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::fold::TypeFoldable;
use crate::ty::subst::Subst;
-
-use crate::infer::{InferOk};
+use syntax::symbol::sym;
+use syntax_pos::DUMMY_SP;
/// Whether we do the orphan check relative to this crate or
/// to some remote crate.
pub fn trait_ref_is_local_or_fundamental<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: ty::TraitRef<'tcx>)
-> bool {
- trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, "fundamental")
+ trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental)
}
pub enum OrphanCheckErr<'tcx> {
use errors::{Applicability, DiagnosticBuilder};
use std::fmt;
use syntax::ast;
+use syntax::symbol::sym;
use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat};
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
return None
};
- if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") {
+ if tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented) {
Some(impl_def_id)
} else {
None
use syntax::ast::{MetaItem, NestedMetaItem};
use syntax::attr;
+use syntax::symbol::sym;
use syntax_pos::Span;
use syntax_pos::symbol::LocalInternedString;
let mut note = None;
let mut subcommands = vec![];
for item in item_iter {
- if item.check_name("message") && message.is_none() {
+ if item.check_name(sym::message) && message.is_none() {
if let Some(message_) = item.value_str() {
message = Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, message_.as_str(), span)?);
continue;
}
- } else if item.check_name("label") && label.is_none() {
+ } else if item.check_name(sym::label) && label.is_none() {
if let Some(label_) = item.value_str() {
label = Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, label_.as_str(), span)?);
continue;
}
- } else if item.check_name("note") && note.is_none() {
+ } else if item.check_name(sym::note) && note.is_none() {
if let Some(note_) = item.value_str() {
note = Some(OnUnimplementedFormatString::try_parse(
tcx, trait_def_id, note_.as_str(), span)?);
continue;
}
- } else if item.check_name("on") && is_root &&
+ } else if item.check_name(sym::on) && is_root &&
message.is_none() && label.is_none() && note.is_none()
{
if let Some(items) = item.meta_item_list() {
{
let attrs = tcx.get_attrs(impl_def_id);
- let attr = if let Some(item) = attr::find_by_name(&attrs, "rustc_on_unimplemented") {
+ let attr = if let Some(item) = attr::find_by_name(&attrs, sym::rustc_on_unimplemented) {
item
} else {
return Ok(None);
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use rustc_macros::HashStable;
use syntax::ast::Ident;
+use syntax::symbol::sym;
use crate::ty::subst::{Subst, InternalSubsts};
use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
use crate::ty::fold::{TypeFoldable, TypeFolder};
gen_sig)
.map_bound(|(trait_ref, yield_ty, return_ty)| {
let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name;
- let ty = if name == "Return" {
+ let ty = if name == sym::Return {
return_ty
- } else if name == "Yield" {
+ } else if name == sym::Yield {
yield_ty
} else {
bug!()
use syntax::attr;
use syntax::source_map::MultiSpan;
use syntax::feature_gate;
-use syntax::symbol::{Symbol, keywords, InternedString};
+use syntax::symbol::{Symbol, keywords, InternedString, sym};
use syntax_pos::Span;
use crate::hir;
}
span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute");
};
- (get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end"))
+ (get(sym::rustc_layout_scalar_valid_range_start),
+ get(sym::rustc_layout_scalar_valid_range_end))
}
pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
};
providers.is_panic_runtime = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
- attr::contains_name(tcx.hir().krate_attrs(), "panic_runtime")
+ attr::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(), "compiler_builtins")
+ attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
};
}
use syntax::ast::{self, Name, Ident, NodeId};
use syntax::attr;
use syntax::ext::hygiene::Mark;
-use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
+use syntax::symbol::{keywords, sym, Symbol, LocalInternedString, InternedString};
use syntax_pos::Span;
use smallvec;
);
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
- if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, "non_exhaustive") {
+ if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) {
debug!("found non-exhaustive field list for {:?}", parent_did);
flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
} else if let Some(variant_did) = variant_did {
- if tcx.has_attr(variant_did, "non_exhaustive") {
+ if tcx.has_attr(variant_did, sym::non_exhaustive) {
debug!("found non-exhaustive field list for {:?}", variant_did);
flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
}
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
let mut flags = AdtFlags::NO_ADT_FLAGS;
- if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") {
+ if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
debug!("found non-exhaustive variant list for {:?}", did);
flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
}
}
let attrs = tcx.get_attrs(did);
- if attr::contains_name(&attrs, "fundamental") {
+ if attr::contains_name(&attrs, sym::fundamental) {
flags |= AdtFlags::IS_FUNDAMENTAL;
}
if Some(did) == tcx.lang_items().phantom_data() {
}
/// Determines whether an item is annotated with an attribute.
- pub fn has_attr(self, did: DefId, attr: &str) -> bool {
+ pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
attr::contains_name(&self.get_attrs(did), attr)
}
use std::{cmp, fmt};
use syntax::ast;
use syntax::attr::{self, SignedInt, UnsignedInt};
+use syntax::symbol::sym;
use syntax_pos::{Span, DUMMY_SP};
#[derive(Copy, Clone, Debug)]
// Such access can be in plain sight (e.g., dereferencing
// `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden
// (e.g., calling `foo.0.clone()` of `Foo<T:Clone>`).
- if self.has_attr(dtor, "unsafe_destructor_blind_to_params") {
+ if self.has_attr(dtor, sym::unsafe_destructor_blind_to_params) {
debug!("destructor_constraint({:?}) - blind", def.did);
return vec![];
}
mut_visit::{self, MutVisitor},
parse::ParseSess,
ptr::P,
- symbol::Symbol
+ symbol::{Symbol, sym}
};
use syntax_pos::Span;
fn flat_map_item(&mut self, item: P<Item>) -> SmallVec<[P<Item>; 1]> {
debug!("in submodule {}", self.in_submod);
- let name = if attr::contains_name(&item.attrs, "global_allocator") {
+ let name = if attr::contains_name(&item.attrs, sym::global_allocator) {
"global_allocator"
} else {
return mut_visit::noop_flat_map_item(item, self);
// rustdoc needs to be able to document functions that use all the features, so
// whitelist them all
Lrc::new(llvm_util::all_known_features()
- .map(|(a, b)| (a.to_string(), b.map(|s| s.to_string())))
+ .map(|(a, b)| (a.to_string(), b))
.collect())
} else {
Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
.iter()
- .map(|&(a, b)| (a.to_string(), b.map(|s| s.to_string())))
+ .map(|&(a, b)| (a.to_string(), b))
.collect())
}
};
use rustc::hir::Node;
use syntax_pos::Span;
use rustc_target::abi::HasDataLayout;
+use syntax::symbol::sym;
use syntax_pos::symbol::LocalInternedString;
use rustc::ty::{self, Ty};
use rustc_codegen_ssa::traits::*;
debug!("get_static: sym={} attrs={:?}", sym, attrs);
for attr in attrs {
- if attr.check_name("thread_local") {
+ if attr.check_name(sym::thread_local) {
llvm::set_thread_local_mode(g, self.tls_model);
}
}
use rustc_codegen_ssa::traits::*;
use syntax::attr;
+use syntax::symbol::sym;
/// Inserts a side-effect free instruction sequence that makes sure that the
pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
let omit_gdb_pretty_printer_section =
- attr::contains_name(&cx.tcx.hir().krate_attrs(),
- "omit_gdb_pretty_printer_section");
+ attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
!omit_gdb_pretty_printer_section &&
cx.sess().opts.debuginfo != DebugInfo::None &&
use libc::c_int;
use std::ffi::CString;
use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::sym;
use std::str;
use std::slice;
// to LLVM or the feature detection code will walk past the end of the feature
// array, leading to crashes.
-const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
- ("aclass", Some("arm_target_feature")),
- ("mclass", Some("arm_target_feature")),
- ("rclass", Some("arm_target_feature")),
- ("dsp", Some("arm_target_feature")),
- ("neon", Some("arm_target_feature")),
- ("v5te", Some("arm_target_feature")),
- ("v6", Some("arm_target_feature")),
- ("v6k", Some("arm_target_feature")),
- ("v6t2", Some("arm_target_feature")),
- ("v7", Some("arm_target_feature")),
- ("v8", Some("arm_target_feature")),
- ("vfp2", Some("arm_target_feature")),
- ("vfp3", Some("arm_target_feature")),
- ("vfp4", Some("arm_target_feature")),
+const ARM_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("aclass", Some(sym::arm_target_feature)),
+ ("mclass", Some(sym::arm_target_feature)),
+ ("rclass", Some(sym::arm_target_feature)),
+ ("dsp", Some(sym::arm_target_feature)),
+ ("neon", Some(sym::arm_target_feature)),
+ ("v5te", Some(sym::arm_target_feature)),
+ ("v6", Some(sym::arm_target_feature)),
+ ("v6k", Some(sym::arm_target_feature)),
+ ("v6t2", Some(sym::arm_target_feature)),
+ ("v7", Some(sym::arm_target_feature)),
+ ("v8", Some(sym::arm_target_feature)),
+ ("vfp2", Some(sym::arm_target_feature)),
+ ("vfp3", Some(sym::arm_target_feature)),
+ ("vfp4", Some(sym::arm_target_feature)),
];
-const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[
- ("fp", Some("aarch64_target_feature")),
- ("neon", Some("aarch64_target_feature")),
- ("sve", Some("aarch64_target_feature")),
- ("crc", Some("aarch64_target_feature")),
- ("crypto", Some("aarch64_target_feature")),
- ("ras", Some("aarch64_target_feature")),
- ("lse", Some("aarch64_target_feature")),
- ("rdm", Some("aarch64_target_feature")),
- ("fp16", Some("aarch64_target_feature")),
- ("rcpc", Some("aarch64_target_feature")),
- ("dotprod", Some("aarch64_target_feature")),
- ("v8.1a", Some("aarch64_target_feature")),
- ("v8.2a", Some("aarch64_target_feature")),
- ("v8.3a", Some("aarch64_target_feature")),
+const AARCH64_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("fp", Some(sym::aarch64_target_feature)),
+ ("neon", Some(sym::aarch64_target_feature)),
+ ("sve", Some(sym::aarch64_target_feature)),
+ ("crc", Some(sym::aarch64_target_feature)),
+ ("crypto", Some(sym::aarch64_target_feature)),
+ ("ras", Some(sym::aarch64_target_feature)),
+ ("lse", Some(sym::aarch64_target_feature)),
+ ("rdm", Some(sym::aarch64_target_feature)),
+ ("fp16", Some(sym::aarch64_target_feature)),
+ ("rcpc", Some(sym::aarch64_target_feature)),
+ ("dotprod", Some(sym::aarch64_target_feature)),
+ ("v8.1a", Some(sym::aarch64_target_feature)),
+ ("v8.2a", Some(sym::aarch64_target_feature)),
+ ("v8.3a", Some(sym::aarch64_target_feature)),
];
-const X86_WHITELIST: &[(&str, Option<&str>)] = &[
- ("adx", Some("adx_target_feature")),
+const X86_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("adx", Some(sym::adx_target_feature)),
("aes", None),
("avx", None),
("avx2", None),
- ("avx512bw", Some("avx512_target_feature")),
- ("avx512cd", Some("avx512_target_feature")),
- ("avx512dq", Some("avx512_target_feature")),
- ("avx512er", Some("avx512_target_feature")),
- ("avx512f", Some("avx512_target_feature")),
- ("avx512ifma", Some("avx512_target_feature")),
- ("avx512pf", Some("avx512_target_feature")),
- ("avx512vbmi", Some("avx512_target_feature")),
- ("avx512vl", Some("avx512_target_feature")),
- ("avx512vpopcntdq", Some("avx512_target_feature")),
+ ("avx512bw", Some(sym::avx512_target_feature)),
+ ("avx512cd", Some(sym::avx512_target_feature)),
+ ("avx512dq", Some(sym::avx512_target_feature)),
+ ("avx512er", Some(sym::avx512_target_feature)),
+ ("avx512f", Some(sym::avx512_target_feature)),
+ ("avx512ifma", Some(sym::avx512_target_feature)),
+ ("avx512pf", Some(sym::avx512_target_feature)),
+ ("avx512vbmi", Some(sym::avx512_target_feature)),
+ ("avx512vl", Some(sym::avx512_target_feature)),
+ ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
("bmi1", None),
("bmi2", None),
- ("cmpxchg16b", Some("cmpxchg16b_target_feature")),
- ("f16c", Some("f16c_target_feature")),
+ ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
+ ("f16c", Some(sym::f16c_target_feature)),
("fma", None),
("fxsr", None),
("lzcnt", None),
- ("mmx", Some("mmx_target_feature")),
- ("movbe", Some("movbe_target_feature")),
+ ("mmx", Some(sym::mmx_target_feature)),
+ ("movbe", Some(sym::movbe_target_feature)),
("pclmulqdq", None),
("popcnt", None),
("rdrand", None),
("rdseed", None),
- ("rtm", Some("rtm_target_feature")),
+ ("rtm", Some(sym::rtm_target_feature)),
("sha", None),
("sse", None),
("sse2", None),
("sse3", None),
("sse4.1", None),
("sse4.2", None),
- ("sse4a", Some("sse4a_target_feature")),
+ ("sse4a", Some(sym::sse4a_target_feature)),
("ssse3", None),
- ("tbm", Some("tbm_target_feature")),
+ ("tbm", Some(sym::tbm_target_feature)),
("xsave", None),
("xsavec", None),
("xsaveopt", None),
("xsaves", None),
];
-const HEXAGON_WHITELIST: &[(&str, Option<&str>)] = &[
- ("hvx", Some("hexagon_target_feature")),
- ("hvx-double", Some("hexagon_target_feature")),
+const HEXAGON_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("hvx", Some(sym::hexagon_target_feature)),
+ ("hvx-double", Some(sym::hexagon_target_feature)),
];
-const POWERPC_WHITELIST: &[(&str, Option<&str>)] = &[
- ("altivec", Some("powerpc_target_feature")),
- ("power8-altivec", Some("powerpc_target_feature")),
- ("power9-altivec", Some("powerpc_target_feature")),
- ("power8-vector", Some("powerpc_target_feature")),
- ("power9-vector", Some("powerpc_target_feature")),
- ("vsx", Some("powerpc_target_feature")),
+const POWERPC_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("altivec", Some(sym::powerpc_target_feature)),
+ ("power8-altivec", Some(sym::powerpc_target_feature)),
+ ("power9-altivec", Some(sym::powerpc_target_feature)),
+ ("power8-vector", Some(sym::powerpc_target_feature)),
+ ("power9-vector", Some(sym::powerpc_target_feature)),
+ ("vsx", Some(sym::powerpc_target_feature)),
];
-const MIPS_WHITELIST: &[(&str, Option<&str>)] = &[
- ("fp64", Some("mips_target_feature")),
- ("msa", Some("mips_target_feature")),
+const MIPS_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("fp64", Some(sym::mips_target_feature)),
+ ("msa", Some(sym::mips_target_feature)),
];
-const WASM_WHITELIST: &[(&str, Option<&str>)] = &[
- ("simd128", Some("wasm_target_feature")),
- ("atomics", Some("wasm_target_feature")),
+const WASM_WHITELIST: &[(&str, Option<Symbol>)] = &[
+ ("simd128", Some(sym::wasm_target_feature)),
+ ("atomics", Some(sym::wasm_target_feature)),
];
/// When rustdoc is running, provide a list of all known features so that all their respective
///
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
/// iterator!
-pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<&'static str>)> {
+pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<Symbol>)> {
ARM_WHITELIST.iter().cloned()
.chain(AARCH64_WHITELIST.iter().cloned())
.chain(X86_WHITELIST.iter().cloned())
}
pub fn target_feature_whitelist(sess: &Session)
- -> &'static [(&'static str, Option<&'static str>)]
+ -> &'static [(&'static str, Option<Symbol>)]
{
match &*sess.target.target.arch {
"arm" => ARM_WHITELIST,
use syntax::attr;
use syntax::ext::hygiene::Mark;
use syntax_pos::MultiSpan;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{Symbol, sym};
use jobserver::{Client, Acquired};
use std::any::Any;
let sess = tcx.sess;
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().attrs, "no_builtins");
+ let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, sym::no_builtins);
let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs,
- "windows_subsystem");
+ sym::windows_subsystem);
let windows_subsystem = subsystem.map(|subsystem| {
- if subsystem != "windows" && subsystem != "console" {
+ if subsystem != sym::windows && subsystem != sym::console {
tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \
`windows` and `console` are allowed",
subsystem));
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
use rustc_apfloat::{ieee, Float, Status, Round};
use std::{u128, i128};
+use syntax::symbol::sym;
use crate::base;
use crate::MemFlags;
mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
match operand.layout.ty.sty {
ty::FnDef(def_id, substs) => {
- if bx.cx().tcx().has_attr(def_id, "rustc_args_required_const") {
- bug!("reifying a fn ptr that requires \
- const arguments");
+ if bx.cx().tcx().has_attr(def_id, sym::rustc_args_required_const) {
+ bug!("reifying a fn ptr that requires const arguments");
}
OperandValue::Immediate(
callee::resolve_and_get_fn(bx.cx(), def_id, substs))
use rustc::ty::TyCtxt;
use rustc::hir::def_id::LOCAL_CRATE;
+use syntax::symbol::sym;
pub mod link;
pub mod codegen_backend;
/// reporting an error.
pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_, '_, '_>) {
if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
- if tcx.has_attr(def_id, "rustc_error") {
+ if tcx.has_attr(def_id, sym::rustc_error) {
tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
}
}
use rustc::session::Session;
use std::path::{Path, PathBuf};
use syntax::{ast, attr};
+use syntax::symbol::sym;
use syntax_pos::Span;
pub fn out_filename(sess: &Session,
// as used. After doing this, however, we still prioritize a crate name from
// 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, "crate_name")
+ let attr_crate_name = attr::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 != &**s {
+ if name.as_str() != *s {
let msg = format!("--crate-name and #[crate_name] are \
required to match, but `{}` != `{}`",
s, name);
use rustc::hir;
use rustc::ty::TyCtxt;
-
use rustc_mir::monomorphize::Instance;
+use syntax::symbol::{Symbol, sym};
-const SYMBOL_NAME: &'static str = "rustc_symbol_name";
-const DEF_PATH: &'static str = "rustc_def_path";
+const SYMBOL_NAME: Symbol = sym::rustc_symbol_name;
+const DEF_PATH: Symbol = sym::rustc_def_path;
pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
// if the `rustc_attrs` feature is not enabled, then the
use syntax::source_map::FileLoader;
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
use syntax::parse::{self, PResult};
+use syntax::symbol::sym;
use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
pub mod pretty;
// through to build scripts.
let value = value.as_ref().map(|s| s.as_str());
let value = value.as_ref().map(|s| s.as_ref());
- if name != "target_feature" || value != Some("crt-static") {
+ if name != sym::target_feature || value != Some("crt-static") {
if !allow_unstable_cfg && gated_cfg.is_some() {
return None
}
use rustc::ty::TyCtxt;
use std::collections::BTreeSet;
use syntax::ast;
+use syntax::symbol::{Symbol, sym};
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
ATTR_EXPECTED_CGU_REUSE};
-const MODULE: &str = "module";
-const CFG: &str = "cfg";
-const KIND: &str = "kind";
+const MODULE: Symbol = sym::module;
+const CFG: Symbol = sym::cfg;
+const KIND: Symbol = sym::kind;
pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.dep_graph.with_ignore(|| {
comp_kind);
}
- fn field(&self, attr: &ast::Attribute, name: &str) -> ast::Name {
+ fn field(&self, attr: &ast::Attribute, name: Symbol) -> ast::Name {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
if item.check_name(name) {
if let Some(value) = item.value_str() {
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::intravisit;
use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
-use syntax::ast::{self, Attribute, NestedMetaItem};
+use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashSet;
+use syntax::ast::{self, Attribute, NestedMetaItem};
+use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
-use rustc::ty::TyCtxt;
-const EXCEPT: &str = "except";
-const LABEL: &str = "label";
-const CFG: &str = "cfg";
+const EXCEPT: Symbol = sym::except;
+const LABEL: Symbol = sym::label;
+const CFG: Symbol = sym::cfg;
// Base and Extra labels to build up the labels
// nodes.
pub struct FindAllAttrs<'a, 'tcx:'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- attr_names: Vec<&'static str>,
+ attr_names: Vec<Symbol>,
found_attrs: Vec<&'tcx Attribute>,
}
pub struct PluginInfo {
syntax_exts: Vec<NamedSyntaxExtension>,
- attributes: Vec<(String, AttributeType)>,
+ attributes: Vec<(Symbol, AttributeType)>,
}
pub fn register_plugins<'a>(
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use syntax::attr;
+use syntax::symbol::sym;
pub fn find<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Option<DefId> {
tcx.proc_macro_decls_static(LOCAL_CRATE)
impl<'v> ItemLikeVisitor<'v> for Finder {
fn visit_item(&mut self, item: &hir::Item) {
- if attr::contains_name(&item.attrs, "rustc_proc_macro_decls") {
+ if attr::contains_name(&item.attrs, sym::rustc_proc_macro_decls) {
self.decls = Some(item.hir_id);
}
}
use syntax::ast::BlockCheckMode;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::source_map::{FileLoader, RealFileLoader, SourceMap};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::{self, ast, attr};
#[cfg(not(parallel_compiler))]
use std::{thread, panic};
let attr_types: Vec<config::CrateType> = attrs
.iter()
.filter_map(|a| {
- if a.check_name("crate_type") {
+ if a.check_name(sym::crate_type) {
match a.value_str() {
- Some(ref n) if *n == "rlib" => Some(config::CrateType::Rlib),
- Some(ref n) if *n == "dylib" => Some(config::CrateType::Dylib),
- Some(ref n) if *n == "cdylib" => Some(config::CrateType::Cdylib),
- Some(ref n) if *n == "lib" => Some(config::default_lib_output()),
- Some(ref n) if *n == "staticlib" => Some(config::CrateType::Staticlib),
- Some(ref n) if *n == "proc-macro" => Some(config::CrateType::ProcMacro),
- Some(ref n) if *n == "bin" => Some(config::CrateType::Executable),
- Some(ref n) => {
+ Some(sym::rlib) => Some(config::CrateType::Rlib),
+ Some(sym::dylib) => Some(config::CrateType::Dylib),
+ Some(sym::cdylib) => Some(config::CrateType::Cdylib),
+ Some(sym::lib) => Some(config::default_lib_output()),
+ Some(sym::staticlib) => Some(config::CrateType::Staticlib),
+ Some(sym::proc_dash_macro) => Some(config::CrateType::ProcMacro),
+ Some(sym::bin) => Some(config::CrateType::Executable),
+ Some(n) => {
let crate_types = vec![
- Symbol::intern("rlib"),
- Symbol::intern("dylib"),
- Symbol::intern("cdylib"),
- Symbol::intern("lib"),
- Symbol::intern("staticlib"),
- Symbol::intern("proc-macro"),
- Symbol::intern("bin")
+ sym::rlib,
+ sym::dylib,
+ sym::cdylib,
+ sym::lib,
+ sym::staticlib,
+ sym::proc_dash_macro,
+ sym::bin
];
if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node {
use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
use syntax::feature_gate::{Stability, deprecated_attributes};
use syntax_pos::{BytePos, Span, SyntaxContext};
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
use syntax::errors::{Applicability, DiagnosticBuilder};
use syntax::print::pprust::expr_to_string;
use syntax::visit::FnKind;
impl EarlyLintPass for UnsafeCode {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
- if attr.check_name("allow_internal_unsafe") {
+ if attr.check_name(sym::allow_internal_unsafe) {
self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
macros using unsafe without triggering \
the `unsafe_code` lint at their call site");
impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
fn has_doc(attr: &ast::Attribute) -> bool {
- if !attr.check_name("doc") {
+ if !attr.check_name(sym::doc) {
return false;
}
if let Some(list) = attr.meta_item_list() {
for meta in list {
- if meta.check_name("include") || meta.check_name("hidden") {
+ if meta.check_name(sym::include) || meta.check_name(sym::hidden) {
return true;
}
}
fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) {
let doc_hidden = self.doc_hidden() ||
attrs.iter().any(|attr| {
- attr.check_name("doc") &&
+ attr.check_name(sym::doc) &&
match attr.meta_item_list() {
None => false,
- Some(l) => attr::list_contains_name(&l, "hidden"),
+ Some(l) => attr::list_contains_name(&l, sym::hidden),
}
});
self.doc_hidden_stack.push(doc_hidden);
let span = sugared_span.take().unwrap_or_else(|| attr.span);
- if attr.check_name("doc") {
+ if attr.check_name(sym::doc) {
let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");
err.span_label(
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
hir::ItemKind::Fn(.., ref generics, _) => {
- if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") {
+ if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
}
}
hir::ItemKind::Const(..) => {
- if attr::contains_name(&it.attrs, "no_mangle") {
+ if attr::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
let msg = "const items should never be #[no_mangle]";
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) {
- if attr.check_name("feature") {
+ if attr.check_name(sym::feature) {
if let Some(items) = attr.meta_item_list() {
for item in items {
ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature");
return;
}
- if let Some(attr) = attr::find_by_name(&it.attrs, "rustc_test_marker") {
+ if let Some(attr) = attr::find_by_name(&it.attrs, sym::rustc_test_marker) {
cx.struct_span_lint(
UNNAMEABLE_TEST_ITEMS,
attr.span,
use syntax::ast;
use syntax::attr;
use syntax::errors::Applicability;
+use syntax::symbol::sym;
use syntax_pos::{BytePos, symbol::Ident, Span};
#[derive(PartialEq)]
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_by_hir_id(hir::CRATE_HIR_ID), "crate_name")
+ attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), sym::crate_name)
.and_then(|attr| attr.meta())
.and_then(|meta| {
meta.name_value_literal().and_then(|lit| {
}
FnKind::ItemFn(ident, _, header, _, attrs) => {
// Skip foreign-ABI #[no_mangle] functions (Issue #31924)
- if header.abi != Abi::Rust && attr::contains_name(attrs, "no_mangle") {
+ if header.abi != Abi::Rust && attr::contains_name(attrs, sym::no_mangle) {
return;
}
self.check_snake_case(cx, "function", ident);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
- hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => {
+ hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, sym::no_mangle) => {
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
}
hir::ItemKind::Const(..) => {
use syntax::errors::Applicability;
use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
use syntax::print::pprust;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax::symbol::Symbol;
use syntax::util::parser;
use syntax_pos::Span;
descr_post_path: &str,
) -> bool {
for attr in cx.tcx.get_attrs(def_id).iter() {
- if attr.check_name("must_use") {
+ if attr.check_name(sym::must_use) {
let msg = format!("unused {}`{}`{} that must be used",
descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path);
let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg);
}
let plugin_attributes = cx.sess().plugin_attributes.borrow_mut();
- for &(ref name, ty) in plugin_attributes.iter() {
- if ty == AttributeType::Whitelisted && attr.check_name(&**name) {
+ for &(name, ty) in plugin_attributes.iter() {
+ if ty == AttributeType::Whitelisted && attr.check_name(name) {
debug!("{:?} (plugin attr) is whitelisted with ty {:?}", name, ty);
break;
}
// Has a plugin registered this attribute as one that must be used at
// the crate level?
let plugin_crate = plugin_attributes.iter()
- .find(|&&(ref x, t)| name == x.as_str() && AttributeType::CrateLevel == t)
+ .find(|&&(x, t)| name == x && AttributeType::CrateLevel == t)
.is_some();
if known_crate || plugin_crate {
let msg = match attr.style {
#[allow(non_camel_case_types)]
mod kw {
syn::custom_keyword!(Keywords);
- syn::custom_keyword!(Other);
+ syn::custom_keyword!(Symbols);
}
struct Keyword {
}
}
-struct Symbol(Ident);
+struct Symbol {
+ name: Ident,
+ value: Option<LitStr>,
+}
impl Parse for Symbol {
fn parse(input: ParseStream<'_>) -> Result<Self> {
- let ident: Ident = input.parse()?;
+ let name = input.parse()?;
+ let value = match input.parse::<Token![:]>() {
+ Ok(_) => Some(input.parse()?),
+ Err(_) => None,
+ };
input.parse::<Token![,]>()?;
- Ok(Symbol(ident))
+ Ok(Symbol {
+ name,
+ value,
+ })
}
}
braced!(content in input);
let keywords = content.parse()?;
- input.parse::<kw::Other>()?;
+ input.parse::<kw::Symbols>()?;
let content;
braced!(content in input);
let symbols = content.parse()?;
}
for symbol in &input.symbols.0 {
- let value = &symbol.0;
- let value_str = value.to_string();
- check_dup(&value_str);
+ let name = &symbol.name;
+ let value = match &symbol.value {
+ Some(value) => value.value(),
+ None => name.to_string(),
+ };
+ check_dup(&value);
prefill_stream.extend(quote! {
- #value_str,
+ #value,
});
symbols_stream.extend(quote! {
- pub const #value: Symbol = Symbol::new(#counter);
+ pub const #name: Symbol = Symbol::new(#counter);
});
counter += 1;
}
- TokenStream::from(quote! {
+ let tt = TokenStream::from(quote! {
macro_rules! keywords {
() => {
#keyword_stream
])
}
}
- })
+ });
+
+ // To see the generated code generated, uncomment this line, recompile, and
+ // run the resulting output through `rustfmt`.
+ //eprintln!("{}", tt);
+
+ tt
}
use syntax::ast;
use syntax::attr;
use syntax::ext::base::SyntaxExtension;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::visit;
use syntax::{span_err, span_fatal};
use syntax_pos::{Span, DUMMY_SP};
/// SVH and DefIndex of the registrar function.
pub fn find_plugin_registrar(&mut self,
span: Span,
- name: &str)
+ name: Symbol)
-> Option<(PathBuf, CrateDisambiguator)> {
- let name = Symbol::intern(name);
let ekrate = self.read_extension_crate(span, name, name);
if ekrate.target_only {
let desired_strategy = self.sess.panic_strategy();
let mut runtime_found = false;
let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
- "needs_panic_runtime");
+ sym::needs_panic_runtime);
self.cstore.iter_crate_data(|cnum, data| {
needs_panic_runtime = needs_panic_runtime ||
let mut uses_std = false;
self.cstore.iter_crate_data(|_, data| {
- if data.name == "std" {
+ if data.name == sym::std {
uses_std = true;
}
});
// about through the `#![needs_allocator]` attribute and is typically
// written down in liballoc.
let mut needs_allocator = attr::contains_name(&krate.attrs,
- "needs_allocator");
+ sym::needs_allocator);
self.cstore.iter_crate_data(|_, data| {
needs_allocator = needs_allocator || data.root.needs_allocator;
});
// 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, "default_lib_allocator");
+ let mut has_default = attr::contains_name(&krate.attrs, sym::default_lib_allocator);
self.cstore.iter_crate_data(|_, data| {
if data.root.has_default_lib_allocator {
has_default = true;
impl<'ast> visit::Visitor<'ast> for Finder {
fn visit_item(&mut self, i: &'ast ast::Item) {
- if attr::contains_name(&i.attrs, "global_allocator") {
+ if attr::contains_name(&i.attrs, sym::global_allocator) {
self.0 = true;
}
visit::walk_item(self, i)
}
None => item.ident.name,
};
- let dep_kind = if attr::contains_name(&item.attrs, "no_link") {
+ let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
DepKind::UnexportedMacrosOnly
} else {
DepKind::Explicit
use syntax::edition::Edition;
use syntax::parse::source_file_to_stream;
use syntax::parse::parser::emit_unclosed_delims;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::{Span, NO_EXPANSION, FileName};
use rustc_data_structures::bit_set::BitSet;
let data = self.get_crate_data(id.krate);
if let Some(ref proc_macros) = data.proc_macros {
return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
- } else if data.name == "proc_macro" && data.item_name(id.index) == "quote" {
+ } else if data.name == sym::proc_macro && data.item_name(id.index) == "quote" {
use syntax::ext::base::SyntaxExtension;
use syntax_ext::proc_macro_impl::BangProcMacro;
use syntax::attr;
use syntax::ast::{self, Ident};
use syntax::source_map;
-use syntax::symbol::InternedString;
+use syntax::symbol::{InternedString, sym};
use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::hygiene::Mark;
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
// 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, "non_exhaustive") {
+ if attr::contains_name(&attrs, sym::non_exhaustive) {
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
vis = ty::Visibility::Restricted(crate_def_id);
}
use syntax::ast;
use syntax::attr;
use syntax::source_map::Spanned;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax_pos::{self, hygiene, FileName, SourceFile, Span};
use log::{debug, trace};
let attrs = tcx.hir().krate_attrs();
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
- let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator");
+ let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
let has_global_allocator = *tcx.sess.has_global_allocator.get();
let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
} else {
None
},
- compiler_builtins: attr::contains_name(&attrs, "compiler_builtins"),
- needs_allocator: attr::contains_name(&attrs, "needs_allocator"),
- needs_panic_runtime: attr::contains_name(&attrs, "needs_panic_runtime"),
- no_builtins: attr::contains_name(&attrs, "no_builtins"),
- panic_runtime: attr::contains_name(&attrs, "panic_runtime"),
- profiler_runtime: attr::contains_name(&attrs, "profiler_runtime"),
- sanitizer_runtime: attr::contains_name(&attrs, "sanitizer_runtime"),
+ 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),
+ sanitizer_runtime: attr::contains_name(&attrs, sym::sanitizer_runtime),
crate_deps,
dylib_dependency_formats,
use rustc::hir;
use rustc::ty::TyCtxt;
use rustc_target::spec::abi::Abi;
+use syntax::symbol::sym;
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<String> {
let mut collector = Collector {
tcx.hir().krate().visit_all_item_likes(&mut collector);
for attr in tcx.hir().krate().attrs.iter() {
- if attr.path == "link_args" {
+ if attr.path == sym::link_args {
if let Some(linkarg) = attr.value_str() {
collector.add_link_args(&linkarg.as_str());
}
}
// First, add all of the custom #[link_args] attributes
- for m in it.attrs.iter().filter(|a| a.check_name("link_args")) {
+ for m in it.attrs.iter().filter(|a| a.check_name(sym::link_args)) {
if let Some(linkarg) = m.value_str() {
self.add_link_args(&linkarg.as_str());
}
use rustc::util::nodemap::FxHashMap;
use errors::DiagnosticBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::struct_span_err;
use syntax_pos::Span;
use rustc_target::spec::{Target, TargetTriple};
self.ident,
add);
- if (self.ident == "std" || self.ident == "core")
+ if (self.ident == sym::std || self.ident == sym::core)
&& self.triple != TargetTriple::from_triple(config::host_triple()) {
err.note(&format!("the `{}` target may not be installed", self.triple));
}
use syntax::attr;
use syntax::source_map::Span;
use syntax::feature_gate::{self, GateIssue};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::{span_err, struct_span_err};
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<NativeLibrary> {
}
// Process all of the #[link(..)]-style arguments
- for m in it.attrs.iter().filter(|a| a.check_name("link")) {
+ for m in it.attrs.iter().filter(|a| a.check_name(sym::link)) {
let items = match m.meta_item_list() {
Some(item) => item,
None => continue,
let mut kind_specified = false;
for item in items.iter() {
- if item.check_name("kind") {
+ if item.check_name(sym::kind) {
kind_specified = true;
let kind = match item.value_str() {
Some(name) => name,
cstore::NativeUnknown
}
};
- } else if item.check_name("name") {
+ } else if item.check_name(sym::name) {
lib.name = item.value_str();
- } else if item.check_name("cfg") {
+ } else if item.check_name(sym::cfg) {
let cfg = match item.meta_item_list() {
Some(list) => list,
None => continue, // skip like historical compilers
} else {
self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
}
- } else if item.check_name("wasm_import_module") {
+ } else if item.check_name(sym::wasm_import_module) {
match item.value_str() {
Some(s) => lib.wasm_import_module = Some(s),
None => {
}
if lib.cfg.is_some() && !self.tcx.features().link_cfg {
feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
- "link_cfg",
+ sym::link_cfg,
span.unwrap(),
GateIssue::Language,
"is feature gated");
if lib.kind == cstore::NativeStaticNobundle &&
!self.tcx.features().static_nobundle {
feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
- "static_nobundle",
+ sym::static_nobundle,
span.unwrap_or_else(|| syntax_pos::DUMMY_SP),
GateIssue::Language,
"kind=\"static-nobundle\" is feature gated");
let any_duplicate = self.libs
.iter()
.filter_map(|lib| lib.name.as_ref())
- .any(|n| n == name);
+ .any(|n| n.as_str() == *name);
if new_name.is_empty() {
self.tcx.sess.err(
&format!("an empty renaming target was specified for library `{}`",name));
// can move them to the end of the list below.
let mut existing = self.libs.drain_filter(|lib| {
if let Some(lib_name) = lib.name {
- if lib_name == name as &str {
+ if lib_name.as_str() == *name {
if let Some(k) = kind {
lib.kind = k;
}
use rustc_errors::{Applicability, DiagnosticBuilder};
use syntax_pos::Span;
use syntax::source_map::CompilerDesugaringKind;
+use syntax::symbol::sym;
use super::borrow_set::BorrowData;
use super::{MirBorrowckCtxt};
PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })
) = place {
let attrs = self.infcx.tcx.get_attrs(*def_id);
- let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
+ let is_thread_local = attrs.iter().any(|attr| attr.check_name(sym::thread_local));
debug!(
"is_place_thread_local: attrs={:?} is_thread_local={:?}",
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
+use syntax::symbol::sym;
use self::mir_util::PassWhere;
use polonius_engine::{Algorithm, Output};
) {
let tcx = infcx.tcx;
let base_def_id = tcx.closure_base_def_id(mir_def_id);
- if !tcx.has_attr(base_def_id, "rustc_regions") {
+ if !tcx.has_attr(base_def_id, sym::rustc_regions) {
return;
}
use syntax::ast::{self, MetaItem};
+use syntax::symbol::{Symbol, sym};
use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet};
use rustc_data_structures::indexed_vec::Idx;
fn propagate(&mut self) { self.flow_state.propagate(); }
}
-pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
+pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option<MetaItem> {
for attr in attrs {
- if attr.check_name("rustc_mir") {
+ if attr.check_name(sym::rustc_mir) {
let items = attr.meta_item_list();
for item in items.iter().flat_map(|l| l.iter()) {
match item.meta_item() {
return None;
};
- let print_preflow_to =
- name_found(tcx.sess, attributes, "borrowck_graphviz_preflow");
- let print_postflow_to =
- name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");
+ let print_preflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_preflow);
+ let print_postflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_postflow);
let mut mbcx = DataflowBuilder {
def_id,
use rustc::ty::layout::VariantIdx;
use syntax::ast;
use syntax::attr;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use rustc::hir;
use crate::hair::constant::{lit_to_const, LitToConstError};
// 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, "rustc_inherit_overflow_checks");
+ let mut check_overflow = attr::contains_name(attrs, sym::rustc_inherit_overflow_checks);
// Respect -C overflow-checks.
check_overflow |= tcx.sess.overflow_checks();
use std::fmt;
use syntax::ast;
use syntax::ptr::P;
+use syntax::symbol::sym;
use syntax_pos::Span;
#[derive(Clone, Debug)]
self.tcx.sess.span_err(span, "cannot use unions in constant patterns");
PatternKind::Wild
}
- ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+ ty::Adt(adt_def, _) if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
let path = self.tcx.def_path_str(adt_def.did);
let msg = format!(
"to use a constant of type `{}` in a pattern, \
PatternKind::Wild
}
ty::Ref(_, ty::TyS { sty: ty::Adt(adt_def, _), .. }, _)
- if !self.tcx.has_attr(adt_def.did, "structural_match") => {
+ if !self.tcx.has_attr(adt_def.did, sym::structural_match) => {
// HACK(estebank): Side-step ICE #53708, but anything other than erroring here
// would be wrong. Returnging `PatternKind::Wild` is not technically correct.
let path = self.tcx.def_path_str(adt_def.did);
use rustc::ty::layout::{self, TyLayout, Size};
use rustc::ty::adjustment::{PointerCast};
use syntax::ast::{FloatTy, IntTy, UintTy};
+use syntax::symbol::sym;
use rustc_apfloat::ieee::{Single, Double};
use rustc::mir::interpret::{
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::FnDef(def_id, substs) => {
- if self.tcx.has_attr(def_id, "rustc_args_required_const") {
- bug!("reifying a fn ptr that requires \
- const arguments");
+ if self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
+ bug!("reifying a fn ptr that requires const arguments");
}
let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
*self.tcx,
use rustc::mir::*;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use std::ops::Bound;
fn builtin_derive_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId> {
debug!("builtin_derive_def_id({:?})", def_id);
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
- if tcx.has_attr(impl_def_id, "automatically_derived") {
+ if tcx.has_attr(impl_def_id, sym::automatically_derived) {
debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id);
Some(impl_def_id)
} else {
use rustc::session::config::nightly_options;
use syntax::ast::LitKind;
use syntax::feature_gate::{emit_feature_err, GateIssue};
+use syntax::symbol::sym;
use syntax_pos::{Span, DUMMY_SP};
use std::fmt;
!allowed ||
cx.tcx.get_attrs(def_id).iter().any(
- |attr| attr.check_name("thread_local"
- ))
+ |attr| attr.check_name(sym::thread_local)
+ )
}
}
}
if self.tcx
.get_attrs(def_id)
.iter()
- .any(|attr| attr.check_name("thread_local")) {
+ .any(|attr| attr.check_name(sym::thread_local)) {
if self.mode != Mode::Fn {
span_err!(self.tcx.sess, self.span, E0625,
"thread-local statics cannot be \
if let ty::RawPtr(_) = base_ty.sty {
if !self.tcx.features().const_raw_ptr_deref {
emit_feature_err(
- &self.tcx.sess.parse_sess, "const_raw_ptr_deref",
+ &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref,
self.span, GateIssue::Language,
&format!(
"dereferencing raw pointers in {}s is unstable",
Mode::ConstFn => {
if !self.tcx.features().const_fn_union {
emit_feature_err(
- &self.tcx.sess.parse_sess, "const_fn_union",
+ &self.tcx.sess.parse_sess, sym::const_fn_union,
self.span, GateIssue::Language,
"unions in const fn are unstable",
);
// in const fn and constants require the feature gate
// FIXME: make it unsafe inside const fn and constants
emit_feature_err(
- &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast",
+ &self.tcx.sess.parse_sess, sym::const_raw_ptr_to_usize_cast,
self.span, GateIssue::Language,
&format!(
"casting pointers to integers in {}s is unstable",
// FIXME: make it unsafe to use these operations
emit_feature_err(
&self.tcx.sess.parse_sess,
- "const_compare_raw_pointers",
+ sym::const_compare_raw_pointers,
self.span,
GateIssue::Language,
&format!("comparing raw pointers inside {}", self.mode),
// const eval transmute calls only with the feature gate
if !self.tcx.features().const_transmute {
emit_feature_err(
- &self.tcx.sess.parse_sess, "const_transmute",
+ &self.tcx.sess.parse_sess, sym::const_transmute,
self.span, GateIssue::Language,
&format!("The use of std::mem::transmute() \
is gated in {}s", self.mode));
// Don't allow panics in constants without the feature gate.
emit_feature_err(
&self.tcx.sess.parse_sess,
- "const_panic",
+ sym::const_panic,
self.span,
GateIssue::Language,
&format!("panicking in {}s is unstable", self.mode),
// Check `#[unstable]` const fns or `#[rustc_const_unstable]`
// functions without the feature gate active in this crate in
// order to report a better error message than the one below.
- if !self.span.allows_unstable(&feature.as_str()) {
+ if !self.span.allows_unstable(feature) {
let mut err = self.tcx.sess.struct_span_err(self.span,
&format!("`{}` is not yet stable as a const fn",
self.tcx.def_path_str(def_id)));
if mode == Mode::Static {
// `#[thread_local]` statics don't have to be `Sync`.
for attr in &tcx.get_attrs(def_id)[..] {
- if attr.check_name("thread_local") {
+ if attr.check_name(sym::thread_local) {
return;
}
}
fn args_required_const(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<FxHashSet<usize>> {
let attrs = tcx.get_attrs(def_id);
- let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?;
+ let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
let mut ret = FxHashSet::default();
for meta in attr.meta_item_list()? {
match meta.literal()?.node {
use rustc_target::spec::abi::{Abi};
use syntax::ast;
+use syntax::symbol::sym;
use syntax_pos::Span;
use rustc::ty::{self, TyCtxt};
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
let def_id = src.def_id();
- if !tcx.has_attr(def_id, "rustc_mir") {
+ if !tcx.has_attr(def_id, sym::rustc_mir) {
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
return;
} else {
DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
- if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
+ if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() {
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits);
}
- if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() {
+ if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() {
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits);
}
- if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() {
+ if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits);
}
- if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() {
+ if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
tcx.sess.fatal("stop_after_dataflow ended compilation");
}
}
use syntax::ast::*;
use syntax::attr;
use syntax::source_map::Spanned;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax::ptr::P;
use syntax::visit::{self, Visitor};
use syntax::{span_err, struct_span_err, walk_list};
self.has_proc_macro_decls = true;
}
- if attr::contains_name(&item.attrs, "global_allocator") {
+ if attr::contains_name(&item.attrs, sym::global_allocator) {
self.has_global_allocator = true;
}
}
ItemKind::Mod(_) => {
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
- attr::first_attr_value_str_by_name(&item.attrs, "path");
- if attr::contains_name(&item.attrs, "warn_directory_ownership") {
+ attr::first_attr_value_str_by_name(&item.attrs, sym::path);
+ if attr::contains_name(&item.attrs, sym::warn_directory_ownership) {
let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
let msg = "cannot declare a new module at this location";
self.session.buffer_lint(lint, item.id, item.span, msg);
use rustc::ty::Ty;
use rustc::ty::TyCtxt;
use syntax::ast::Attribute;
+use syntax::symbol::sym;
pub fn test_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
if tcx.features().rustc_attrs {
if let ItemKind::Ty(..) = item.node {
for attr in self.tcx.get_attrs(item_def_id).iter() {
- if attr.check_name("rustc_layout") {
+ if attr.check_name(sym::rustc_layout) {
self.dump_layout_of(item_def_id, item, attr);
}
}
// The `..` are the names of fields to dump.
let meta_items = attr.meta_item_list().unwrap_or_default();
for meta_item in meta_items {
- match meta_item.name_or_empty().get() {
- "abi" => {
+ match meta_item.name_or_empty() {
+ sym::abi => {
self.tcx
.sess
.span_err(item.span, &format!("abi: {:?}", ty_layout.abi));
}
- "align" => {
+ sym::align => {
self.tcx
.sess
.span_err(item.span, &format!("align: {:?}", ty_layout.align));
}
- "size" => {
+ sym::size => {
self.tcx
.sess
.span_err(item.span, &format!("size: {:?}", ty_layout.size));
}
- "homogeneous_aggregate" => {
+ sym::homogeneous_aggregate => {
self.tcx.sess.span_err(
item.span,
&format!(
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::util::nodemap::{ItemLocalSet, HirIdSet};
use rustc::hir;
+use syntax::symbol::sym;
use syntax_pos::{Span, DUMMY_SP};
use log::debug;
use Promotability::*;
if v.in_static {
for attr in &v.tcx.get_attrs(did)[..] {
- if attr.check_name("thread_local") {
+ if attr.check_name(sym::thread_local) {
debug!("Reference to Static(id={:?}) is unpromotable \
due to a #[thread_local] attribute", did);
return NotPromotable;
//! Used by `rustc` when compiling a plugin crate.
use syntax::attr;
+use syntax::symbol::sym;
use syntax_pos::Span;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir;
impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
fn visit_item(&mut self, item: &hir::Item) {
if let hir::ItemKind::Fn(..) = item.node {
- if attr::contains_name(&item.attrs,
- "plugin_registrar") {
+ if attr::contains_name(&item.attrs, sym::plugin_registrar) {
self.registrars.push((item.hir_id, item.span));
}
}
use std::path::PathBuf;
use syntax::ast;
use syntax::span_err;
+use syntax::symbol::{Symbol, keywords, sym};
use syntax_pos::{Span, DUMMY_SP};
/// Pointer to a registrar function.
// the feature enabled will result in an error later...
if sess.features_untracked().plugin {
for attr in &krate.attrs {
- if !attr.check_name("plugin") {
+ if !attr.check_name(sym::plugin) {
continue;
}
for plugin in plugins {
// plugins must have a name and can't be key = value
let name = plugin.name_or_empty();
- if !name.is_empty() && !plugin.is_value_str() {
+ if name != keywords::Invalid.name() && !plugin.is_value_str() {
let args = plugin.meta_item_list().map(ToOwned::to_owned);
- loader.load_plugin(plugin.span(), &name, args.unwrap_or_default());
+ loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
} else {
call_malformed_plugin_attribute(sess, attr.span);
}
if let Some(plugins) = addl_plugins {
for plugin in plugins {
- loader.load_plugin(DUMMY_SP, &plugin, vec![]);
+ loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
}
}
}
}
- fn load_plugin(&mut self, span: Span, name: &str, args: Vec<ast::NestedMetaItem>) {
+ fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
let registrar = self.reader.find_plugin_registrar(span, name);
if let Some((lib, disambiguator)) = registrar {
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT};
use syntax::ext::base::MacroExpanderFn;
use syntax::ext::hygiene;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::ast;
use syntax::feature_gate::AttributeType;
use syntax_pos::Span;
pub llvm_passes: Vec<String>,
#[doc(hidden)]
- pub attributes: Vec<(String, AttributeType)>,
+ pub attributes: Vec<(Symbol, AttributeType)>,
}
impl<'a> Registry<'a> {
///
/// This is the most general hook into `libsyntax`'s expansion behavior.
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
- if name == "macro_rules" {
+ if name == sym::macro_rules {
panic!("user-defined macros may not be named `macro_rules`");
}
self.syntax_exts.push((name, match extension {
/// Registered attributes will bypass the `custom_attribute` feature gate.
/// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
/// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
- pub fn register_attribute(&mut self, name: String, ty: AttributeType) {
+ pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
self.attributes.push((name, ty));
}
}
use rustc_data_structures::sync::Lrc;
use syntax::ast::Ident;
use syntax::attr;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax_pos::Span;
use std::{cmp, fmt, mem};
ctor_vis = ty::Visibility::Restricted(
DefId::local(CRATE_DEF_INDEX));
let attrs = tcx.get_attrs(variant.def_id);
- span = attr::find_by_name(&attrs, "non_exhaustive").unwrap().span;
+ span = attr::find_by_name(&attrs, sym::non_exhaustive)
+ .unwrap().span;
descr = "crate-visible";
}
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, "non_exhaustive")
+ span = attr::find_by_name(&item.attrs, sym::non_exhaustive)
.unwrap().span;
descr = "crate-visible";
}
use syntax::parse::token::{self, Token};
use syntax::span_err;
use syntax::std_inject::injected_crate_name;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP};
}
ast::UseTreeKind::Glob => {
let subclass = GlobImport {
- is_prelude: attr::contains_name(&item.attrs, "prelude_import"),
+ is_prelude: attr::contains_name(&item.attrs, sym::prelude_import),
max_vis: Cell::new(ty::Visibility::Invisible),
};
self.add_import_directive(
};
self.populate_module_if_necessary(module);
- if injected_crate_name().map_or(false, |name| ident.name == name) {
+ if injected_crate_name().map_or(false, |name| ident.name.as_str() == name) {
self.injected_crate = Some(module);
}
let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
let module = self.arenas.alloc_module(ModuleData {
no_implicit_prelude: parent.no_implicit_prelude || {
- attr::contains_name(&item.attrs, "no_implicit_prelude")
+ attr::contains_name(&item.attrs, sym::no_implicit_prelude)
},
..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
});
// Functions introducing procedural macros reserve a slot
// in the macro namespace as well (see #52225).
- if attr::contains_name(&item.attrs, "proc_macro") ||
- attr::contains_name(&item.attrs, "proc_macro_attribute") {
+ if attr::contains_name(&item.attrs, sym::proc_macro) ||
+ attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id());
self.define(parent, ident, MacroNS, (res, vis, sp, expansion));
}
- if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") {
+ if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
if let Some(trait_attr) =
attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
if let Some(ident) = trait_attr.ident() {
let mut ctor_vis = vis;
- let has_non_exhaustive = attr::contains_name(&item.attrs, "non_exhaustive");
+ let has_non_exhaustive = attr::contains_name(&item.attrs, sym::non_exhaustive);
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
// 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.node.attrs, "non_exhaustive");
+ let has_non_exhaustive = attr::contains_name(&variant.node.attrs, sym::non_exhaustive);
if has_non_exhaustive && vis == ty::Visibility::Public {
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
}
let mut import_all = None;
let mut single_imports = Vec::new();
for attr in &item.attrs {
- if attr.check_name("macro_use") {
+ if attr.check_name(sym::macro_use) {
if self.current_module.parent.is_some() {
span_err!(self.session, item.span, E0468,
"an `extern crate` loading macros must be at the crate root");
/// 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("macro_escape") {
+ if attr.check_name(sym::macro_escape) {
let msg = "macro_escape is a deprecated synonym for macro_use";
let mut err = self.session.struct_span_warn(attr.span, msg);
if let ast::AttrStyle::Inner = attr.style {
} else {
err.emit();
}
- } else if !attr.check_name("macro_use") {
+ } else if !attr.check_name(sym::macro_use) {
continue;
}
use syntax::ext::base::SyntaxExtension;
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::base::MacroKind;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::visit::{self, FnKind, Visitor};
fn resolve_str_path(
&mut self,
span: Span,
- crate_root: Option<&str>,
- components: &[&str],
+ crate_root: Option<Symbol>,
+ components: &[Symbol],
is_value: bool
) -> hir::Path {
let root = if crate_root.is_some() {
.chain(
crate_root.into_iter()
.chain(components.iter().cloned())
- .map(Ident::from_str)
+ .map(Ident::with_empty_ctxt)
).map(|i| self.new_ast_path_segment(i)).collect::<Vec<_>>();
keywords::Invalid.name(),
);
let graph_root = arenas.alloc_module(ModuleData {
- no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
+ no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
});
let mut module_map = FxHashMap::default();
session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))
.collect();
- if !attr::contains_name(&krate.attrs, "no_core") {
+ if !attr::contains_name(&krate.attrs, sym::no_core) {
extern_prelude.insert(Ident::from_str("core"), Default::default());
- if !attr::contains_name(&krate.attrs, "no_std") {
+ if !attr::contains_name(&krate.attrs, sym::no_std) {
extern_prelude.insert(Ident::from_str("std"), Default::default());
if session.rust_2018() {
extern_prelude.insert(Ident::from_str("meta"), Default::default());
use syntax::feature_gate::{
feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
};
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
use syntax::visit::Visitor;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{Span, DUMMY_SP};
if !features.rustc_attrs {
let msg = "unless otherwise specified, attributes with the prefix \
`rustc_` are reserved for internal compiler diagnostics";
- self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs");
+ self.report_unknown_attribute(path.span, &name, msg,
+ sym::rustc_attrs);
}
} else if !features.custom_attribute {
let msg = format!("The attribute `{}` is currently unknown to the \
path.span,
&name,
&msg,
- "custom_attribute",
+ sym::custom_attribute,
);
}
}
Ok((res, self.get_macro(res)))
}
- fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
+ fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: Symbol) {
let mut err = feature_err(
&self.session.parse_sess,
feature,
WhereToResolve::LegacyPluginHelpers => {
if (use_prelude || rust_2015) &&
self.session.plugin_attributes.borrow().iter()
- .any(|(name, _)| ident.name == &**name) {
+ .any(|(name, _)| ident.name == *name) {
let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
ty::Visibility::Public, DUMMY_SP, Mark::root())
.to_name_binding(self.arenas);
let msg =
format!("cannot find {} `{}{}` in this scope", kind.descr(), ident, bang);
let mut err = self.session.struct_span_err(ident.span, &msg);
- self.suggest_macro_name(&ident.as_str(), kind, &mut err, ident.span);
+ self.suggest_macro_name(ident.name, kind, &mut err, ident.span);
err.emit();
}
}
}
}
- fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
+ fn suggest_macro_name(&mut self, name: Symbol, kind: MacroKind,
err: &mut DiagnosticBuilder<'a>, span: Span) {
// First check if this is a locally-defined bang macro.
let suggestion = if let MacroKind::Bang = kind {
- find_best_match_for_name(self.macro_names.iter().map(|ident| &ident.name), name, None)
+ find_best_match_for_name(
+ self.macro_names.iter().map(|ident| &ident.name), &name.as_str(), None)
} else {
None
// Then check global macros.
.filter_map(|(name, binding)| {
if binding.macro_kind() == Some(kind) { Some(name) } else { None }
});
- find_best_match_for_name(names, name, None)
+ find_best_match_for_name(names, &name.as_str(), None)
// Then check modules.
}).or_else(|| {
let is_macro = |res| {
false
}
};
- let ident = Ident::new(Symbol::intern(name), span);
+ let ident = Ident::new(name, span);
self.lookup_typo_candidate(&[Segment::from_ident(ident)], MacroNS, is_macro, span)
.map(|suggestion| suggestion.candidate)
});
current_legacy_scope: &mut LegacyScope<'a>) {
self.local_macro_def_scopes.insert(item.id, self.current_module);
let ident = item.ident;
- if ident.name == "macro_rules" {
+ if ident.name == sym::macro_rules {
self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`");
}
let ident = ident.modern();
self.macro_names.insert(ident);
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
- let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
+ let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
let vis = if is_macro_export {
ty::Visibility::Public
} else {
self.define(module, ident, MacroNS,
(res, vis, item.span, expansion, IsMacroExport));
} else {
- if !attr::contains_name(&item.attrs, "rustc_doc_only_macro") {
+ if !attr::contains_name(&item.attrs, sym::rustc_doc_only_macro) {
self.check_reserved_macro_name(ident, MacroNS);
}
self.unused_macros.insert(def_id);
use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID};
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::hygiene::Mark;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::{struct_span_err, unwrap_or};
use syntax_pos::{MultiSpan, Span};
// Reserve some names that are not quite covered by the general check
// performed on `Resolver::builtin_attrs`.
if ns == MacroNS &&
- (ident.name == "cfg" || ident.name == "cfg_attr" || ident.name == "derive") {
+ (ident.name == sym::cfg || ident.name == sym::cfg_attr ||
+ ident.name == sym::derive) {
self.session.span_err(ident.span,
&format!("name `{}` is reserved in macro namespace", ident));
}
has_errors = true;
if let SingleImport { source, ref source_bindings, .. } = import.subclass {
- if source.name == "self" {
+ if source.name == keywords::SelfLower.name() {
// Silence `unresolved import` error if E0429 is already emitted
if let Err(Determined) = source_bindings.value_ns.get() {
continue;
let initial_res = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false;
if let Some(target_binding) = target_bindings[ns].get() {
- if target.name == "_" &&
+ // Note that as_str() de-gensyms the Symbol
+ if target.name.as_str() == "_" &&
initial_binding.is_extern_crate() && !initial_binding.is_import() {
this.record_use(ident, ns, target_binding,
directive.module_path.is_empty());
// (e.g. implicitly injected `std`) cannot be properly encoded in metadata,
// so they can cause name conflict errors downstream.
let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
- !(ident.name.is_gensymed() && ident.name != "_");
+ // Note that as_str() de-gensyms the Symbol
+ !(ident.name.is_gensymed() && ident.name.as_str() != "_");
if is_good_import || binding.is_macro_def() {
let res = binding.res();
if res != Res::Err {
let mut result = String::new();
for attr in attrs {
- if attr.check_name("doc") {
+ if attr.check_name(sym::doc) {
if let Some(val) = attr.value_str() {
if attr.is_sugared_doc {
result.push_str(&strip_doc_comment_decoration(&val.as_str()));
result.push('\n');
} else if let Some(meta_list) = attr.meta_item_list() {
meta_list.into_iter()
- .filter(|it| it.check_name("include"))
+ .filter(|it| it.check_name(sym::include))
.filter_map(|it| it.meta_item_list().map(|l| l.to_owned()))
.flat_map(|it| it)
- .filter(|meta| meta.check_name("contents"))
+ .filter(|meta| meta.check_name(sym::contents))
.filter_map(|meta| meta.value_str())
.for_each(|val| {
result.push_str(&val.as_str());
fn lower_attributes(attrs: Vec<Attribute>, scx: &SaveContext<'_, '_>) -> Vec<rls_data::Attribute> {
attrs.into_iter()
// Only retain real attributes. Doc comments are lowered separately.
- .filter(|attr| attr.path != "doc")
+ .filter(|attr| attr.path != sym::doc)
.map(|mut attr| {
// Remove the surrounding '#[..]' or '#![..]' of the pretty printed
// attribute. First normalize all inner attribute (#![..]) to outer
use rustc::ty::{self, List, TyCtxt};
use rustc::ty::subst::{Subst, InternalSubsts};
use syntax::ast;
+use syntax::symbol::sym;
use std::iter;
for attr in attrs {
let mut clauses = None;
- if attr.check_name("rustc_dump_program_clauses") {
+ if attr.check_name(sym::rustc_dump_program_clauses) {
clauses = Some(self.tcx.program_clauses_for(def_id));
}
- if attr.check_name("rustc_dump_env_program_clauses") {
+ if attr.check_name(sym::rustc_dump_env_program_clauses) {
let environment = self.tcx.environment(def_id);
clauses = Some(self.tcx.program_clauses_for_env(environment));
}
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax::ptr::P;
use syntax::util::lev_distance::find_best_match_for_name;
+use syntax::symbol::sym;
use syntax_pos::{DUMMY_SP, Span, MultiSpan};
use crate::util::common::ErrorReported;
use crate::util::nodemap::FxHashMap;
} else {
"parenthetical notation is only stable when used with `Fn`-family traits"
};
- emit_feature_err(&self.tcx().sess.parse_sess, "unboxed_closures",
+ emit_feature_err(&self.tcx().sess.parse_sess, sym::unboxed_closures,
span, GateIssue::Language, msg);
}
use std::ops::Deref;
use syntax::feature_gate;
use syntax::ptr::P;
+use syntax::symbol::sym;
use syntax_pos;
struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
- "unsized_tuple_coercion",
+ sym::unsized_tuple_coercion,
self.cause.span,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_UNSIZED_TUPLE_COERCION);
use rustc::infer::InferOk;
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
+use syntax::symbol::sym;
use syntax::util::parser::PREC_POSTFIX;
use syntax_pos::Span;
use rustc::hir;
//
// FIXME? Other potential candidate methods: `as_ref` and
// `as_mut`?
- .find(|a| a.check_name("rustc_conversion_suggestion")).is_some()
+ .find(|a| a.check_name(sym::rustc_conversion_suggestion)).is_some()
});
methods
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax::ptr::P;
use syntax::source_map::{DUMMY_SP, original_sp};
-use syntax::symbol::{Symbol, LocalInternedString, keywords};
+use syntax::symbol::{Symbol, LocalInternedString, keywords, sym};
use syntax::util::lev_distance::find_best_match_for_name;
use std::cell::{Cell, RefCell, Ref, RefMut};
if vs.is_empty() {
let attributes = tcx.get_attrs(def_id);
- if let Some(attr) = attr::find_by_name(&attributes, "repr") {
+ if let Some(attr) = attr::find_by_name(&attributes, sym::repr) {
struct_span_err!(
tcx.sess, attr.span, E0084,
"unsupported representation for zero-variant enum")
if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
if !tcx.features().repr128 {
emit_feature_err(&tcx.sess.parse_sess,
- "repr128",
+ sym::repr128,
sp,
GateIssue::Language,
"repr with 128-bit type is unstable");
// ... except when we try to 'break rust;'.
// ICE this expression in particular (see #43162).
if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node {
- if path.segments.len() == 1 && path.segments[0].ident.name == "rust" {
+ if path.segments.len() == 1 &&
+ path.segments[0].ident.name == sym::rust {
fatally_break_rust(self.tcx.sess);
}
}
span: Span) {
// We're only interested in functions tagged with
// #[rustc_args_required_const], so ignore anything that's not.
- if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
+ if !self.tcx.has_attr(def_id, sym::rustc_args_required_const) {
return
}
use syntax::ast;
use syntax::feature_gate::{self, GateIssue};
use syntax_pos::Span;
+use syntax::symbol::sym;
use errors::{DiagnosticBuilder, DiagnosticId};
use rustc::hir::itemlikevisit::ParItemLikeVisitor;
// report error, would have worked with arbitrary_self_types
feature_gate::feature_err(
&fcx.tcx.sess.parse_sess,
- "arbitrary_self_types",
+ sym::arbitrary_self_types,
span,
GateIssue::Language,
&format!(
use rustc::util::nodemap::DefIdSet;
use rustc_data_structures::sync::Lrc;
use std::mem;
+use syntax::symbol::sym;
use syntax_pos::Span;
///////////////////////////////////////////////////////////////////////////
let item_def_id = self.tcx.hir().local_def_id(item_id);
// This attribute causes us to dump some writeback information
- // in the form of errors, which is used for unit tests.
- let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, "rustc_dump_user_substs");
+ // in the form of errors, which is uSymbolfor unit tests.
+ let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, sym::rustc_dump_user_substs);
let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_substs);
for arg in &body.arguments {
use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used};
use syntax::source_map::Spanned;
use syntax::feature_gate;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
use syntax_pos::{Span, DUMMY_SP};
use rustc::hir::def::{CtorKind, Res, DefKind};
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
};
- let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
+ let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
if paren_sugar && !tcx.features().unboxed_closures {
let mut err = tcx.sess.struct_span_err(
item.span,
err.emit();
}
- let is_marker = tcx.has_attr(def_id, "marker");
+ let is_marker = tcx.has_attr(def_id, sym::marker);
let def_path_hash = tcx.def_path_hash(def_id);
let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, is_auto, is_marker, def_path_hash);
tcx.alloc_trait_def(def)
tcx: TyCtxt<'_, '_, '_>,
id: DefId,
attr: &ast::Attribute,
- whitelist: &FxHashMap<String, Option<String>>,
+ whitelist: &FxHashMap<String, Option<Symbol>>,
target_features: &mut Vec<Symbol>,
) {
let list = match attr.meta_item_list() {
let rust_features = tcx.features();
for item in list {
// Only `enable = ...` is accepted in the meta item list
- if !item.check_name("enable") {
+ if !item.check_name(sym::enable) {
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
currently";
tcx.sess.span_err(item.span(), &msg);
};
// Only allow features whose feature gates have been enabled
- let allowed = match feature_gate.as_ref().map(|s| &**s) {
- Some("arm_target_feature") => rust_features.arm_target_feature,
- Some("aarch64_target_feature") => rust_features.aarch64_target_feature,
- Some("hexagon_target_feature") => rust_features.hexagon_target_feature,
- Some("powerpc_target_feature") => rust_features.powerpc_target_feature,
- Some("mips_target_feature") => rust_features.mips_target_feature,
- Some("avx512_target_feature") => rust_features.avx512_target_feature,
- Some("mmx_target_feature") => rust_features.mmx_target_feature,
- Some("sse4a_target_feature") => rust_features.sse4a_target_feature,
- Some("tbm_target_feature") => rust_features.tbm_target_feature,
- Some("wasm_target_feature") => rust_features.wasm_target_feature,
- Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature,
- Some("adx_target_feature") => rust_features.adx_target_feature,
- Some("movbe_target_feature") => rust_features.movbe_target_feature,
- Some("rtm_target_feature") => rust_features.rtm_target_feature,
- Some("f16c_target_feature") => rust_features.f16c_target_feature,
+ let allowed = match feature_gate.as_ref().map(|s| *s) {
+ Some(sym::arm_target_feature) => rust_features.arm_target_feature,
+ Some(sym::aarch64_target_feature) => rust_features.aarch64_target_feature,
+ Some(sym::hexagon_target_feature) => rust_features.hexagon_target_feature,
+ Some(sym::powerpc_target_feature) => rust_features.powerpc_target_feature,
+ Some(sym::mips_target_feature) => rust_features.mips_target_feature,
+ Some(sym::avx512_target_feature) => rust_features.avx512_target_feature,
+ Some(sym::mmx_target_feature) => rust_features.mmx_target_feature,
+ Some(sym::sse4a_target_feature) => rust_features.sse4a_target_feature,
+ Some(sym::tbm_target_feature) => rust_features.tbm_target_feature,
+ Some(sym::wasm_target_feature) => rust_features.wasm_target_feature,
+ Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature,
+ Some(sym::adx_target_feature) => rust_features.adx_target_feature,
+ Some(sym::movbe_target_feature) => rust_features.movbe_target_feature,
+ Some(sym::rtm_target_feature) => rust_features.rtm_target_feature,
+ Some(sym::f16c_target_feature) => rust_features.f16c_target_feature,
Some(name) => bug!("unknown target feature gate {}", name),
None => true,
};
if !allowed && id.is_local() {
feature_gate::emit_feature_err(
&tcx.sess.parse_sess,
- feature_gate.as_ref().unwrap(),
+ feature_gate.unwrap(),
item.span(),
feature_gate::GateIssue::Language,
&format!("the target feature `{}` is currently unstable", feature),
let mut inline_span = None;
for attr in attrs.iter() {
- if attr.check_name("cold") {
+ if attr.check_name(sym::cold) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
- } else if attr.check_name("allocator") {
+ } else if attr.check_name(sym::allocator) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
- } else if attr.check_name("unwind") {
+ } else if attr.check_name(sym::unwind) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND;
- } else if attr.check_name("ffi_returns_twice") {
+ } else if attr.check_name(sym::ffi_returns_twice) {
if tcx.is_foreign_item(id) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE;
} else {
"`#[ffi_returns_twice]` may only be used on foreign functions"
).emit();
}
- } else if attr.check_name("rustc_allocator_nounwind") {
+ } else if attr.check_name(sym::rustc_allocator_nounwind) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
- } else if attr.check_name("naked") {
+ } else if attr.check_name(sym::naked) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
- } else if attr.check_name("no_mangle") {
+ } else if attr.check_name(sym::no_mangle) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
- } else if attr.check_name("rustc_std_internal_symbol") {
+ } else if attr.check_name(sym::rustc_std_internal_symbol) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
- } else if attr.check_name("no_debug") {
+ } else if attr.check_name(sym::no_debug) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_DEBUG;
- } else if attr.check_name("used") {
+ } else if attr.check_name(sym::used) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
- } else if attr.check_name("thread_local") {
+ } else if attr.check_name(sym::thread_local) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
- } else if attr.check_name("export_name") {
+ } else if attr.check_name(sym::export_name) {
if let Some(s) = attr.value_str() {
if s.as_str().contains("\0") {
// `#[export_name = ...]` will be converted to a null-terminated string,
}
codegen_fn_attrs.export_name = Some(s);
}
- } else if attr.check_name("target_feature") {
+ } else if attr.check_name(sym::target_feature) {
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
let msg = "#[target_feature(..)] can only be applied to \
`unsafe` function";
&whitelist,
&mut codegen_fn_attrs.target_features,
);
- } else if attr.check_name("linkage") {
+ } else if attr.check_name(sym::linkage) {
if let Some(val) = attr.value_str() {
codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str()));
}
- } else if attr.check_name("link_section") {
+ } else if attr.check_name(sym::link_section) {
if let Some(val) = attr.value_str() {
if val.as_str().bytes().any(|b| b == 0) {
let msg = format!(
codegen_fn_attrs.link_section = Some(val);
}
}
- } else if attr.check_name("link_name") {
+ } else if attr.check_name(sym::link_name) {
codegen_fn_attrs.link_name = attr.value_str();
}
}
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
- if attr.path != "inline" {
+ if attr.path != sym::inline {
return ia;
}
match attr.meta().map(|i| i.node) {
"expected one argument"
);
InlineAttr::None
- } else if list_contains_name(&items[..], "always") {
+ } else if list_contains_name(&items[..], sym::always) {
InlineAttr::Always
- } else if list_contains_name(&items[..], "never") {
+ } else if list_contains_name(&items[..], sym::never) {
InlineAttr::Never
} else {
span_err!(
});
codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
- if attr.path != "optimize" {
+ if attr.path != sym::optimize {
return ia;
}
let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s);
if items.len() != 1 {
err(attr.span, "expected one argument");
OptimizeAttr::None
- } else if list_contains_name(&items[..], "size") {
+ } else if list_contains_name(&items[..], sym::size) {
OptimizeAttr::Size
- } else if list_contains_name(&items[..], "speed") {
+ } else if list_contains_name(&items[..], sym::speed) {
OptimizeAttr::Speed
} else {
err(items[0].span(), "invalid argument");
use rustc::ty::subst::UnpackedKind;
use rustc::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_data_structures::sync::Lrc;
+use syntax::symbol::sym;
mod explicit;
mod implicit_infer;
.map(|p| *p)
.unwrap_or(&[]);
- if tcx.has_attr(item_def_id, "rustc_outlives") {
+ if tcx.has_attr(item_def_id, sym::rustc_outlives) {
let mut pred: Vec<String> = predicates
.iter()
.map(|out_pred| match out_pred {
use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::TyCtxt;
+use syntax::symbol::sym;
pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.hir()
// For unit testing: check for a special "rustc_outlives"
// attribute and report an error with various results if found.
- if self.tcx.has_attr(item_def_id, "rustc_outlives") {
+ if self.tcx.has_attr(item_def_id, sym::rustc_outlives) {
let inferred_outlives_of = self.tcx.inferred_outlives_of(item_def_id);
span_err!(
self.tcx.sess,
use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::TyCtxt;
+use syntax::symbol::sym;
pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
// For unit testing: check for a special "rustc_variance"
// attribute and report an error with various results if found.
- if self.tcx.has_attr(item_def_id, "rustc_variance") {
+ if self.tcx.has_attr(item_def_id, sym::rustc_variance) {
let variances_of = self.tcx.variances_of(item_def_id);
span_err!(self.tcx.sess,
item.span,
use std::fmt::{self, Write};
use std::ops;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, LitKind};
use syntax::parse::ParseSess;
use syntax::feature_gate::Features;
fn should_use_with_in_description(&self) -> bool {
match *self {
- Cfg::Cfg(ref name, _) if name == &"target_feature" => true,
+ Cfg::Cfg(name, _) if name == sym::target_feature => true,
_ => false,
}
}
use syntax::ast;
use syntax::ext::base::{MacroKind, SyntaxExtension};
+use syntax::symbol::sym;
use syntax_pos::Span;
use rustc::hir;
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
let generics = filter_non_trait_generics(did, generics);
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
- let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight");
+ let is_spotlight = load_attrs(cx, did).has_doc_flag(sym::spotlight);
let is_auto = cx.tcx.trait_is_auto(did);
clean::Trait {
auto: auto_trait,
use syntax::source_map::{dummy_spanned, Spanned};
use syntax::ptr::P;
use syntax::symbol::keywords::{self, Keyword};
+use syntax::symbol::{Symbol, sym};
use syntax::symbol::InternedString;
use syntax_pos::{self, Pos, FileName};
// `compiler_builtins` should be masked too, but we can't apply
// `#[doc(masked)]` to the injected `extern crate` because it's unstable.
if it.is_extern_crate()
- && (it.attrs.has_doc_flag("masked")
+ && (it.attrs.has_doc_flag(sym::masked)
|| self.cx.tcx.is_compiler_builtins(it.def_id.krate))
{
masked_crates.insert(it.def_id.krate);
if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
let mut prim = None;
- for attr in attrs.lists("doc") {
+ for attr in attrs.lists(sym::doc) {
if let Some(v) = attr.value_str() {
- if attr.check_name("primitive") {
+ if attr.check_name(sym::primitive) {
prim = PrimitiveType::from_str(&v.as_str());
if prim.is_some() {
break;
if let Res::Def(DefKind::Mod, def_id) = res {
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
let mut keyword = None;
- for attr in attrs.lists("doc") {
+ for attr in attrs.lists(sym::doc) {
if let Some(v) = attr.value_str() {
- if attr.check_name("keyword") {
+ if attr.check_name(sym::keyword) {
keyword = Keyword::from_str(&v.as_str()).ok()
.map(|x| x.name().to_string());
if keyword.is_some() {
pub fn is_non_exhaustive(&self) -> bool {
self.attrs.other_attrs.iter()
- .any(|a| a.check_name("non_exhaustive"))
+ .any(|a| a.check_name(sym::non_exhaustive))
}
/// Returns a documentation-level item type from the item.
pub struct ListAttributesIter<'a> {
attrs: slice::Iter<'a, ast::Attribute>,
current_list: vec::IntoIter<ast::NestedMetaItem>,
- name: &'a str
+ name: Symbol,
}
impl<'a> Iterator for ListAttributesIter<'a> {
pub trait AttributesExt {
/// Finds an attribute as List and returns the list of attributes nested inside.
- fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>;
+ fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a>;
}
impl AttributesExt for [ast::Attribute] {
- fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
+ fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
ListAttributesIter {
attrs: self.iter(),
current_list: Vec::new().into_iter(),
pub trait NestedAttributesExt {
/// Returns `true` if the attribute list contains a specific `Word`
- fn has_word(self, word: &str) -> bool;
+ fn has_word(self, word: Symbol) -> bool;
}
impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
- fn has_word(self, word: &str) -> bool {
+ fn has_word(self, word: Symbol) -> bool {
self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
}
}
if let ast::MetaItemKind::List(ref nmis) = mi.node {
if nmis.len() == 1 {
if let MetaItem(ref cfg_mi) = nmis[0] {
- if cfg_mi.check_name("cfg") {
+ if cfg_mi.check_name(sym::cfg) {
if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node {
if cfg_nmis.len() == 1 {
if let MetaItem(ref content_mi) = cfg_nmis[0] {
{
mi.meta_item_list().and_then(|list| {
for meta in list {
- if meta.check_name("include") {
+ if meta.check_name(sym::include) {
// the actual compiled `#[doc(include="filename")]` gets expanded to
// `#[doc(include(file="filename", contents="file contents")]` so we need to
// look for that instead
let mut contents: Option<String> = None;
for it in list {
- if it.check_name("file") {
+ if it.check_name(sym::file) {
if let Some(name) = it.value_str() {
filename = Some(name.to_string());
}
- } else if it.check_name("contents") {
+ } else if it.check_name(sym::contents) {
if let Some(docs) = it.value_str() {
contents = Some(docs.to_string());
}
})
}
- pub fn has_doc_flag(&self, flag: &str) -> bool {
+ pub fn has_doc_flag(&self, flag: Symbol) -> bool {
for attr in &self.other_attrs {
- if !attr.check_name("doc") { continue; }
+ if !attr.check_name(sym::doc) { continue; }
if let Some(items) = attr.meta_item_list() {
if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
let other_attrs = attrs.iter().filter_map(|attr| {
attr.with_desugared_doc(|attr| {
- if attr.check_name("doc") {
+ if attr.check_name(sym::doc) {
if let Some(mi) = attr.meta() {
if let Some(value) = mi.value_str() {
// Extracted #[doc = "..."]
// treat #[target_feature(enable = "feat")] attributes as if they were
// #[doc(cfg(target_feature = "feat"))] attributes as well
- for attr in attrs.lists("target_feature") {
- if attr.check_name("enable") {
+ for attr in attrs.lists(sym::target_feature) {
+ if attr.check_name(sym::enable) {
if let Some(feat) = attr.value_str() {
let meta = attr::mk_name_value_item_str(Ident::from_str("target_feature"),
dummy_spanned(feat));
}
let inner_docs = attrs.iter()
- .filter(|a| a.check_name("doc"))
+ .filter(|a| a.check_name(sym::doc))
.next()
.map_or(true, |a| a.style == AttrStyle::Inner);
}
impl AttributesExt for Attributes {
- fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
+ fn lists<'a>(&'a self, name: Symbol) -> ListAttributesIter<'a> {
self.other_attrs.lists(name)
}
}
impl Clean<Item> for doctree::Trait {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
- let is_spotlight = attrs.has_doc_flag("spotlight");
+ let is_spotlight = attrs.has_doc_flag(sym::spotlight);
Item {
name: Some(self.name.clean(cx)),
attrs: attrs,
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
- a.check_name("doc") && match a.meta_item_list() {
- Some(l) => attr::list_contains_name(&l, "inline"),
+ a.check_name(sym::doc) && match a.meta_item_list() {
+ Some(l) => attr::list_contains_name(&l, sym::inline),
None => false,
}
});
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
- a.check_name("doc") && match a.meta_item_list() {
- Some(l) => attr::list_contains_name(&l, "no_inline") ||
- attr::list_contains_name(&l, "hidden"),
+ a.check_name(sym::doc) && match a.meta_item_list() {
+ Some(l) => attr::list_contains_name(&l, sym::no_inline) ||
+ attr::list_contains_name(&l, sym::hidden),
None => false,
}
});
// Also check whether imports were asked to be inlined, in case we're trying to re-export a
// crate in Rust 2018+
- let please_inline = self.attrs.lists("doc").has_word("inline");
+ let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
let path = self.path.clean(cx);
let inner = if self.glob {
if !denied {
// Start of code copied from rust-clippy
-pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
+pub fn path_to_def_local(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option<DefId> {
let krate = tcx.hir().krate();
let mut items = krate.module.item_ids.clone();
let mut path_it = path.iter().peekable();
}
}
-pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
+pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option<DefId> {
let crates = tcx.crates();
let krate = crates
use syntax::source_map;
use syntax::feature_gate::UnstableFeatures;
use syntax::json::JsonEmitter;
+use syntax::symbol::sym;
use errors;
use errors::emitter::{Emitter, EmitterWriter};
use parking_lot::ReentrantMutex;
};
let send_trait = if crate_name == Some("core".to_string()) {
- clean::path_to_def_local(tcx, &["marker", "Send"])
+ clean::path_to_def_local(tcx, &[sym::marker, sym::Send])
} else {
- clean::path_to_def(tcx, &["core", "marker", "Send"])
+ clean::path_to_def(tcx, &[sym::core, sym::marker, sym::Send])
};
let mut renderinfo = RenderInfo::default();
// Process all of the crate attributes, extracting plugin metadata along
// with the passes which we are supposed to run.
- for attr in krate.module.as_ref().unwrap().attrs.lists("doc") {
+ for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) {
let diag = ctxt.sess().diagnostic();
let name = attr.name_or_empty();
if attr.is_word() {
- if name == "no_default_passes" {
+ if name == sym::no_default_passes {
report_deprecated_attr("no_default_passes", diag);
if default_passes == passes::DefaultPassOption::Default {
default_passes = passes::DefaultPassOption::None;
}
}
} else if let Some(value) = attr.value_str() {
- let sink = match name.get() {
- "passes" => {
+ let sink = match name {
+ sym::passes => {
report_deprecated_attr("passes = \"...\"", diag);
&mut manual_passes
},
- "plugins" => {
+ sym::plugins => {
report_deprecated_attr("plugins = \"...\"", diag);
eprintln!("WARNING: #![doc(plugins = \"...\")] no longer functions; \
see CVE-2018-1000622");
}
}
- if attr.is_word() && name == "document_private_items" {
+ if attr.is_word() && name == sym::document_private_items {
if default_passes == passes::DefaultPassOption::Default {
default_passes = passes::DefaultPassOption::Private;
}
use syntax::ext::base::MacroKind;
use syntax::source_map::FileName;
use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::{Symbol, sym};
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
use rustc::middle::privacy::AccessLevels;
use rustc::middle::stability;
// Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML
if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) {
- for attr in attrs.lists("doc") {
- match (attr.name_or_empty().get(), attr.value_str()) {
- ("html_favicon_url", Some(s)) => {
+ for attr in attrs.lists(sym::doc) {
+ match (attr.name_or_empty(), attr.value_str()) {
+ (sym::html_favicon_url, Some(s)) => {
scx.layout.favicon = s.to_string();
}
- ("html_logo_url", Some(s)) => {
+ (sym::html_logo_url, Some(s)) => {
scx.layout.logo = s.to_string();
}
- ("html_playground_url", Some(s)) => {
+ (sym::html_playground_url, Some(s)) => {
markdown::PLAYGROUND.with(|slot| {
let name = krate.name.clone();
*slot.borrow_mut() = Some((Some(name), s.to_string()));
});
}
- ("issue_tracker_base_url", Some(s)) => {
+ (sym::issue_tracker_base_url, Some(s)) => {
scx.issue_tracker_base_url = Some(s.to_string());
}
- ("html_no_source", None) if attr.is_word() => {
+ (sym::html_no_source, None) if attr.is_word() => {
scx.include_sources = false;
}
_ => {}
// Failing that, see if there's an attribute specifying where to find this
// external crate
- e.attrs.lists("doc")
- .filter(|a| a.check_name("html_root_url"))
+ e.attrs.lists(sym::doc)
+ .filter(|a| a.check_name(sym::html_root_url))
.filter_map(|a| a.value_str())
.map(|url| {
let mut url = url.to_string();
let path = self.paths.get(&item.def_id)
.map(|p| p.0[..p.0.len() - 1].join("::"))
.unwrap_or("std".to_owned());
- for alias in item.attrs.lists("doc")
- .filter(|a| a.check_name("alias"))
+ for alias in item.attrs.lists(sym::doc)
+ .filter(|a| a.check_name(sym::alias))
.filter_map(|a| a.value_str()
.map(|s| s.to_string().replace("\"", "")))
.filter(|v| !v.is_empty())
}
}
-const ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
- "export_name",
- "lang",
- "link_section",
- "must_use",
- "no_mangle",
- "repr",
- "unsafe_destructor_blind_to_params",
- "non_exhaustive"
+const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[
+ sym::export_name,
+ sym::lang,
+ sym::link_section,
+ sym::must_use,
+ sym::no_mangle,
+ sym::repr,
+ sym::unsafe_destructor_blind_to_params,
+ sym::non_exhaustive
];
fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
let mut attrs = String::new();
for attr in &it.attrs.other_attrs {
- if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty().get()) {
+ if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty()) {
continue;
}
if let Some(s) = render_attribute(&attr.meta().unwrap()) {
use syntax::attr;
use syntax_pos::FileName;
+use syntax::symbol::sym;
use std::collections::BTreeMap;
use std::ops;
return Some(i);
}
clean::ImplItem(ref impl_)
- if attr::contains_name(&i.attrs.other_attrs, "automatically_derived")
+ if attr::contains_name(&i.attrs.other_attrs, sym::automatically_derived)
|| impl_.synthetic || impl_.blanket_impl.is_some() =>
{
// built-in derives get the `#[automatically_derived]` attribute, and
// Try looking for methods and associated items.
let mut split = path_str.rsplitn(2, "::");
let item_name = if let Some(first) = split.next() {
- first
+ Symbol::intern(first)
} else {
return Err(())
};
use rustc::util::nodemap::FxHashSet;
use rustc::hir::def_id::DefId;
+use syntax::symbol::sym;
pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
name: "collect-trait-impls",
inline::build_impl(cx, def_id, &mut new_items);
// FIXME(eddyb) is this `doc(hidden)` check needed?
- if !cx.tcx.get_attrs(def_id).lists("doc").has_word("hidden") {
+ if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
let self_ty = cx.tcx.type_of(def_id);
let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
let mut renderinfo = cx.renderinfo.borrow_mut();
fn fold_item(&mut self, i: Item) -> Option<Item> {
if i.is_struct() || i.is_enum() || i.is_union() {
// FIXME(eddyb) is this `doc(hidden)` check needed?
- if !self.cx.tcx.get_attrs(i.def_id).lists("doc").has_word("hidden") {
+ if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) {
self.impls.extend(get_auto_trait_and_blanket_impls(
self.cx,
self.cx.tcx.type_of(i.def_id),
use rustc::util::nodemap::DefIdSet;
use std::mem;
+use syntax::symbol::sym;
use crate::clean::{self, AttributesExt, NestedAttributesExt};
use crate::clean::Item;
impl<'a> DocFolder for Stripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
- if i.attrs.lists("doc").has_word("hidden") {
+ if i.attrs.lists(sym::doc).has_word(sym::hidden) {
debug!("strip_hidden: stripping {} {:?}", i.type_(), i.name);
// use a dedicated hidden item for given item type if any
match i.inner {
use syntax::source_map::SourceMap;
use syntax::edition::Edition;
use syntax::feature_gate::UnstableFeatures;
-use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
-use tempfile::Builder as TempFileBuilder;
-use testing;
-
use std::env;
use std::io::prelude::*;
use std::io;
use std::process::Command;
use std::str;
use std::sync::{Arc, Mutex};
+use syntax::symbol::sym;
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
+use tempfile::Builder as TempFileBuilder;
+use testing;
use crate::clean::Attributes;
use crate::config::Options;
};
let test_attrs: Vec<_> = krate.attrs.iter()
- .filter(|a| a.check_name("doc"))
+ .filter(|a| a.check_name(sym::doc))
.flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new))
- .filter(|a| a.check_name("test"))
+ .filter(|a| a.check_name(sym::test))
.collect();
let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[]));
for attr in attrs {
- if attr.check_name("no_crate_inject") {
+ if attr.check_name(sym::no_crate_inject) {
opts.no_crate_inject = true;
}
- if attr.check_name("attr") {
+ if attr.check_name(sym::attr) {
if let Some(l) = attr.meta_item_list() {
for item in l {
opts.attrs.push(pprust::meta_list_item_to_string(item));
use syntax::attr;
use syntax::ext::base::MacroKind;
use syntax::source_map::Spanned;
+use syntax::symbol::sym;
use syntax_pos::{self, Span};
use std::mem;
body: hir::BodyId) {
debug!("Visiting fn");
let macro_kind = item.attrs.iter().filter_map(|a| {
- if a.check_name("proc_macro") {
+ if a.check_name(sym::proc_macro) {
Some(MacroKind::Bang)
- } else if a.check_name("proc_macro_derive") {
+ } else if a.check_name(sym::proc_macro_derive) {
Some(MacroKind::Derive)
- } else if a.check_name("proc_macro_attribute") {
+ } else if a.check_name(sym::proc_macro_attribute) {
Some(MacroKind::Attr)
} else {
None
match macro_kind {
Some(kind) => {
let name = if kind == MacroKind::Derive {
- item.attrs.lists("proc_macro_derive")
+ item.attrs.lists(sym::proc_macro_derive)
.filter_map(|mi| mi.ident())
.next()
.expect("proc-macro derives require a name")
};
let mut helpers = Vec::new();
- for mi in item.attrs.lists("proc_macro_derive") {
- if !mi.check_name("attributes") {
+ for mi in item.attrs.lists(sym::proc_macro_derive) {
+ if !mi.check_name(sym::attributes) {
continue;
}
fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool {
while let Some(id) = cx.tcx.hir().get_enclosing_scope(node) {
node = id;
- if cx.tcx.hir().attrs_by_hir_id(node).lists("doc").has_word("hidden") {
+ if cx.tcx.hir().attrs_by_hir_id(node)
+ .lists(sym::doc).has_word(sym::hidden) {
return true;
}
if node == hir::CRATE_HIR_ID {
let use_attrs = tcx.hir().attrs_by_hir_id(id);
// Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
- let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
- use_attrs.lists("doc").has_word("hidden");
+ let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline) ||
+ use_attrs.lists(sym::doc).has_word(sym::hidden);
// For cross-crate impl inlining we need to know whether items are
// reachable in documentation -- a previously nonreachable item can be
// (this is done here because we need to know this upfront).
if !res_did.is_local() && !is_no_inline {
let attrs = clean::inline::load_attrs(self.cx, res_did);
- let self_is_hidden = attrs.lists("doc").has_word("hidden");
+ let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
match res {
Res::Def(DefKind::Trait, did) |
Res::Def(DefKind::Struct, did) |
if item.vis.node.is_pub() && self.inside_public_path {
let please_inline = item.attrs.iter().any(|item| {
match item.meta_item_list() {
- Some(ref list) if item.check_name("doc") => {
- list.iter().any(|i| i.check_name("inline"))
+ Some(ref list) if item.check_name(sym::doc) => {
+ list.iter().any(|i| i.check_name(sym::inline))
}
_ => false,
}
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
use rustc::ty::Visibility;
use rustc::util::nodemap::FxHashSet;
+use syntax::symbol::sym;
use std::cell::RefMut;
// Updates node level and returns the updated level
fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
- let is_hidden = self.cx.tcx.get_attrs(did).lists("doc").has_word("hidden");
+ let is_hidden = self.cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden);
let old_level = self.access_levels.map.get(&did).cloned();
// Accessibility levels can only grow
}
}
-impl<'a> PartialEq<&'a str> for Path {
- fn eq(&self, string: &&'a str) -> bool {
- self.segments.len() == 1 && self.segments[0].ident.name == *string
- }
-}
-
impl fmt::Debug for Path {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "path({})", pprust::path_to_string(self))
use crate::parse::ParseSess;
use errors::{Applicability, Handler};
-use syntax_pos::{symbol::Symbol, Span};
+use syntax_pos::{symbol::Symbol, symbol::sym, Span};
use super::{mark_used, MetaItemKind};
/// Determine what `#[unwind]` attribute is present in `attrs`, if any.
pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
attrs.iter().fold(None, |ia, attr| {
- if attr.check_name("unwind") {
+ if attr.check_name(sym::unwind) {
if let Some(meta) = attr.meta() {
if let MetaItemKind::List(items) = meta.node {
if items.len() == 1 {
- if items[0].check_name("allowed") {
+ if items[0].check_name(sym::allowed) {
return Some(UnwindAttr::Allowed);
- } else if items[0].check_name("aborts") {
+ } else if items[0].check_name(sym::aborts) {
return Some(UnwindAttr::Aborts);
}
}
/// 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: &str) -> bool {
+pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
attrs.iter().any(|item| {
- item.check_name("feature") &&
+ item.check_name(sym::feature) &&
item.meta_item_list().map(|list| {
list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name))
}).unwrap_or(false)
'outer: for attr in attrs_iter {
if ![
- "rustc_deprecated",
- "rustc_const_unstable",
- "unstable",
- "stable",
- "rustc_promotable",
- "rustc_allow_const_fn_ptr",
+ sym::rustc_deprecated,
+ sym::rustc_const_unstable,
+ sym::unstable,
+ sym::stable,
+ sym::rustc_promotable,
+ sym::rustc_allow_const_fn_ptr,
].iter().any(|&s| attr.path == s) {
continue // not a stability level
}
let meta = attr.meta();
- if attr.path == "rustc_promotable" {
+ if attr.path == sym::rustc_promotable {
promotable = true;
}
- if attr.path == "rustc_allow_const_fn_ptr" {
+ if attr.path == sym::rustc_allow_const_fn_ptr {
allow_const_fn_ptr = true;
}
// attributes with data
)+
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match mi.name_or_empty().get() {
+ match mi.name_or_empty() {
$(
- stringify!($name)
- => if !get(mi, &mut $name) { continue 'outer },
+ sym::$name => if !get(mi, &mut $name) { continue 'outer },
)+
_ => {
let expected = &[ $( stringify!($name) ),+ ];
}
}
- match meta.name_or_empty().get() {
- "rustc_deprecated" => {
+ match meta.name_or_empty() {
+ sym::rustc_deprecated => {
if rustc_depr.is_some() {
span_err!(diagnostic, item_sp, E0540,
"multiple rustc_deprecated attributes");
}
}
}
- "rustc_const_unstable" => {
+ sym::rustc_const_unstable => {
if rustc_const_unstable.is_some() {
span_err!(diagnostic, item_sp, E0553,
"multiple rustc_const_unstable attributes");
continue
}
}
- "unstable" => {
+ sym::unstable => {
if stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
break
let mut issue = None;
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match mi.name_or_empty().get() {
- "feature" => if !get(mi, &mut feature) { continue 'outer },
- "reason" => if !get(mi, &mut reason) { continue 'outer },
- "issue" => if !get(mi, &mut issue) { continue 'outer },
+ match mi.name_or_empty() {
+ sym::feature => if !get(mi, &mut feature) { continue 'outer },
+ sym::reason => if !get(mi, &mut reason) { continue 'outer },
+ sym::issue => if !get(mi, &mut issue) { continue 'outer },
_ => {
handle_errors(
sess,
}
}
}
- "stable" => {
+ sym::stable => {
if stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
break
for meta in metas {
match meta {
NestedMetaItem::MetaItem(mi) => {
- match mi.name_or_empty().get() {
- "feature" =>
- if !get(mi, &mut feature) { continue 'outer },
- "since" =>
- if !get(mi, &mut since) { continue 'outer },
+ match mi.name_or_empty() {
+ sym::feature => if !get(mi, &mut feature) { continue 'outer },
+ sym::since => if !get(mi, &mut since) { continue 'outer },
_ => {
handle_errors(
sess,
}
pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
- super::first_attr_value_str_by_name(attrs, "crate_name")
+ super::first_attr_value_str_by_name(attrs, sym::crate_name)
}
/// Tests if a cfg-pattern matches the cfg set
// The unwraps below may look dangerous, but we've already asserted
// that they won't fail with the loop above.
- match cfg.name_or_empty().get() {
- "any" => mis.iter().any(|mi| {
+ match cfg.name_or_empty() {
+ sym::any => mis.iter().any(|mi| {
eval_condition(mi.meta_item().unwrap(), sess, eval)
}),
- "all" => mis.iter().all(|mi| {
+ sym::all => mis.iter().all(|mi| {
eval_condition(mi.meta_item().unwrap(), sess, eval)
}),
- "not" => {
+ sym::not => {
if mis.len() != 1 {
span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
return false;
let diagnostic = &sess.span_diagnostic;
'outer: for attr in attrs_iter {
- if !attr.check_name("deprecated") {
+ if !attr.check_name(sym::deprecated) {
continue;
}
for meta in list {
match meta {
NestedMetaItem::MetaItem(mi) => {
- match mi.name_or_empty().get() {
- "since" => if !get(mi, &mut since) { continue 'outer },
- "note" => if !get(mi, &mut note) { continue 'outer },
+ match mi.name_or_empty() {
+ sym::since => if !get(mi, &mut since) { continue 'outer },
+ sym::note => if !get(mi, &mut note) { continue 'outer },
_ => {
handle_errors(
sess,
let mut acc = Vec::new();
let diagnostic = &sess.span_diagnostic;
- if attr.path == "repr" {
+ if attr.path == sym::repr {
if let Some(items) = attr.meta_item_list() {
mark_used(attr);
for item in items {
let mut recognised = false;
if item.is_word() {
- let hint = match item.name_or_empty().get() {
- "C" => Some(ReprC),
- "packed" => Some(ReprPacked(1)),
- "simd" => Some(ReprSimd),
- "transparent" => Some(ReprTransparent),
+ let hint = match item.name_or_empty() {
+ sym::C => Some(ReprC),
+ sym::packed => Some(ReprPacked(1)),
+ sym::simd => Some(ReprSimd),
+ sym::transparent => Some(ReprTransparent),
name => int_type_of_word(name).map(ReprInt),
};
};
let mut literal_error = None;
- if name == "align" {
+ if name == sym::align {
recognised = true;
match parse_alignment(&value.node) {
Ok(literal) => acc.push(ReprAlign(literal)),
Err(message) => literal_error = Some(message)
};
}
- else if name == "packed" {
+ else if name == sym::packed {
recognised = true;
match parse_alignment(&value.node) {
Ok(literal) => acc.push(ReprPacked(literal)),
}
} else {
if let Some(meta_item) = item.meta_item() {
- if meta_item.check_name("align") {
+ if meta_item.check_name(sym::align) {
if let MetaItemKind::NameValue(ref value) = meta_item.node {
recognised = true;
let mut err = struct_span_err!(diagnostic, item.span(), E0693,
acc
}
-fn int_type_of_word(s: &str) -> Option<IntType> {
+fn int_type_of_word(s: Symbol) -> Option<IntType> {
use IntType::*;
match s {
- "i8" => Some(SignedInt(ast::IntTy::I8)),
- "u8" => Some(UnsignedInt(ast::UintTy::U8)),
- "i16" => Some(SignedInt(ast::IntTy::I16)),
- "u16" => Some(UnsignedInt(ast::UintTy::U16)),
- "i32" => Some(SignedInt(ast::IntTy::I32)),
- "u32" => Some(UnsignedInt(ast::UintTy::U32)),
- "i64" => Some(SignedInt(ast::IntTy::I64)),
- "u64" => Some(UnsignedInt(ast::UintTy::U64)),
- "i128" => Some(SignedInt(ast::IntTy::I128)),
- "u128" => Some(UnsignedInt(ast::UintTy::U128)),
- "isize" => Some(SignedInt(ast::IntTy::Isize)),
- "usize" => Some(UnsignedInt(ast::UintTy::Usize)),
+ sym::i8 => Some(SignedInt(ast::IntTy::I8)),
+ sym::u8 => Some(UnsignedInt(ast::UintTy::U8)),
+ sym::i16 => Some(SignedInt(ast::IntTy::I16)),
+ sym::u16 => Some(UnsignedInt(ast::UintTy::U16)),
+ sym::i32 => Some(SignedInt(ast::IntTy::I32)),
+ sym::u32 => Some(UnsignedInt(ast::UintTy::U32)),
+ sym::i64 => Some(SignedInt(ast::IntTy::I64)),
+ sym::u64 => Some(UnsignedInt(ast::UintTy::U64)),
+ sym::i128 => Some(SignedInt(ast::IntTy::I128)),
+ sym::u128 => Some(UnsignedInt(ast::UintTy::U128)),
+ sym::isize => Some(SignedInt(ast::IntTy::Isize)),
+ sym::usize => Some(UnsignedInt(ast::UintTy::Usize)),
_ => None
}
}
use crate::parse::{self, ParseSess, PResult};
use crate::parse::token::{self, Token};
use crate::ptr::P;
-use crate::symbol::{keywords, LocalInternedString, Symbol};
+use crate::symbol::{keywords, Symbol};
use crate::ThinVec;
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
use crate::GLOBALS;
}
/// Returns `true` if this list item is a MetaItem with a name of `name`.
- pub fn check_name<T>(&self, name: T) -> bool
- where
- Path: PartialEq<T>,
- {
+ pub fn check_name(&self, name: Symbol) -> bool {
self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
}
pub fn ident(&self) -> Option<Ident> {
self.meta_item().and_then(|meta_item| meta_item.ident())
}
- pub fn name_or_empty(&self) -> LocalInternedString {
- self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+ pub fn name_or_empty(&self) -> Symbol {
+ self.ident().unwrap_or(keywords::Invalid.ident()).name
}
/// Gets the string value if self is a MetaItem and the MetaItem is a
/// attribute is marked as used.
///
/// To check the attribute name without marking it used, use the `path` field directly.
- pub fn check_name<T>(&self, name: T) -> bool
- where
- Path: PartialEq<T>,
- {
+ pub fn check_name(&self, name: Symbol) -> bool {
let matches = self.path == name;
if matches {
mark_used(self);
None
}
}
- pub fn name_or_empty(&self) -> LocalInternedString {
- self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+ pub fn name_or_empty(&self) -> Symbol {
+ self.ident().unwrap_or(keywords::Invalid.ident()).name
}
pub fn value_str(&self) -> Option<Symbol> {
None
}
}
- pub fn name_or_empty(&self) -> LocalInternedString {
- self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+ pub fn name_or_empty(&self) -> Symbol {
+ self.ident().unwrap_or(keywords::Invalid.ident()).name
}
// #[attribute(name = "value")]
}
}
- pub fn check_name<T>(&self, name: T) -> bool
- where
- Path: PartialEq<T>,
- {
+ pub fn check_name(&self, name: Symbol) -> bool {
self.path == name
}
}
}
-pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
+pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
items.iter().any(|item| {
item.check_name(name)
})
}
-pub fn contains_name(attrs: &[Attribute], name: &str) -> bool {
+pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
attrs.iter().any(|item| {
item.check_name(name)
})
}
-pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> {
+pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> {
attrs.iter().find(|attr| attr.check_name(name))
}
-pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: &'a str)
+pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol)
-> impl Iterator<Item = &'a Attribute> {
attrs.iter().filter(move |attr| attr.check_name(name))
}
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
+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())
use crate::mut_visit::*;
use crate::parse::{token, ParseSess};
use crate::ptr::P;
+use crate::symbol::sym;
use crate::util::map_in_place::MapInPlace;
use errors::Applicability;
/// is in the original source file. Gives a compiler error if the syntax of
/// the attribute is incorrect.
fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
- if !attr.check_name("cfg_attr") {
+ if !attr.check_name(sym::cfg_attr) {
return vec![attr];
}
pub fn maybe_emit_expr_attr_err(&self, attr: &ast::Attribute) {
if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) {
let mut err = feature_err(self.sess,
- "stmt_expr_attributes",
+ sym::stmt_expr_attributes,
attr.span,
GateIssue::Language,
EXPLAIN_STMT_ATTR_SYNTAX);
/// See issue #51279.
pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
for attr in param.attrs() {
- let offending_attr = if attr.check_name("cfg") {
+ let offending_attr = if attr.check_name(sym::cfg) {
"cfg"
- } else if attr.check_name("cfg_attr") {
+ } else if attr.check_name(sym::cfg_attr) {
"cfg_attr"
} else {
continue;
}
fn is_cfg(attr: &ast::Attribute) -> bool {
- attr.check_name("cfg")
+ attr.check_name(sym::cfg)
}
use crate::attr;
use crate::ast::{Item, ItemKind};
+use crate::symbol::sym;
pub enum EntryPointType {
None,
pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
match item.node {
ItemKind::Fn(..) => {
- if attr::contains_name(&item.attrs, "start") {
+ if attr::contains_name(&item.attrs, sym::start) {
EntryPointType::Start
- } else if attr::contains_name(&item.attrs, "main") {
+ } else if attr::contains_name(&item.attrs, sym::main) {
EntryPointType::MainAttr
- } else if item.ident.name == "main" {
+ } else if item.ident.name == sym::main {
if depth == 1 {
// This is a top-level function so can be 'main'
EntryPointType::MainNamed
use crate::parse::{self, parser, DirectoryOwnership};
use crate::parse::token;
use crate::ptr::P;
-use crate::symbol::{keywords, Ident, Symbol};
+use crate::symbol::{keywords, Ident, Symbol, sym};
use crate::ThinVec;
use crate::tokenstream::{self, TokenStream};
let mut last_macro = None;
loop {
if ctxt.outer().expn_info().map_or(None, |info| {
- if info.format.name() == "include" {
+ if info.format.name() == sym::include {
// Stop going up the backtrace once include! is encountered
return None;
}
use crate::ext::base::ExtCtxt;
use crate::ext::build::AstBuilder;
use crate::parse::parser::PathStyle;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, sym};
use syntax_pos::Span;
pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
let mut result = Vec::new();
attrs.retain(|attr| {
- if attr.path != "derive" {
+ if attr.path != sym::derive {
return true;
}
if !attr.is_meta_item_list() {
use crate::parse::parser::Parser;
use crate::ptr::P;
use crate::symbol::Symbol;
-use crate::symbol::keywords;
+use crate::symbol::{keywords, sym};
use crate::tokenstream::{TokenStream, TokenTree};
use crate::visit::{self, Visitor};
use crate::util::map_in_place::MapInPlace;
self.collect_invocations(fragment, &[])
} else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind {
if !item.derive_allowed() {
- let attr = attr::find_by_name(item.attrs(), "derive")
+ let attr = attr::find_by_name(item.attrs(), sym::derive)
.expect("`derive` attribute should exist");
let span = attr.span;
let mut err = self.cx.mut_span_err(span,
}
let mut item = self.fully_configure(item);
- item.visit_attrs(|attrs| attrs.retain(|a| a.path != "derive"));
+ item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
let mut item_with_markers = item.clone();
add_derived_markers(&mut self.cx, item.span(), &traits, &mut item_with_markers);
let derives = derives.entry(invoc.expansion_data.mark).or_default();
if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
!self.cx.ecfg.macros_in_extern_enabled() {
if let SyntaxExtension::NonMacroAttr { .. } = *ext {} else {
- emit_feature_err(&self.cx.parse_sess, "macros_in_extern",
+ emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
invoc.span(), GateIssue::Language,
"macro invocations in `extern {}` blocks are experimental");
}
Annotatable::Item(ref item) => {
match item.node {
ItemKind::Mod(_) if self.cx.ecfg.proc_macro_hygiene() => return,
- ItemKind::Mod(_) => ("modules", "proc_macro_hygiene"),
+ ItemKind::Mod(_) => ("modules", sym::proc_macro_hygiene),
_ => return,
}
}
Annotatable::ForeignItem(_) => return,
Annotatable::Stmt(_) |
Annotatable::Expr(_) if self.cx.ecfg.proc_macro_hygiene() => return,
- Annotatable::Stmt(_) => ("statements", "proc_macro_hygiene"),
- Annotatable::Expr(_) => ("expressions", "proc_macro_hygiene"),
+ Annotatable::Stmt(_) => ("statements", sym::proc_macro_hygiene),
+ Annotatable::Expr(_) => ("expressions", sym::proc_macro_hygiene),
};
emit_feature_err(
self.cx.parse_sess,
if let ast::ItemKind::MacroDef(_) = i.node {
emit_feature_err(
self.parse_sess,
- "proc_macro_hygiene",
+ sym::proc_macro_hygiene,
self.span,
GateIssue::Language,
"procedural macros cannot expand to macro definitions",
// don't stability-check macros in the same crate
// (the only time this is null is for syntax extensions registered as macros)
if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span))
- && !span.allows_unstable(&feature.as_str())
+ && !span.allows_unstable(feature)
&& this.cx.ecfg.features.map_or(true, |feats| {
// macro features will count as lib features
!feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature)
}) {
let explain = format!("macro {}! is unstable", path);
- emit_feature_err(this.cx.parse_sess, &*feature.as_str(), span,
+ emit_feature_err(this.cx.parse_sess, feature, span,
GateIssue::Library(Some(issue)), &explain);
this.cx.trace_macros_diag();
}
}
emit_feature_err(
self.cx.parse_sess,
- "proc_macro_hygiene",
+ sym::proc_macro_hygiene,
span,
GateIssue::Language,
&format!("procedural macros cannot be expanded to {}", kind),
-> Option<ast::Attribute> {
let attr = attrs.iter()
.position(|a| {
- if a.path == "derive" {
+ if a.path == sym::derive {
*after_derive = true;
}
!attr::is_known(a) && !is_builtin_attr(a)
.map(|i| attrs.remove(i));
if let Some(attr) = &attr {
if !self.cx.ecfg.enable_custom_inner_attributes() &&
- attr.style == ast::AttrStyle::Inner && attr.path != "test" {
- emit_feature_err(&self.cx.parse_sess, "custom_inner_attributes",
+ attr.style == ast::AttrStyle::Inner && attr.path != sym::test {
+ emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
attr.span, GateIssue::Language,
"non-builtin inner attributes are unstable");
}
self.check_attribute_inner(attr, features);
// macros are expanded before any lint passes so this warning has to be hardcoded
- if attr.path == "derive" {
+ if attr.path == sym::derive {
self.cx.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
.note("this may become a hard error in a future release")
.emit();
let inline_module = item.span.contains(inner) || inner.is_dummy();
if inline_module {
- if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
+ if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, sym::path) {
self.cx.current_expansion.directory_ownership =
DirectoryOwnership::Owned { relative: None };
module.directory.push(&*path.as_str());
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("doc") {
+ if !at.check_name(sym::doc) {
return noop_visit_attribute(at, self);
}
if let Some(list) = at.meta_item_list() {
- if !list.iter().any(|it| it.check_name("include")) {
+ if !list.iter().any(|it| it.check_name(sym::include)) {
return noop_visit_attribute(at, self);
}
let mut items = vec![];
for mut it in list {
- if !it.check_name("include") {
+ if !it.check_name(sym::include) {
items.push({ noop_visit_meta_list_item(&mut it, self); it });
continue;
}
use crate::parse::{self, token, DirectoryOwnership};
use crate::print::pprust;
use crate::ptr::P;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, sym};
use crate::tokenstream;
use smallvec::SmallVec;
/* __rust_unstable_column!(): expands to the current column number */
pub fn expand_column_gated(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
-> Box<dyn base::MacResult+'static> {
- if sp.allows_unstable("__rust_unstable_column") {
+ if sp.allows_unstable(sym::__rust_unstable_column) {
expand_column(cx, sp, tts)
} else {
cx.span_fatal(sp, "the __rust_unstable_column macro is unstable");
use crate::parse::parser::Parser;
use crate::parse::token::{self, NtTT};
use crate::parse::token::Token::*;
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, keywords, sym};
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
use errors::FatalError;
});
if body.legacy {
- let allow_internal_unstable = attr::find_by_name(&def.attrs, "allow_internal_unstable")
+ let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable)
.map(|attr| attr
.meta_item_list()
.map(|list| list.iter()
vec![Symbol::intern("allow_internal_unstable_backcompat_hack")].into()
})
);
- let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe");
+ let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe);
let mut local_inner_macros = false;
- if let Some(macro_export) = attr::find_by_name(&def.attrs, "macro_export") {
+ if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
if let Some(l) = macro_export.meta_item_list() {
- local_inner_macros = attr::list_contains_name(&l, "local_inner_macros");
+ local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
}
}
edition,
}
} else {
- let is_transparent = attr::contains_name(&def.attrs, "rustc_transparent_macro");
+ let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro);
SyntaxExtension::DeclMacro {
expander,
TokenTree::Sequence(span, ref seq) => {
if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| {
match *seq_tt {
- TokenTree::MetaVarDecl(_, _, id) => id.name == "vis",
+ TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis,
TokenTree::Sequence(_, ref sub_seq) =>
sub_seq.op == quoted::KleeneOp::ZeroOrMore
|| sub_seq.op == quoted::KleeneOp::ZeroOrOne,
match *tok {
TokenTree::Token(_, ref tok) => match *tok {
FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
- Ident(i, false) if i.name == "if" || i.name == "in" => IsInFollow::Yes,
+ Ident(i, false) if i.name == keywords::If.name() ||
+ i.name == keywords::In.name() => IsInFollow::Yes,
_ => IsInFollow::No(tokens),
},
_ => IsInFollow::No(tokens),
OpenDelim(token::DelimToken::Bracket) |
Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi |
BinOp(token::Or) => IsInFollow::Yes,
- Ident(i, false) if i.name == "as" || i.name == "where" => IsInFollow::Yes,
+ Ident(i, false) if i.name == keywords::As.name() ||
+ i.name == keywords::Where.name() => IsInFollow::Yes,
_ => IsInFollow::No(tokens),
},
- TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => IsInFollow::Yes,
+ TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block =>
+ IsInFollow::Yes,
_ => IsInFollow::No(tokens),
}
},
match *tok {
TokenTree::Token(_, ref tok) => match *tok {
Comma => IsInFollow::Yes,
- Ident(i, is_raw) if is_raw || i.name != "priv" => IsInFollow::Yes,
+ Ident(i, is_raw) if is_raw || i.name != keywords::Priv.name() =>
+ IsInFollow::Yes,
ref tok => if tok.can_begin_type() {
IsInFollow::Yes
} else {
IsInFollow::No(tokens)
}
},
- TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident"
- || frag.name == "ty"
- || frag.name == "path" => IsInFollow::Yes,
+ TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::ident
+ || frag.name == sym::ty
+ || frag.name == sym::path =>
+ IsInFollow::Yes,
_ => IsInFollow::No(tokens),
}
},
use crate::edition::{ALL_EDITIONS, Edition};
use crate::visit::{self, FnKind, Visitor};
use crate::parse::{token, ParseSess};
-use crate::symbol::Symbol;
+use crate::symbol::{Symbol, keywords, sym};
use crate::tokenstream::TokenTree;
use errors::{DiagnosticBuilder, Handler};
use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::abi::Abi;
-use syntax_pos::{Span, DUMMY_SP, symbols};
+use syntax_pos::{Span, DUMMY_SP};
use log::debug;
use lazy_static::lazy_static;
/// Represents active features that are currently being implemented or
/// currently being considered for addition/removal.
const ACTIVE_FEATURES:
- &[(&str, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
- &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+];
+ &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
+ &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
/// A set of features to be used by later passes.
#[derive(Clone)]
($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
/// Represents unstable features which have since been removed (it was once Active)
- const REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
- $((stringify!($feature), $ver, $issue, $reason)),+
+ const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+ $((sym::$feature, $ver, $issue, $reason)),+
];
};
($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
/// Represents stable features which have since been removed (it was once Accepted)
- const STABLE_REMOVED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
- $((stringify!($feature), $ver, $issue, None)),+
+ const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+ $((sym::$feature, $ver, $issue, None)),+
];
};
($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
/// Those language feature has since been Accepted (it was once Active)
- const ACCEPTED_FEATURES: &[(&str, &str, Option<u32>, Option<&str>)] = &[
- $((stringify!($feature), $ver, $issue, None)),+
+ const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+ $((sym::$feature, $ver, $issue, None)),+
];
}
}
// Some features are known to be incomplete and using them is likely to have
// unanticipated results, such as compiler crashes. We warn the user about these
// to alert them.
-const INCOMPLETE_FEATURES: &[&str] = &[
- "generic_associated_types",
- "const_generics"
+const INCOMPLETE_FEATURES: &[Symbol] = &[
+ sym::generic_associated_types,
+ sym::const_generics
];
declare_features! (
pub enum AttributeGate {
/// Is gated by a given feature gate, reason
/// and function to check if enabled
- Gated(Stability, &'static str, &'static str, fn(&Features) -> bool),
+ Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
/// Ungated attribute, can be used on all release channels
Ungated,
// Normal attributes
(
- symbols::warn,
+ sym::warn,
Normal,
template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
Ungated
),
(
- symbols::allow,
+ sym::allow,
Normal,
template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
Ungated
),
(
- symbols::forbid,
+ sym::forbid,
Normal,
template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
Ungated
),
(
- symbols::deny,
+ sym::deny,
Normal,
template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
Ungated
),
- (symbols::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
- (symbols::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
- (symbols::plugin_registrar, Normal, template!(Word), Ungated),
-
- (symbols::cfg, Normal, template!(List: "predicate"), Ungated),
- (symbols::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
- (symbols::main, Normal, template!(Word), Ungated),
- (symbols::start, Normal, template!(Word), Ungated),
- (symbols::repr, Normal, template!(List: "C, packed, ..."), Ungated),
- (symbols::path, Normal, template!(NameValueStr: "file"), Ungated),
- (symbols::automatically_derived, Normal, template!(Word), Ungated),
- (symbols::no_mangle, Normal, template!(Word), Ungated),
- (symbols::no_link, Normal, template!(Word), Ungated),
- (symbols::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
+ (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
+ (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
+ (sym::plugin_registrar, Normal, template!(Word), Ungated),
+
+ (sym::cfg, Normal, template!(List: "predicate"), Ungated),
+ (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
+ (sym::main, Normal, template!(Word), Ungated),
+ (sym::start, Normal, template!(Word), Ungated),
+ (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
+ (sym::path, Normal, template!(NameValueStr: "file"), Ungated),
+ (sym::automatically_derived, Normal, template!(Word), Ungated),
+ (sym::no_mangle, Normal, template!(Word), Ungated),
+ (sym::no_link, Normal, template!(Word), Ungated),
+ (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
(
- symbols::should_panic,
+ sym::should_panic,
Normal,
template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
Ungated
),
- (symbols::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
- (symbols::no_implicit_prelude, Normal, template!(Word), Ungated),
- (symbols::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
- (symbols::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
- "link_args",
+ (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
+ (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
+ (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
+ (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
+ sym::link_args,
"the `link_args` attribute is experimental and not \
portable across platforms, it is recommended to \
use `#[link(name = \"foo\")] instead",
cfg_fn!(link_args))),
- (symbols::macro_escape, Normal, template!(Word), Ungated),
+ (sym::macro_escape, Normal, template!(Word), Ungated),
// RFC #1445.
- (symbols::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "structural_match",
+ (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::structural_match,
"the semantics of constant patterns is \
not yet settled",
cfg_fn!(structural_match))),
// RFC #2008
- (symbols::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "non_exhaustive",
+ (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::non_exhaustive,
"non exhaustive is an experimental feature",
cfg_fn!(non_exhaustive))),
// RFC #1268
- (symbols::marker, Normal, template!(Word), Gated(Stability::Unstable,
- "marker_trait_attr",
+ (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::marker_trait_attr,
"marker traits is an experimental feature",
cfg_fn!(marker_trait_attr))),
- (symbols::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
- "plugin",
+ (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
+ sym::plugin,
"compiler plugins are experimental \
and possibly buggy",
cfg_fn!(plugin))),
- (symbols::no_std, CrateLevel, template!(Word), Ungated),
- (symbols::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
- "no_core",
+ (sym::no_std, CrateLevel, template!(Word), Ungated),
+ (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
+ sym::no_core,
"no_core is experimental",
cfg_fn!(no_core))),
- (symbols::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
- "lang_items",
+ (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
+ sym::lang_items,
"language items are subject to change",
cfg_fn!(lang_items))),
- (symbols::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
+ (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
Gated(Stability::Unstable,
- "linkage",
+ sym::linkage,
"the `linkage` attribute is experimental \
and not portable across platforms",
cfg_fn!(linkage))),
- (symbols::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "thread_local",
+ (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::thread_local,
"`#[thread_local]` is an experimental feature, and does \
not currently handle destructors",
cfg_fn!(thread_local))),
- (symbols::rustc_on_unimplemented, Whitelisted, template!(List:
+ (sym::rustc_on_unimplemented, Whitelisted, template!(List:
r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
NameValueStr: "message"),
Gated(Stability::Unstable,
- "on_unimplemented",
+ sym::on_unimplemented,
"the `#[rustc_on_unimplemented]` attribute \
is an experimental feature",
cfg_fn!(on_unimplemented))),
- (symbols::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
+ (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
Gated(Stability::Unstable,
- "rustc_const_unstable",
+ sym::rustc_const_unstable,
"the `#[rustc_const_unstable]` attribute \
is an internal feature",
cfg_fn!(rustc_const_unstable))),
- (symbols::global_allocator, Normal, template!(Word), Ungated),
- (symbols::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "allocator_internals",
+ (sym::global_allocator, Normal, template!(Word), Ungated),
+ (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::allocator_internals,
"the `#[default_lib_allocator]` \
attribute is an experimental feature",
cfg_fn!(allocator_internals))),
- (symbols::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
- "allocator_internals",
+ (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::allocator_internals,
"the `#[needs_allocator]` \
attribute is an experimental \
feature",
cfg_fn!(allocator_internals))),
- (symbols::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "panic_runtime",
+ (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::panic_runtime,
"the `#[panic_runtime]` attribute is \
an experimental feature",
cfg_fn!(panic_runtime))),
- (symbols::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "needs_panic_runtime",
+ (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::needs_panic_runtime,
"the `#[needs_panic_runtime]` \
attribute is an experimental \
feature",
cfg_fn!(needs_panic_runtime))),
- (symbols::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_outlives]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_variance]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_layout, Normal, template!(List: "field1, field2, ..."),
+ (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_layout]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
+ (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_layout_scalar_valid_range_start]` attribute \
is just used to enable niche optimizations in libcore \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
+ (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_layout_scalar_valid_range_end]` attribute \
is just used to enable niche optimizations in libcore \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_regions]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_error]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"this attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
+ (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_if_this_changed]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
+ (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_if_this_changed]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
+ (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
/*opt*/ except = "...""#),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_dirty]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
+ (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
/*opt*/ except = "...""#),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_clean]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
(
- symbols::rustc_partition_reused,
+ sym::rustc_partition_reused,
Whitelisted,
template!(List: r#"cfg = "...", module = "...""#),
Gated(
Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"this attribute \
is just used for rustc unit tests \
and will never be stable",
)
),
(
- symbols::rustc_partition_codegened,
+ sym::rustc_partition_codegened,
Whitelisted,
template!(List: r#"cfg = "...", module = "...""#),
Gated(
Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"this attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs),
)
),
- (symbols::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
+ (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
kind = "...""#),
Gated(Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"this attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"this attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"internal rustc attributes will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"internal rustc attributes will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_mir]` attribute \
is just used for rustc unit tests \
and will never be stable",
cfg_fn!(rustc_attrs))),
(
- symbols::rustc_inherit_overflow_checks,
+ sym::rustc_inherit_overflow_checks,
Whitelisted,
template!(Word),
Gated(
Stability::Unstable,
- "rustc_attrs",
+ sym::rustc_attrs,
"the `#[rustc_inherit_overflow_checks]` \
attribute is just used to control \
overflow checking behavior of several \
)
),
- (symbols::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_dump_program_clauses]` \
attribute is just used for rustc unit \
tests and will never be stable",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"the `#[rustc_test_marker]` attribute \
is used internally to track tests",
cfg_fn!(rustc_attrs))),
- (symbols::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_transparent_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"used internally for testing macro hygiene",
cfg_fn!(rustc_attrs))),
- (symbols::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "compiler_builtins",
+ (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::compiler_builtins,
"the `#[compiler_builtins]` attribute is used to \
identify the `compiler_builtins` crate which \
contains compiler-rt intrinsics and will never be \
stable",
cfg_fn!(compiler_builtins))),
- (symbols::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "sanitizer_runtime",
+ (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::sanitizer_runtime,
"the `#[sanitizer_runtime]` attribute is used to \
identify crates that contain the runtime of a \
sanitizer and will never be stable",
cfg_fn!(sanitizer_runtime))),
- (symbols::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "profiler_runtime",
+ (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::profiler_runtime,
"the `#[profiler_runtime]` attribute is used to \
identify the `profiler_builtins` crate which \
contains the profiler runtime and will never be \
stable",
cfg_fn!(profiler_runtime))),
- (symbols::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
+ (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
Gated(Stability::Unstable,
- "allow_internal_unstable",
+ sym::allow_internal_unstable,
EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
cfg_fn!(allow_internal_unstable))),
- (symbols::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
- "allow_internal_unsafe",
+ (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::allow_internal_unsafe,
EXPLAIN_ALLOW_INTERNAL_UNSAFE,
cfg_fn!(allow_internal_unsafe))),
- (symbols::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "fundamental",
+ (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::fundamental,
"the `#[fundamental]` attribute \
is an experimental feature",
cfg_fn!(fundamental))),
- (symbols::proc_macro_derive, Normal, template!(List: "TraitName, \
+ (sym::proc_macro_derive, Normal, template!(List: "TraitName, \
/*opt*/ attributes(name1, name2, ...)"),
Ungated),
- (symbols::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_copy_clone_marker, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"internal implementation detail",
cfg_fn!(rustc_attrs))),
// FIXME: #14408 whitelist docs since rustdoc looks at them
(
- symbols::doc,
+ sym::doc,
Whitelisted,
template!(List: "hidden|inline|...", NameValueStr: "string"),
Ungated
// FIXME: #14406 these are processed in codegen, which happens after the
// lint pass
- (symbols::cold, Whitelisted, template!(Word), Ungated),
- (symbols::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "naked_functions",
+ (sym::cold, Whitelisted, template!(Word), Ungated),
+ (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::naked_functions,
"the `#[naked]` attribute \
is an experimental feature",
cfg_fn!(naked_functions))),
- (symbols::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "ffi_returns_twice",
+ (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::ffi_returns_twice,
"the `#[ffi_returns_twice]` attribute \
is an experimental feature",
cfg_fn!(ffi_returns_twice))),
- (symbols::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
- (symbols::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
- (symbols::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
- (symbols::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
+ (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
+ (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
+ (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
+ (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
/*opt*/ cfg = "...""#), Ungated),
- (symbols::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
- (symbols::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
- (symbols::no_builtins, Whitelisted, template!(Word), Ungated),
- (symbols::no_debug, Whitelisted, template!(Word), Gated(
+ (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
+ (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
+ (sym::no_builtins, Whitelisted, template!(Word), Ungated),
+ (sym::no_debug, Whitelisted, template!(Word), Gated(
Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
- "no_debug",
+ sym::no_debug,
"the `#[no_debug]` attribute was an experimental feature that has been \
deprecated due to lack of demand",
cfg_fn!(no_debug))),
(
- symbols::omit_gdb_pretty_printer_section,
+ sym::omit_gdb_pretty_printer_section,
Whitelisted,
template!(Word),
Gated(
Stability::Unstable,
- "omit_gdb_pretty_printer_section",
+ sym::omit_gdb_pretty_printer_section,
"the `#[omit_gdb_pretty_printer_section]` \
attribute is just used for the Rust test \
suite",
cfg_fn!(omit_gdb_pretty_printer_section)
)
),
- (symbols::unsafe_destructor_blind_to_params,
+ (sym::unsafe_destructor_blind_to_params,
Normal,
template!(Word),
Gated(Stability::Deprecated("https://github.com/rust-lang/rust/issues/34761",
Some("replace this attribute with `#[may_dangle]`")),
- "dropck_parametricity",
+ sym::dropck_parametricity,
"unsafe_destructor_blind_to_params has been replaced by \
may_dangle and will be removed in the future",
cfg_fn!(dropck_parametricity))),
- (symbols::may_dangle,
+ (sym::may_dangle,
Normal,
template!(Word),
Gated(Stability::Unstable,
- "dropck_eyepatch",
+ sym::dropck_eyepatch,
"may_dangle has unstable semantics and may be removed in the future",
cfg_fn!(dropck_eyepatch))),
- (symbols::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
- "unwind_attributes",
+ (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
+ sym::unwind_attributes,
"#[unwind] is experimental",
cfg_fn!(unwind_attributes))),
- (symbols::used, Whitelisted, template!(Word), Ungated),
+ (sym::used, Whitelisted, template!(Word), Ungated),
// used in resolve
- (symbols::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "prelude_import",
+ (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::prelude_import,
"`#[prelude_import]` is for use by rustc only",
cfg_fn!(prelude_import))),
// FIXME: #14407 these are only looked at on-demand so we can't
// guarantee they'll have already been checked
(
- symbols::rustc_deprecated,
+ sym::rustc_deprecated,
Whitelisted,
template!(List: r#"since = "version", reason = "...""#),
Ungated
),
- (symbols::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
+ (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
(
- symbols::stable,
+ sym::stable,
Whitelisted,
template!(List: r#"feature = "name", since = "version""#),
Ungated
),
(
- symbols::unstable,
+ sym::unstable,
Whitelisted,
template!(List: r#"feature = "name", reason = "...", issue = "N""#),
Ungated
),
- (symbols::deprecated,
+ (sym::deprecated,
Normal,
template!(
Word,
Ungated
),
- (symbols::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
- "unboxed_closures",
+ (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::unboxed_closures,
"unboxed_closures are still evolving",
cfg_fn!(unboxed_closures))),
- (symbols::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
+ (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
- (symbols::proc_macro_attribute, Normal, template!(Word), Ungated),
- (symbols::proc_macro, Normal, template!(Word), Ungated),
+ (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
+ (sym::proc_macro, Normal, template!(Word), Ungated),
- (symbols::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"used internally by rustc",
cfg_fn!(rustc_attrs))),
- (symbols::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
- "allow_fail",
+ (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::allow_fail,
"allow_fail attribute is currently unstable",
cfg_fn!(allow_fail))),
- (symbols::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"this is an internal attribute that will \
never be stable",
cfg_fn!(rustc_attrs))),
// whitelists "identity-like" conversion methods to suggest on type mismatch
- (symbols::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
- "rustc_attrs",
+ (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
+ sym::rustc_attrs,
"this is an internal attribute that will \
never be stable",
cfg_fn!(rustc_attrs))),
(
- symbols::rustc_args_required_const,
+ sym::rustc_args_required_const,
Whitelisted,
template!(List: "N"),
- Gated(Stability::Unstable, "rustc_attrs", "never will be stable", cfg_fn!(rustc_attrs))
+ Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
+ cfg_fn!(rustc_attrs))
),
// RFC 2070
- (symbols::panic_handler, Normal, template!(Word), Ungated),
+ (sym::panic_handler, Normal, template!(Word), Ungated),
- (symbols::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
- "alloc_error_handler",
+ (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
+ sym::alloc_error_handler,
"#[alloc_error_handler] is an unstable feature",
cfg_fn!(alloc_error_handler))),
// RFC 2412
- (symbols::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
- "optimize_attribute",
+ (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
+ sym::optimize_attribute,
"#[optimize] attribute is an unstable feature",
cfg_fn!(optimize_attribute))),
// Crate level attributes
- (symbols::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
- (symbols::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
- (symbols::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
- (symbols::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
- (symbols::no_start, CrateLevel, template!(Word), Ungated),
- (symbols::no_main, CrateLevel, template!(Word), Ungated),
- (symbols::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
- (symbols::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
- (symbols::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
- "custom_test_frameworks",
+ (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
+ (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
+ (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
+ (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
+ (sym::no_start, CrateLevel, template!(Word), Ungated),
+ (sym::no_main, CrateLevel, template!(Word), Ungated),
+ (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
+ (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
+ (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
+ sym::custom_test_frameworks,
EXPLAIN_CUSTOM_TEST_FRAMEWORKS,
cfg_fn!(custom_test_frameworks))),
];
}
// cfg(...)'s that are feature gated
-const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[
+const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
// (name in cfg, feature, function to check if the feature is enabled)
- ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)),
- ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)),
- ("rustdoc", "doc_cfg", cfg_fn!(doc_cfg)),
+ (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
+ (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
+ (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
];
#[derive(Debug)]
struct Context<'a> {
features: &'a Features,
parse_sess: &'a ParseSess,
- plugin_attributes: &'a [(String, AttributeType)],
+ plugin_attributes: &'a [(Symbol, AttributeType)],
}
macro_rules! gate_feature_fn {
macro_rules! gate_feature {
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
- stringify!($feature), $explain, GateStrength::Hard)
+ sym::$feature, $explain, GateStrength::Hard)
};
($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
- stringify!($feature), $explain, $level)
+ sym::$feature, $explain, $level)
};
}
self, has_feature, attr.span, name, desc, GateStrength::Hard
);
}
- } else if name == symbols::doc {
+ } else if name == sym::doc {
if let Some(content) = attr.meta_item_list() {
- if content.iter().any(|c| c.check_name(symbols::include)) {
+ if content.iter().any(|c| c.check_name(sym::include)) {
gate_feature!(self, external_doc, attr.span,
"#[doc(include = \"...\")] is experimental"
);
debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
return;
}
- for &(ref n, ref ty) in self.plugin_attributes {
- if attr.path == &**n {
+ for &(n, ty) in self.plugin_attributes {
+ if attr.path == n {
// Plugins can't gate attributes, so we don't check for it
// unlike the code above; we only use this loop to
// short-circuit to avoid the checks below.
}
}
if !attr::is_known(attr) {
- if attr.name_or_empty().starts_with("rustc_") {
+ if attr.name_or_empty().as_str().starts_with("rustc_") {
let msg = "unless otherwise specified, attributes with the prefix `rustc_` \
are reserved for internal compiler diagnostics";
gate_feature!(self, rustc_attrs, attr.span, msg);
);
}
-fn find_lang_feature_issue(feature: &str) -> Option<u32> {
+fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
let issue = info.2;
// FIXME (#28244): enforce that active features have issue numbers
pub fn emit_feature_err(
sess: &ParseSess,
- feature: &str,
+ feature: Symbol,
span: Span,
issue: GateIssue,
explain: &str,
pub fn feature_err<'a>(
sess: &'a ParseSess,
- feature: &str,
+ feature: Symbol,
span: Span,
issue: GateIssue,
explain: &str,
fn leveled_feature_err<'a>(
sess: &'a ParseSess,
- feature: &str,
+ feature: Symbol,
span: Span,
issue: GateIssue,
explain: &str,
macro_rules! gate_feature_post {
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
let (cx, span) = ($cx, $span);
- if !span.allows_unstable(stringify!($feature)) {
+ if !span.allows_unstable(sym::$feature) {
gate_feature!(cx.context, $feature, span, $explain)
}
}};
($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
let (cx, span) = ($cx, $span);
- if !span.allows_unstable(stringify!($feature)) {
+ if !span.allows_unstable(sym::$feature) {
gate_feature!(cx.context, $feature, span, $explain, $level)
}
}}
template: AttributeTemplate) {
// Some special attributes like `cfg` must be checked
// before the generic check, so we skip them here.
- let should_skip = |name| name == symbols::cfg;
+ let should_skip = |name| name == sym::cfg;
// Some of previously accepted forms were used in practice,
// report them as warnings for now.
- let should_warn = |name| name == symbols::doc || name == symbols::ignore ||
- name == symbols::inline || name == symbols::link;
+ let should_warn = |name| name == sym::doc || name == sym::ignore ||
+ name == sym::inline || name == sym::link;
match attr.parse_meta(self.context.parse_sess) {
Ok(meta) => if !should_skip(name) && !template.compatible(&meta.node) {
// check for gated attributes
self.context.check_attribute(attr, attr_info, false);
- if attr.check_name(symbols::doc) {
+ if attr.check_name(sym::doc) {
if let Some(content) = attr.meta_item_list() {
- if content.len() == 1 && content[0].check_name(symbols::cfg) {
+ if content.len() == 1 && content[0].check_name(sym::cfg) {
gate_feature_post!(&self, doc_cfg, attr.span,
"#[doc(cfg(...))] is experimental"
);
- } else if content.iter().any(|c| c.check_name(symbols::masked)) {
+ } else if content.iter().any(|c| c.check_name(sym::masked)) {
gate_feature_post!(&self, doc_masked, attr.span,
"#[doc(masked)] is experimental"
);
- } else if content.iter().any(|c| c.check_name(symbols::spotlight)) {
+ } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
gate_feature_post!(&self, doc_spotlight, attr.span,
"#[doc(spotlight)] is experimental"
);
- } else if content.iter().any(|c| c.check_name(symbols::alias)) {
+ } else if content.iter().any(|c| c.check_name(sym::alias)) {
gate_feature_post!(&self, doc_alias, attr.span,
"#[doc(alias = \"...\")] is experimental"
);
- } else if content.iter().any(|c| c.check_name(symbols::keyword)) {
+ } else if content.iter().any(|c| c.check_name(sym::keyword)) {
gate_feature_post!(&self, doc_keyword, attr.span,
"#[doc(keyword = \"...\")] is experimental"
);
fn visit_item(&mut self, i: &'a ast::Item) {
match i.node {
ast::ItemKind::Const(_,_) => {
- if i.ident.name == "_" {
+ if i.ident.name == keywords::Underscore.name() {
gate_feature_post!(&self, underscore_const_names, i.span,
"naming constants with `_` is unstable");
}
}
ast::ItemKind::Fn(..) => {
- if attr::contains_name(&i.attrs[..], "plugin_registrar") {
+ if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
gate_feature_post!(&self, plugin_registrar, i.span,
"compiler plugins are experimental and possibly buggy");
}
- if attr::contains_name(&i.attrs[..], "start") {
+ if attr::contains_name(&i.attrs[..], sym::start) {
gate_feature_post!(&self, start, i.span,
"a #[start] function is an experimental \
feature whose signature may change \
over time");
}
- if attr::contains_name(&i.attrs[..], "main") {
+ if attr::contains_name(&i.attrs[..], sym::main) {
gate_feature_post!(&self, main, i.span,
"declaration of a nonstandard #[main] \
function may change over time, for now \
}
ast::ItemKind::Struct(..) => {
- for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+ for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
- if item.check_name(symbols::simd) {
+ if item.check_name(sym::simd) {
gate_feature_post!(&self, repr_simd, attr.span,
"SIMD types are experimental and possibly buggy");
}
}
ast::ItemKind::Enum(..) => {
- for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+ for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
- if item.check_name(symbols::align) {
+ if item.check_name(sym::align) {
gate_feature_post!(&self, repr_align_enum, attr.span,
"`#[repr(align(x))]` on enums is experimental");
}
match i.node {
ast::ForeignItemKind::Fn(..) |
ast::ForeignItemKind::Static(..) => {
- let link_name = attr::first_attr_value_str_by_name(&i.attrs, "link_name");
+ let link_name = attr::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
if edition <= crate_edition {
// The `crate_edition` implies its respective umbrella feature-gate
// (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
- edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition);
+ edition_enabled_features.insert(edition.feature_name(), edition);
}
}
if let Some(f_edition) = f_edition {
if f_edition <= crate_edition {
set(&mut features, DUMMY_SP);
- edition_enabled_features.insert(Symbol::intern(name), crate_edition);
+ edition_enabled_features.insert(name, crate_edition);
}
}
}
// 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(symbols::feature) {
+ if !attr.check_name(sym::feature) {
continue
}
// FIXME(Manishearth) there is currently no way to set
// lib features by edition
set(&mut features, DUMMY_SP);
- edition_enabled_features.insert(Symbol::intern(name), *edition);
+ edition_enabled_features.insert(name, *edition);
}
}
}
}
for attr in krate_attrs {
- if !attr.check_name(symbols::feature) {
+ if !attr.check_name(sym::feature) {
continue
}
pub fn check_crate(krate: &ast::Crate,
sess: &ParseSess,
features: &Features,
- plugin_attributes: &[(String, AttributeType)],
+ plugin_attributes: &[(Symbol, AttributeType)],
unstable: UnstableFeatures) {
maybe_stage_features(&sess.span_diagnostic, krate, unstable);
let ctx = Context {
};
if !allow_features {
for attr in &krate.attrs {
- if attr.check_name(symbols::feature) {
+ if attr.check_name(sym::feature) {
let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
span_err!(span_handler, attr.span, E0554,
"#![feature] may not be used on the {} release channel",
#[test]
fn string_to_tts_macro () {
with_globals(|| {
+ use crate::symbol::sym;
+
let tts: Vec<_> =
string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect();
let tts: &[TokenTree] = &tts[..];
Some(&TokenTree::Token(_, token::Ident(name_zip, false))),
Some(&TokenTree::Delimited(_, macro_delim, ref macro_tts)),
)
- if name_macro_rules.name == "macro_rules"
- && name_zip.name == "zip" => {
+ if name_macro_rules.name == sym::macro_rules
+ && name_zip.name.as_str() == "zip" => {
let tts = ¯o_tts.trees().collect::<Vec<_>>();
match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
(
Some(&TokenTree::Token(_, token::Dollar)),
Some(&TokenTree::Token(_, token::Ident(ident, false))),
)
- if first_delim == token::Paren && ident.name == "a" => {},
+ if first_delim == token::Paren && ident.name.as_str() == "a" => {},
_ => panic!("value 3: {:?} {:?}", first_delim, first_tts),
}
let tts = &second_tts.trees().collect::<Vec<_>>();
Some(&TokenTree::Token(_, token::Dollar)),
Some(&TokenTree::Token(_, token::Ident(ident, false))),
)
- if second_delim == token::Paren && ident.name == "a" => {},
+ if second_delim == token::Paren && ident.name.as_str() == "a" => {},
_ => panic!("value 4: {:?} {:?}", second_delim, second_tts),
}
},
#[test] fn crlf_doc_comments() {
with_globals(|| {
+ use crate::symbol::sym;
+
let sess = ParseSess::new(FilePathMapping::empty());
let name_1 = FileName::Custom("crlf_source_1".to_string());
let source = "/// doc comment\r\nfn foo() {}".to_string();
let item = parse_item_from_source_str(name_1, source, &sess)
.unwrap().unwrap();
- let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
- assert_eq!(doc, "/// doc comment");
+ let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap();
+ assert_eq!(doc.as_str(), "/// doc comment");
let name_2 = FileName::Custom("crlf_source_2".to_string());
let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
let item = parse_item_from_source_str(name_2, source, &sess)
.unwrap().unwrap();
- let docs = item.attrs.iter().filter(|a| a.path == "doc")
+ let docs = item.attrs.iter().filter(|a| a.path == sym::doc)
.map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
assert_eq!(&docs[..], b);
let name_3 = FileName::Custom("clrf_source_3".to_string());
let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string();
let item = parse_item_from_source_str(name_3, source, &sess).unwrap().unwrap();
- let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
- assert_eq!(doc, "/** doc comment\n * with CRLF */");
+ let doc = first_attr_value_str_by_name(&item.attrs, sym::doc).unwrap();
+ assert_eq!(doc.as_str(), "/** doc comment\n * with CRLF */");
});
}
use crate::parse::PResult;
use crate::ThinVec;
use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
-use crate::symbol::{keywords, Symbol};
+use crate::symbol::{keywords, sym, Symbol};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
use rustc_target::spec::abi::{self, Abi};
(ident, ast::MacroDef { tokens: tokens.into(), legacy: false })
}
- token::Ident(ident, _) if ident.name == "macro_rules" &&
+ token::Ident(ident, _) if ident.name == sym::macro_rules &&
self.look_ahead(1, |t| *t == token::Not) => {
let prev_span = self.prev_span;
self.complain_if_pub_macro(&vis.node, prev_span);
}
fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
- if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
+ if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
self.directory.path.to_mut().push(&path.as_str());
self.directory.ownership = DirectoryOwnership::Owned { relative: None };
} else {
}
pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
- if let Some(s) = attr::first_attr_value_str_by_name(attrs, "path") {
+ if let Some(s) = attr::first_attr_value_str_by_name(attrs, sym::path) {
let s = s.as_str();
// On windows, the base path might have the form
use crate::attr;
use crate::edition::Edition;
use crate::ext::hygiene::{Mark, SyntaxContext};
-use crate::symbol::{Symbol, keywords};
+use crate::symbol::{Symbol, keywords, sym};
use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan};
use crate::ptr::P;
use crate::tokenstream::TokenStream;
}
thread_local! {
+ // A `Symbol` might make more sense here, but it doesn't work, probably for
+ // reasons relating to the use of thread-local storage for the Symbol
+ // interner.
static INJECTED_CRATE_NAME: Cell<Option<&'static str>> = Cell::new(None);
}
let rust_2018 = edition >= Edition::Edition2018;
// the first name in this list is the crate name of the crate with the prelude
- let names: &[&str] = if attr::contains_name(&krate.attrs, "no_core") {
+ let names: &[&str] = if attr::contains_name(&krate.attrs, sym::no_core) {
return krate;
- } else if attr::contains_name(&krate.attrs, "no_std") {
- if attr::contains_name(&krate.attrs, "compiler_builtins") {
+ } else if attr::contains_name(&krate.attrs, sym::no_std) {
+ if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
&["core"]
} else {
&["core", "compiler_builtins"]
use crate::print::pprust;
use crate::ast::{self, Ident};
use crate::ptr::P;
-use crate::symbol::{self, Symbol, keywords};
+use crate::symbol::{self, Symbol, keywords, sym};
use crate::ThinVec;
struct Test {
// 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,
- "reexport_test_harness_main");
+ attr::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
ident,
attrs: attrs.into_iter()
.filter(|attr| {
- !attr.check_name("main") && !attr.check_name("start")
+ !attr.check_name(sym::main) && !attr.check_name(sym::start)
})
.chain(iter::once(allow_dead_code))
.collect(),
test_cases: Vec::new(),
reexport_test_harness_main,
// N.B., doesn't consider the value of `--crate-name` passed on the command line.
- is_libtest: attr::find_crate_name(&krate.attrs).map(|s| s == "test").unwrap_or(false),
+ is_libtest: attr::find_crate_name(&krate.attrs)
+ .map(|s| s == sym::test).unwrap_or(false),
toplevel_reexport: None,
ctxt: SyntaxContext::empty().apply_mark(mark),
features,
}
fn is_test_case(i: &ast::Item) -> bool {
- attr::contains_name(&i.attrs, "rustc_test_marker")
+ attr::contains_name(&i.attrs, sym::rustc_test_marker)
}
fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
- let test_attr = attr::find_by_name(&krate.attrs, "test_runner")?;
+ let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
test_attr.meta_item_list().map(|meta_list| {
if meta_list.len() != 1 {
sd.span_fatal(test_attr.span,
use syntax::feature_gate;
use syntax::parse::{self, token};
use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::ast::AsmDialect;
use syntax_pos::Span;
use syntax::tokenstream;
}
}
-const OPTIONS: &[&str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
sp: Span,
-> Box<dyn base::MacResult + 'cx> {
if !cx.ecfg.enable_asm() {
feature_gate::emit_feature_err(&cx.parse_sess,
- "asm",
+ sym::asm,
sp,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_ASM);
Options => {
let (option, _) = p.parse_str()?;
- if option == "volatile" {
+ if option == sym::volatile {
// Indicates that the inline assembly has side effects
// and must not be optimized out along with its outputs.
volatile = true;
- } else if option == "alignstack" {
+ } else if option == sym::alignstack {
alignstack = true;
- } else if option == "intel" {
+ } else if option == sym::intel {
dialect = AsmDialect::Intel;
} else {
cx.span_warn(p.prev_span, "unrecognized option");
use syntax::parse::token;
use syntax::ptr::P;
use syntax_pos::Span;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::{Symbol, sym};
use syntax::tokenstream::TokenTree;
pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
-> Box<dyn base::MacResult + 'cx> {
if !cx.ecfg.enable_concat_idents() {
feature_gate::emit_feature_err(&cx.parse_sess,
- "concat_idents",
+ sym::concat_idents,
sp,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_CONCAT_IDENTS);
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
use syntax_pos::Span;
pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
match annitem.node {
ItemKind::Struct(_, Generics { ref params, .. }) |
ItemKind::Enum(_, Generics { ref params, .. }) => {
- if attr::contains_name(&annitem.attrs, "rustc_copy_clone_marker") &&
+ if attr::contains_name(&annitem.attrs, sym::rustc_copy_clone_marker) &&
!params.iter().any(|param| match param.kind {
ast::GenericParamKind::Type { .. } => true,
_ => false,
use syntax::source_map::{self, respan};
use syntax::util::map_in_place::MapInPlace;
use syntax::ptr::P;
-use syntax::symbol::{Symbol, keywords};
+use syntax::symbol::{Symbol, keywords, sym};
use syntax::parse::ParseSess;
use syntax_pos::{DUMMY_SP, Span};
}
};
let is_always_copy =
- attr::contains_name(&item.attrs, "rustc_copy_clone_marker") &&
+ attr::contains_name(&item.attrs, sym::rustc_copy_clone_marker) &&
has_no_type_params;
let use_temporaries = is_packed && is_always_copy;
attrs.extend(item.attrs
.iter()
.filter(|a| {
- ["allow", "warn", "deny", "forbid", "stable", "unstable"]
- .contains(&a.name_or_empty().get())
+ [sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable]
+ .contains(&a.name_or_empty())
})
.cloned());
push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
use syntax::ext::build::AstBuilder;
use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
macro path_local($x:ident) {
let intrinsic_allowed_via_allow_internal_unstable = cx
.current_expansion.mark.expn_info().unwrap()
.allow_internal_unstable.map_or(false, |features| features.iter().any(|&s|
- s == "core_intrinsics"
+ s == sym::core_intrinsics
));
if intrinsic_allowed_via_allow_internal_unstable {
span = span.with_ctxt(cx.backtrace());
use syntax::feature_gate;
use syntax::parse::token;
use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::tokenstream;
use syntax_pos::{MultiSpan, Span, DUMMY_SP};
//if !ecx.ecfg.enable_allow_internal_unstable() {
// For some reason, the only one that actually works for `println` is the first check
- if !sp.allows_unstable("format_args_nl") // the span is marked as `#[allow_insternal_unsable]`
+ if !sp.allows_unstable(sym::format_args_nl) // the span is marked `#[allow_insternal_unsable]`
&& !ecx.ecfg.enable_allow_internal_unstable() // NOTE: when is this enabled?
&& !ecx.ecfg.enable_format_args_nl() // enabled using `#[feature(format_args_nl]`
{
feature_gate::emit_feature_err(&ecx.parse_sess,
- "format_args_nl",
+ sym::format_args_nl,
sp,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_FORMAT_ARGS_NL);
use syntax::feature_gate;
use syntax::parse::token;
use syntax::ptr::P;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::Span;
use syntax::tokenstream;
use smallvec::smallvec;
-pub const MACRO: &str = "global_asm";
+pub const MACRO: Symbol = sym::global_asm;
pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
sp: Span,
use syntax::feature_gate;
use syntax::print;
use syntax::tokenstream;
+use syntax::symbol::sym;
use syntax_pos;
pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt<'_>,
-> Box<dyn base::MacResult + 'cx> {
if !cx.ecfg.enable_log_syntax() {
feature_gate::emit_feature_err(&cx.parse_sess,
- "log_syntax",
+ sym::log_syntax,
sp,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_LOG_SYNTAX);
use syntax::parse::ParseSess;
use syntax::ptr::P;
use syntax::symbol::Symbol;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP};
-const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
+const PROC_MACRO_KINDS: [Symbol; 3] = [
+ sym::proc_macro_derive,
+ sym::proc_macro_attribute,
+ sym::proc_macro
+];
struct ProcMacroDerive {
trait_name: ast::Name,
let attributes_attr = list.get(1);
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
- if !attr.check_name("attributes") {
+ if !attr.check_name(sym::attributes) {
self.handler.span_err(attr.span(), "second argument must be `attributes`")
}
attr.meta_item_list().unwrap_or_else(|| {
impl<'a> Visitor<'a> for CollectProcMacros<'a> {
fn visit_item(&mut self, item: &'a ast::Item) {
if let ast::ItemKind::MacroDef(..) = item.node {
- if self.is_proc_macro_crate && attr::contains_name(&item.attrs, "macro_export") {
+ if self.is_proc_macro_crate && attr::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(item.span, msg);
return;
}
- if attr.check_name("proc_macro_derive") {
+ if attr.check_name(sym::proc_macro_derive) {
self.collect_custom_derive(item, attr);
- } else if attr.check_name("proc_macro_attribute") {
+ } else if attr.check_name(sym::proc_macro_attribute) {
self.collect_attr_proc_macro(item);
- } else if attr.check_name("proc_macro") {
+ } else if attr.check_name(sym::proc_macro) {
self.collect_bang_proc_macro(item);
};
use syntax::attr;
use syntax::ast;
use syntax::print::pprust;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::{DUMMY_SP, Span};
use syntax::source_map::{ExpnInfo, MacroAttribute};
use std::iter;
}
fn should_ignore(i: &ast::Item) -> bool {
- attr::contains_name(&i.attrs, "ignore")
+ attr::contains_name(&i.attrs, sym::ignore)
}
fn should_fail(i: &ast::Item) -> bool {
- attr::contains_name(&i.attrs, "allow_fail")
+ attr::contains_name(&i.attrs, sym::allow_fail)
}
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
- match attr::find_by_name(&i.attrs, "should_panic") {
+ match attr::find_by_name(&i.attrs, sym::should_panic) {
Some(attr) => {
let ref sd = cx.parse_sess.span_diagnostic;
// Handle #[should_panic(expected = "foo")]
Some(list) => {
let msg = list.iter()
- .find(|mi| mi.check_name("expected"))
+ .find(|mi| mi.check_name(sym::expected))
.and_then(|mi| mi.meta_item())
.and_then(|mi| mi.value_str());
if list.len() != 1 || msg.is_none() {
}
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
- let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
+ let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
let ref sd = cx.parse_sess.span_diagnostic;
if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.node {
if header.unsafety == ast::Unsafety::Unsafe {
use syntax::ext::hygiene::{self, Mark, SyntaxContext};
use syntax::ast;
use syntax::source_map::respan;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax_pos::{DUMMY_SP, Span};
use syntax::source_map::{ExpnInfo, MacroAttribute};
use syntax::feature_gate;
) -> Vec<Annotatable> {
if !ecx.ecfg.enable_custom_test_frameworks() {
feature_gate::emit_feature_err(&ecx.parse_sess,
- "custom_test_frameworks",
+ sym::custom_test_frameworks,
attr_sp,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS);
use syntax::ext::base::{self, ExtCtxt};
use syntax::feature_gate;
-use syntax::symbol::keywords;
+use syntax::symbol::{keywords, sym};
use syntax_pos::Span;
use syntax::tokenstream::TokenTree;
-> Box<dyn base::MacResult + 'static> {
if !cx.ecfg.enable_trace_macros() {
feature_gate::emit_feature_err(&cx.parse_sess,
- "trace_macros",
+ sym::trace_macros,
sp,
feature_gate::GateIssue::Language,
feature_gate::EXPLAIN_TRACE_MACROS);
+use crate::symbol::{Symbol, sym};
use std::fmt;
use std::str::FromStr;
}
}
- pub fn feature_name(&self) -> &'static str {
+ pub fn feature_name(&self) -> Symbol {
match *self {
- Edition::Edition2015 => "rust_2015_preview",
- Edition::Edition2018 => "rust_2018_preview",
+ Edition::Edition2015 => sym::rust_2015_preview,
+ Edition::Edition2018 => sym::rust_2018_preview,
}
}
pub use span_encoding::{Span, DUMMY_SP};
pub mod symbol;
-pub use symbol::symbols;
+pub use symbol::{Symbol, sym};
mod analyze_source_file;
/// Checks if a span is "internal" to a macro in which `#[unstable]`
/// items can be used (that is, a macro marked with
/// `#[allow_internal_unstable]`).
- pub fn allows_unstable(&self, feature: &str) -> bool {
+ pub fn allows_unstable(&self, feature: Symbol) -> bool {
match self.ctxt().outer().expn_info() {
Some(info) => info
.allow_internal_unstable
.map_or(false, |features| features.iter().any(|&f|
- f == feature || f == "allow_internal_unstable_backcompat_hack"
+ f == feature || f == sym::allow_internal_unstable_backcompat_hack
)),
None => false,
}
Union: "union",
}
- // Other symbols that can be referred to with syntax_pos::symbols::*
- Other {
+ // Symbols that can be referred to with syntax_pos::sym::*. The symbol is
+ // the stringified identifier unless otherwise specified (e.g.
+ // `proc_dash_macro` represents "proc-macro").
+ Symbols {
+ aarch64_target_feature,
+ abi,
+ abi_amdgpu_kernel,
+ abi_msp430_interrupt,
+ abi_ptx,
+ abi_sysv64,
+ abi_thiscall,
+ abi_unadjusted,
+ abi_vectorcall,
+ abi_x86_interrupt,
+ aborts,
+ advanced_slice_patterns,
+ adx_target_feature,
alias,
align,
+ alignstack,
+ all,
+ allocator,
+ allocator_internals,
alloc_error_handler,
allow,
+ allowed,
allow_fail,
allow_internal_unsafe,
allow_internal_unstable,
+ allow_internal_unstable_backcompat_hack,
+ always,
+ any,
+ arbitrary_self_types,
+ arm_target_feature,
+ asm,
+ associated_consts,
+ associated_type_defaults,
+ associated_types,
+ async_await,
+ attr,
+ attributes,
+ attr_literals,
+ augmented_assignments,
automatically_derived,
+ avx512_target_feature,
+ await_macro,
+ bin,
+ bind_by_move_pattern_guards,
+ block,
+ borrowck_graphviz_postflow,
+ borrowck_graphviz_preflow,
+ box_patterns,
+ box_syntax,
+ braced_empty_structs,
+ C,
+ cdylib,
cfg,
cfg_attr,
+ cfg_attr_multi,
+ cfg_target_feature,
+ cfg_target_has_atomic,
+ cfg_target_thread_local,
+ cfg_target_vendor,
+ clone,
+ clone_closures,
+ clone_from,
+ closure_to_fn_coercion,
+ cmpxchg16b_target_feature,
cold,
+ compile_error,
compiler_builtins,
+ concat_idents,
+ conservative_impl_trait,
+ console,
+ const_compare_raw_pointers,
+ const_fn,
+ const_fn_union,
+ const_generics,
+ const_indexing,
+ const_let,
+ const_panic,
+ const_raw_ptr_deref,
+ const_raw_ptr_to_usize_cast,
+ const_transmute,
+ contents,
+ convert,
+ copy_closures,
+ core,
+ core_intrinsics,
crate_id,
+ crate_in_paths,
crate_name,
crate_type,
+ crate_visibility_modifier,
+ custom_attribute,
+ custom_derive,
+ custom_inner_attributes,
+ custom_test_frameworks,
+ c_variadic,
+ decl_macro,
default_lib_allocator,
+ default_type_parameter_fallback,
+ default_type_params,
deny,
deprecated,
derive,
doc,
+ doc_alias,
+ doc_cfg,
+ doc_keyword,
+ doc_masked,
+ doc_spotlight,
+ document_private_items,
+ dotdoteq_in_patterns,
+ dotdot_in_tuple_patterns,
+ dropck_eyepatch,
+ dropck_parametricity,
+ drop_types_in_const,
+ dylib,
+ dyn_trait,
+ eh_personality,
+ eh_unwind_resume,
+ enable,
+ Err,
+ except,
+ exclusive_range_pattern,
+ exhaustive_integer_patterns,
+ exhaustive_patterns,
+ existential_type,
+ expected,
export_name,
+ extern_absolute_paths,
+ external_doc,
+ extern_crate_item_prelude,
+ extern_crate_self,
+ extern_in_paths,
+ extern_prelude,
+ extern_types,
+ f16c_target_feature,
feature,
ffi_returns_twice,
+ field_init_shorthand,
+ file,
+ fn_must_use,
forbid,
+ format_args_nl,
+ from,
+ From,
+ from_error,
+ from_generator,
+ from_ok,
fundamental,
+ future,
+ Future,
+ generators,
+ generic_associated_types,
+ generic_param_attrs,
global_allocator,
+ global_asm,
+ globs,
+ hexagon_target_feature,
+ hidden,
+ homogeneous_aggregate,
+ html_favicon_url,
+ html_logo_url,
+ html_no_source,
+ html_playground_url,
+ html_root_url,
+ i128,
+ i128_type,
+ i16,
+ i32,
+ i64,
+ i8,
+ ident,
+ if_let,
+ if_while_or_patterns,
ignore,
+ impl_header_lifetime_elision,
+ impl_trait_in_bindings,
+ import_shadowing,
+ in_band_lifetimes,
include,
+ inclusive_range_syntax,
+ infer_outlives_requirements,
+ infer_static_outlives_requirements,
inline,
+ intel,
+ into_iter,
+ IntoIterator,
+ into_result,
+ intrinsics,
+ irrefutable_let_patterns,
+ isize,
+ issue,
+ issue_5723_bootstrap,
+ issue_tracker_base_url,
+ item_like_imports,
+ iter,
+ Iterator,
keyword,
+ kind,
+ label,
+ label_break_value,
lang,
+ lang_items,
+ lib,
link,
+ linkage,
link_args,
+ link_cfg,
+ link_llvm_intrinsics,
link_name,
link_section,
- linkage,
+ lint_reasons,
+ local_inner_macros,
+ log_syntax,
+ loop_break_value,
+ macro_at_most_once_rep,
macro_escape,
macro_export,
+ macro_lifetime_matcher,
+ macro_literal_matcher,
+ macro_reexport,
+ macro_rules,
+ macros_in_extern,
macro_use,
+ macro_vis_matcher,
main,
+ managed_boxes,
marker,
+ marker_trait_attr,
masked,
+ match_beginning_vert,
+ match_default_bindings,
may_dangle,
+ message,
+ min_const_fn,
+ min_const_unsafe_fn,
+ mips_target_feature,
+ mmx_target_feature,
+ module,
+ more_struct_aliases,
+ movbe_target_feature,
must_use,
naked,
+ naked_functions,
+ name,
needs_allocator,
needs_panic_runtime,
+ negate_unsigned,
+ never,
+ never_type,
+ next,
+ nll,
no_builtins,
no_core,
+ no_crate_inject,
no_debug,
+ no_default_passes,
no_implicit_prelude,
+ no_inline,
no_link,
no_main,
no_mangle,
+ non_ascii_idents,
+ None,
+ non_exhaustive,
+ non_modrs_mods,
+ no_stack_check,
no_start,
no_std,
- non_exhaustive,
+ not,
+ note,
+ Ok,
omit_gdb_pretty_printer_section,
+ on,
+ on_unimplemented,
+ oom,
+ ops,
optimize,
+ optimize_attribute,
+ optin_builtin_traits,
+ option,
+ Option,
+ opt_out_copy,
+ overlapping_marker_traits,
+ packed,
panic_handler,
+ panic_impl,
+ panic_implementation,
panic_runtime,
+ passes,
path,
+ pattern_parentheses,
+ Pending,
+ pin,
+ Pin,
+ platform_intrinsics,
plugin,
plugin_registrar,
+ plugins,
+ Poll,
+ poll_with_tls_context,
+ powerpc_target_feature,
+ precise_pointer_size_matching,
+ prelude,
prelude_import,
+ primitive,
+ proc_dash_macro: "proc-macro",
proc_macro,
proc_macro_attribute,
proc_macro_derive,
+ proc_macro_expr,
+ proc_macro_gen,
+ proc_macro_hygiene,
+ proc_macro_mod,
+ proc_macro_non_items,
+ proc_macro_path_invoc,
profiler_runtime,
+ pub_restricted,
+ pushpop_unsafe,
+ quad_precision_float,
+ question_mark,
+ quote,
+ Range,
+ RangeFrom,
+ RangeFull,
+ RangeInclusive,
+ RangeTo,
+ RangeToInclusive,
+ raw_identifiers,
+ Ready,
+ reason,
recursion_limit,
reexport_test_harness_main,
+ reflect,
+ relaxed_adts,
repr,
+ repr128,
+ repr_align,
+ repr_align_enum,
+ repr_packed,
+ repr_simd,
+ repr_transparent,
+ re_rebalance_coherence,
+ result,
+ Result,
+ Return,
+ rlib,
+ rtm_target_feature,
+ rust,
+ rust_2015_preview,
+ rust_2018_preview,
+ rust_begin_unwind,
+ rustc_allocator_nounwind,
+ rustc_allow_const_fn_ptr,
rustc_args_required_const,
+ rustc_attrs,
rustc_clean,
rustc_const_unstable,
rustc_conversion_suggestion,
rustc_copy_clone_marker,
rustc_def_path,
rustc_deprecated,
+ rustc_diagnostic_macros,
rustc_dirty,
+ rustc_doc_only_macro,
+ rustc_dump_env_program_clauses,
rustc_dump_program_clauses,
rustc_dump_user_substs,
rustc_error,
rustc_layout_scalar_valid_range_end,
rustc_layout_scalar_valid_range_start,
rustc_mir,
+ rustc_object_lifetime_default,
rustc_on_unimplemented,
rustc_outlives,
rustc_paren_sugar,
rustc_partition_codegened,
rustc_partition_reused,
+ rustc_peek,
+ rustc_peek_definite_init,
+ rustc_peek_maybe_init,
+ rustc_peek_maybe_uninit,
+ rustc_private,
rustc_proc_macro_decls,
+ rustc_promotable,
rustc_regions,
+ rustc_stable,
rustc_std_internal_symbol,
rustc_symbol_name,
rustc_synthetic,
rustc_then_this_would_need,
rustc_transparent_macro,
rustc_variance,
+ rustdoc,
+ rust_eh_personality,
+ rust_eh_unwind_resume,
+ rust_oom,
+ __rust_unstable_column,
+ rvalue_static_promotion,
sanitizer_runtime,
+ self_in_typedefs,
+ self_struct_ctor,
+ Send,
should_panic,
simd,
+ simd_ffi,
+ since,
+ size,
+ slice_patterns,
+ slicing_syntax,
+ Some,
+ specialization,
+ speed,
spotlight,
+ sse4a_target_feature,
stable,
+ staged_api,
start,
+ static_in_const,
+ staticlib,
+ static_nobundle,
+ static_recursion,
+ std,
+ stmt_expr_attributes,
+ stop_after_dataflow,
+ struct_field_attributes,
+ struct_inherit,
structural_match,
+ struct_variant,
+ suggestion,
target_feature,
+ target_has_atomic,
+ target_thread_local,
+ task,
+ tbm_target_feature,
+ termination_trait,
+ termination_trait_test,
+ test,
+ test_2018_feature,
+ test_accepted_feature,
+ test_removed_feature,
test_runner,
thread_local,
+ tool_attributes,
+ tool_lints,
+ trace_macros,
+ trait_alias,
+ transmute,
+ transparent,
+ trivial_bounds,
+ Try,
+ try_blocks,
+ tuple_indexing,
+ ty,
+ type_alias_enum_variants,
+ type_ascription,
type_length_limit,
+ type_macros,
+ u128,
+ u16,
+ u32,
+ u64,
+ u8,
+ unboxed_closures,
+ underscore_const_names,
+ underscore_imports,
+ underscore_lifetimes,
+ uniform_paths,
+ universal_impl_trait,
+ unmarked_api,
+ unrestricted_attribute_tokens,
unsafe_destructor_blind_to_params,
+ unsafe_no_drop_flag,
+ unsized_locals,
+ unsized_tuple_coercion,
unstable,
+ untagged_unions,
unwind,
+ unwind_attributes,
used,
+ use_extern_macros,
+ use_nested_groups,
+ usize,
+ v1,
+ vis,
+ visible_private_types,
+ volatile,
warn,
+ warn_directory_ownership,
+ wasm_import_module,
+ wasm_target_feature,
+ while_let,
+ windows,
windows_subsystem,
+ Yield,
}
}
}
}
-impl<T: std::ops::Deref<Target=str>> PartialEq<T> for Symbol {
- fn eq(&self, other: &T) -> bool {
- self.as_str() == other.deref()
- }
-}
-
// The `&'static str`s in this type actually point into the arena.
//
// Note that normal symbols are indexed upward from 0, and gensyms are indexed
keywords!();
}
-pub mod symbols {
+// This module has a very short name because it's used a lot.
+pub mod sym {
use super::Symbol;
symbols!();
}
use syntax::attr;
use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{Symbol, sym};
use syntax::ptr::P;
use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure};
use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching};
};
fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| {
- if attr::contains_name(&item.attrs, "ignore") {
+ if attr::contains_name(&item.attrs, sym::ignore) {
acc
} else {
cx.expr_binary(item.span, ast::BinOpKind::Add, acc,
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_late_lint_pass(box MissingWhitelistedAttrPass);
- reg.register_attribute("whitelisted_attr".to_string(), Whitelisted);
+ reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted);
}
declare_lint! {
_ => cx.tcx.hir().expect_item_by_hir_id(cx.tcx.hir().get_parent_item(id)),
};
- if !attr::contains_name(&item.attrs, "whitelisted_attr") {
+ if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) {
cx.span_lint(MISSING_WHITELISTED_ATTR, span,
"Missing 'whitelisted_attr' attribute");
}
use rustc_plugin::Registry;
use rustc::hir;
use syntax::attr;
+use syntax::symbol::Symbol;
macro_rules! fake_lint_pass {
($struct:ident, $lints:expr, $($attr:expr),*) => {
fake_lint_pass! {
PassOkay,
lint_array!(CRATE_NOT_OKAY), // Single lint
- "rustc_crate_okay"
+ Symbol::intern("rustc_crate_okay")
}
fake_lint_pass! {
PassRedBlue,
lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints
- "rustc_crate_red", "rustc_crate_blue"
+ Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue")
}
fake_lint_pass! {
PassGreyGreen,
lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma
- "rustc_crate_grey", "rustc_crate_green"
+ Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green")
}
#[plugin_registrar]
extern crate rustc;
extern crate rustc_plugin;
+use syntax::symbol::Symbol;
use syntax::feature_gate::AttributeType;
use rustc_plugin::Registry;
-
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_attribute("foo".to_owned(), AttributeType::Normal);
- reg.register_attribute("bar".to_owned(), AttributeType::CrateLevel);
- reg.register_attribute("baz".to_owned(), AttributeType::Whitelisted);
+ reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal);
+ reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel);
+ reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted);
}
use rustc_plugin::Registry;
use rustc::hir;
use syntax::attr;
+use syntax::symbol::Symbol;
declare_lint! {
CRATE_NOT_OKAY,
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
- if !attr::contains_name(&krate.attrs, "crate_okay") {
+ if !attr::contains_name(&krate.attrs, Symbol::intern("crate_okay")) {
cx.span_lint(CRATE_NOT_OKAY, krate.span,
"crate is not marked with #![crate_okay]");
}
impl EarlyLintPass for Pass {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
- if it.ident.name == "lintme" {
+ if it.ident.name.as_str() == "lintme" {
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
}
}
impl EarlyLintPass for Pass {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
- if it.ident.name == "lintme" {
+ if it.ident.name.as_str() == "lintme" {
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
}
- if it.ident.name == "lintmetoo" {
+ if it.ident.name.as_str() == "lintmetoo" {
cx.span_lint(TEST_GROUP, it.span, "item is named 'lintmetoo'");
}
}