Switch token trees to use Symbols

This commit is contained in:
Lukas Wirth 2024-07-16 09:59:39 +02:00
parent 0c95aaa08e
commit 93024ad411
51 changed files with 593 additions and 399 deletions

View file

@ -159,14 +159,14 @@ impl Attrs {
pub fn has_doc_hidden(&self) -> bool {
self.by_key("doc").tt_values().any(|tt| {
tt.delimiter.kind == DelimiterKind::Parenthesis &&
matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.text == "hidden")
matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::hidden)
})
}
pub fn has_doc_notable_trait(&self) -> bool {
self.by_key("doc").tt_values().any(|tt| {
tt.delimiter.kind == DelimiterKind::Parenthesis &&
matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.text == "notable_trait")
matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::notable_trait)
})
}
@ -267,7 +267,7 @@ impl DocExpr {
fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr> {
let name = match it.next() {
None => return None,
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.text.clone(),
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.sym.clone(),
Some(_) => return Some(DocExpr::Invalid),
};
@ -275,13 +275,16 @@ fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr>
let ret = match it.as_slice().first() {
Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => {
match it.as_slice().get(1) {
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal {
symbol: text,
kind: tt::LitKind::Str,
..
}))) => {
it.next();
it.next();
// FIXME: escape? raw string?
let value =
SmolStr::new(literal.text.trim_start_matches('"').trim_end_matches('"'));
DocAtom::KeyValue { key: name, value }.into()
let value = SmolStr::new(text.as_str());
DocAtom::KeyValue { key: name.as_str().into(), value }.into()
}
_ => return Some(DocExpr::Invalid),
}
@ -294,7 +297,7 @@ fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr>
_ => DocExpr::Invalid,
}
}
_ => DocAtom::Flag(name).into(),
_ => DocAtom::Flag(name.as_str().into()).into(),
};
// Eat comma separator
@ -311,10 +314,11 @@ fn parse_comma_sep<S>(subtree: &tt::Subtree<S>) -> Vec<SmolStr> {
.token_trees
.iter()
.filter_map(|tt| match tt {
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
// FIXME: escape? raw string?
Some(SmolStr::new(lit.text.trim_start_matches('"').trim_end_matches('"')))
}
tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal {
kind: tt::LitKind::Str,
symbol: text,
..
})) => Some(SmolStr::new(text.as_str())),
_ => None,
})
.collect()
@ -598,14 +602,14 @@ impl<'attr> AttrQuery<'attr> {
/// #[doc(html_root_url = "url")]
/// ^^^^^^^^^^^^^ key
/// ```
pub fn find_string_value_in_tt(self, key: &'attr str) -> Option<&SmolStr> {
pub fn find_string_value_in_tt(self, key: &'attr str) -> Option<&str> {
self.tt_values().find_map(|tt| {
let name = tt.token_trees.iter()
.skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { text, ..} )) if text == key))
.skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if sym.as_str() == key))
.nth(2);
match name {
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal{ text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_) , ..}))) => Some(text),
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal{ symbol: text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_) , ..}))) => Some(text.as_str()),
_ => None
}
})

View file

@ -6,7 +6,7 @@
use std::fmt;
use hir_expand::name::{AsName, Name};
use intern::sym;
use intern::{sym, Symbol};
/// Different signed int types.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BuiltinInt {
@ -143,6 +143,18 @@ impl BuiltinInt {
};
Some(res)
}
pub fn from_suffix_sym(suffix: &Symbol) -> Option<BuiltinInt> {
let res = match suffix {
s if *s == sym::isize => Self::Isize,
s if *s == sym::i8 => Self::I8,
s if *s == sym::i16 => Self::I16,
s if *s == sym::i32 => Self::I32,
s if *s == sym::i64 => Self::I64,
s if *s == sym::i128 => Self::I128,
_ => return None,
};
Some(res)
}
}
#[rustfmt::skip]
@ -160,6 +172,19 @@ impl BuiltinUint {
};
Some(res)
}
pub fn from_suffix_sym(suffix: &Symbol) -> Option<BuiltinUint> {
let res = match suffix {
s if *s == sym::usize => Self::Usize,
s if *s == sym::u8 => Self::U8,
s if *s == sym::u16 => Self::U16,
s if *s == sym::u32 => Self::U32,
s if *s == sym::u64 => Self::U64,
s if *s == sym::u128 => Self::U128,
_ => return None,
};
Some(res)
}
}
#[rustfmt::skip]

View file

@ -150,7 +150,7 @@ fn parse_rustc_legacy_const_generics(tt: &crate::tt::Subtree) -> Box<[u32]> {
let mut indices = Vec::new();
for args in tt.token_trees.chunks(2) {
match &args[0] {
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => match lit.text.parse() {
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() {
Ok(index) => indices.push(index),
Err(_) => break,
},

View file

@ -9,7 +9,7 @@ use hir_expand::{
name::{AsName, Name},
HirFileId, InFile,
};
use intern::Interned;
use intern::{sym, Interned};
use la_arena::Arena;
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
use syntax::ast::{self, HasName, HasVisibility};
@ -112,12 +112,12 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprOptions> {
let mut tts = tt.token_trees.iter().peekable();
while let Some(tt) = tts.next() {
if let TokenTree::Leaf(Leaf::Ident(ident)) = tt {
flags.insert(match &*ident.text {
"packed" => {
flags.insert(match &ident.sym {
s if *s == sym::packed => {
let pack = if let Some(TokenTree::Subtree(tt)) = tts.peek() {
tts.next();
if let Some(TokenTree::Leaf(Leaf::Literal(lit))) = tt.token_trees.first() {
lit.text.parse().unwrap_or_default()
lit.symbol.as_str().parse().unwrap_or_default()
} else {
0
}
@ -129,11 +129,11 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprOptions> {
Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack });
ReprFlags::empty()
}
"align" => {
s if *s == sym::align => {
if let Some(TokenTree::Subtree(tt)) = tts.peek() {
tts.next();
if let Some(TokenTree::Leaf(Leaf::Literal(lit))) = tt.token_trees.first() {
if let Ok(align) = lit.text.parse() {
if let Ok(align) = lit.symbol.as_str().parse() {
let align = Align::from_bytes(align).ok();
max_align = max_align.max(align);
}
@ -141,13 +141,13 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprOptions> {
}
ReprFlags::empty()
}
"C" => ReprFlags::IS_C,
"transparent" => ReprFlags::IS_TRANSPARENT,
"simd" => ReprFlags::IS_SIMD,
s if *s == sym::C => ReprFlags::IS_C,
s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT,
s if *s == sym::simd => ReprFlags::IS_SIMD,
repr => {
if let Some(builtin) = BuiltinInt::from_suffix(repr)
if let Some(builtin) = BuiltinInt::from_suffix_sym(repr)
.map(Either::Left)
.or_else(|| BuiltinUint::from_suffix(repr).map(Either::Right))
.or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right))
{
int = Some(match builtin {
Either::Left(bi) => match bi {

View file

@ -278,7 +278,7 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool {
tt.split(|tt| matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ','));
for output in segments.skip(1) {
match output {
[tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.text == "no_std" => {
[tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::no_std => {
return true
}
_ => {}

View file

@ -63,6 +63,7 @@ use base_db::{CrateId, FileId};
use hir_expand::{
name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
};
use intern::Symbol;
use itertools::Itertools;
use la_arena::Arena;
use rustc_hash::{FxHashMap, FxHashSet};
@ -148,11 +149,11 @@ struct DefMapCrateData {
proc_macro_loading_error: Option<Box<str>>,
/// Custom attributes registered with `#![register_attr]`.
registered_attrs: Vec<SmolStr>,
registered_attrs: Vec<Symbol>,
/// Custom tool modules registered with `#![register_tool]`.
registered_tools: Vec<SmolStr>,
registered_tools: Vec<Symbol>,
/// Unstable features of Rust enabled with `#![feature(A, B)]`.
unstable_features: FxHashSet<SmolStr>,
unstable_features: FxHashSet<Symbol>,
/// #[rustc_coherence_is_core]
rustc_coherence_is_core: bool,
no_core: bool,
@ -170,7 +171,7 @@ impl DefMapCrateData {
fn_proc_macro_mapping: FxHashMap::default(),
proc_macro_loading_error: None,
registered_attrs: Vec::new(),
registered_tools: PREDEFINED_TOOLS.into(),
registered_tools: PREDEFINED_TOOLS.iter().map(|it| Symbol::intern(it)).collect(),
unstable_features: FxHashSet::default(),
rustc_coherence_is_core: false,
no_core: false,
@ -447,15 +448,15 @@ impl DefMap {
self.derive_helpers_in_scope.get(&id.map(|it| it.upcast())).map(Deref::deref)
}
pub fn registered_tools(&self) -> &[SmolStr] {
pub fn registered_tools(&self) -> &[Symbol] {
&self.data.registered_tools
}
pub fn registered_attrs(&self) -> &[SmolStr] {
pub fn registered_attrs(&self) -> &[Symbol] {
&self.data.registered_attrs
}
pub fn is_unstable_feature_enabled(&self, feature: &str) -> bool {
pub fn is_unstable_feature_enabled(&self, feature: &Symbol) -> bool {
self.data.unstable_features.contains(feature)
}

View file

@ -7,7 +7,7 @@ use hir_expand::{
MacroCallId, MacroCallKind, MacroDefId,
};
use span::SyntaxContextId;
use syntax::{ast, SmolStr};
use syntax::ast;
use triomphe::Arc;
use crate::{
@ -79,20 +79,20 @@ impl DefMap {
let segments = path.segments();
if let Some(name) = segments.first() {
let name = name.to_smol_str();
let pred = |n: &_| *n == name;
let name = name.symbol();
let pred = |n: &_| *n == *name;
let is_tool = self.data.registered_tools.iter().map(SmolStr::as_str).any(pred);
let is_tool = self.data.registered_tools.iter().any(pred);
// FIXME: tool modules can be shadowed by actual modules
if is_tool {
return true;
}
if segments.len() == 1 {
if find_builtin_attr_idx(&name).is_some() {
if find_builtin_attr_idx(name).is_some() {
return true;
}
if self.data.registered_attrs.iter().map(SmolStr::as_str).any(pred) {
if self.data.registered_attrs.iter().any(pred) {
return true;
}
}

View file

@ -317,20 +317,20 @@ impl DefCollector<'_> {
.into_iter()
.flatten()
.filter_map(|(feat, _)| match feat.segments() {
[name] => Some(name.to_smol_str()),
[name] => Some(name.symbol().clone()),
_ => None,
});
crate_data.unstable_features.extend(features);
}
() if *attr_name == sym::register_attr.clone() => {
if let Some(ident) = attr.single_ident_value() {
crate_data.registered_attrs.push(ident.text.clone());
crate_data.registered_attrs.push(ident.sym.clone());
cov_mark::hit!(register_attr);
}
}
() if *attr_name == sym::register_tool.clone() => {
if let Some(ident) = attr.single_ident_value() {
crate_data.registered_tools.push(ident.text.clone());
crate_data.registered_tools.push(ident.sym.clone());
cov_mark::hit!(register_tool);
}
}
@ -2129,9 +2129,7 @@ impl ModCollector<'_, '_> {
let is_export = export_attr.exists();
let local_inner = if is_export {
export_attr.tt_values().flat_map(|it| it.token_trees.iter()).any(|it| match it {
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
ident.text.contains("local_inner_macros")
}
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident.sym == sym::local_inner_macros,
_ => false,
})
} else {

View file

@ -1,6 +1,7 @@
//! Nameres-specific procedural macro data and helpers.
use hir_expand::name::{AsName, Name};
use intern::sym;
use crate::attr::Attrs;
use crate::tt::{Leaf, TokenTree};
@ -67,7 +68,7 @@ pub(crate) fn parse_macro_name_and_helper_attrs(tt: &[TokenTree]) -> Option<(Nam
TokenTree::Leaf(Leaf::Punct(comma)),
TokenTree::Leaf(Leaf::Ident(attributes)),
TokenTree::Subtree(helpers)
] if comma.char == ',' && attributes.text == "attributes" =>
] if comma.char == ',' && attributes.sym == sym::attributes =>
{
let helpers = helpers
.token_trees